17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay Provides a general mechanism to maintain a linked list of PETSc objects. 4e5c89e4eSSatish Balay This is used to allow PETSc objects to carry a list of "composed" objects 5e5c89e4eSSatish Balay */ 6c6db04a5SJed Brown #include <petscsys.h> 7e5c89e4eSSatish Balay 8140e18c1SBarry Smith struct _n_PetscObjectList { 9e5c89e4eSSatish Balay char name[256]; 10140e18c1SBarry Smith PetscBool skipdereference; /* when the PetscObjectList is destroyed do not call PetscObjectDereference() on this object */ 11e5c89e4eSSatish Balay PetscObject obj; 12140e18c1SBarry Smith PetscObjectList next; 13e5c89e4eSSatish Balay }; 14e5c89e4eSSatish Balay 156ba4bc90SBarry Smith /*@C 16140e18c1SBarry Smith PetscObjectListRemoveReference - Calls PetscObjectDereference() on an object in the list immediately but keeps a pointer to the object in the list. 176ba4bc90SBarry Smith 186ba4bc90SBarry Smith Input Parameters: 196ba4bc90SBarry Smith + fl - the object list 206ba4bc90SBarry Smith - name - the name to use for the object 216ba4bc90SBarry Smith 226ba4bc90SBarry Smith Level: developer 236ba4bc90SBarry Smith 24*95452b02SPatrick Sanan Notes: 25*95452b02SPatrick Sanan Use PetscObjectListAdd(PetscObjectList,const char name[],NULL) to truly remove the object from the list 266ba4bc90SBarry Smith 276ba4bc90SBarry Smith Use this routine ONLY if you know that the object referenced will remain in existence until the pointing object is destroyed 286ba4bc90SBarry Smith 296ba4bc90SBarry Smith Developer Note: this is to handle some cases that otherwise would result in having circular references so reference counts never got to zero 306ba4bc90SBarry Smith 31140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate(), PetscObjectListAdd() 326ba4bc90SBarry Smith 336ba4bc90SBarry Smith @*/ 34140e18c1SBarry Smith PetscErrorCode PetscObjectListRemoveReference(PetscObjectList *fl,const char name[]) 356ba4bc90SBarry Smith { 36140e18c1SBarry Smith PetscObjectList nlist; 376ba4bc90SBarry Smith PetscErrorCode ierr; 386ba4bc90SBarry Smith PetscBool match; 396ba4bc90SBarry Smith 406ba4bc90SBarry Smith PetscFunctionBegin; 4187130e5eSHong Zhang nlist = *fl; 426ba4bc90SBarry Smith while (nlist) { 436ba4bc90SBarry Smith ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 4400ac8be1SBarry Smith if (match) { /* found it in the list */ 4500ac8be1SBarry Smith if (!nlist->skipdereference) { 466ba4bc90SBarry Smith ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 4700ac8be1SBarry Smith } 486ba4bc90SBarry Smith nlist->skipdereference = PETSC_TRUE; 496ba4bc90SBarry Smith PetscFunctionReturn(0); 506ba4bc90SBarry Smith } 516ba4bc90SBarry Smith nlist = nlist->next; 526ba4bc90SBarry Smith } 536ba4bc90SBarry Smith PetscFunctionReturn(0); 546ba4bc90SBarry Smith } 556ba4bc90SBarry Smith 561d0fab5eSBarry Smith /*@C 57140e18c1SBarry Smith PetscObjectListAdd - Adds a new object to an PetscObjectList 58e5c89e4eSSatish Balay 591d0fab5eSBarry Smith Input Parameters: 601d0fab5eSBarry Smith + fl - the object list 611d0fab5eSBarry Smith . name - the name to use for the object 621d0fab5eSBarry Smith - obj - the object to attach 63e5c89e4eSSatish Balay 64b235ab32SBarry Smith Level: developer 65b235ab32SBarry Smith 66*95452b02SPatrick Sanan Notes: 67*95452b02SPatrick Sanan Replaces item if it is already in list. Removes item if you pass in a NULL object. 681d0fab5eSBarry Smith 69140e18c1SBarry Smith Use PetscObjectListFind() or PetscObjectListReverseFind() to get the object back 701d0fab5eSBarry Smith 71140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 721d0fab5eSBarry Smith 731d0fab5eSBarry Smith @*/ 74140e18c1SBarry Smith PetscErrorCode PetscObjectListAdd(PetscObjectList *fl,const char name[],PetscObject obj) 75e5c89e4eSSatish Balay { 76140e18c1SBarry Smith PetscObjectList olist,nlist,prev; 77e5c89e4eSSatish Balay PetscErrorCode ierr; 78ace3abfcSBarry Smith PetscBool match; 79e5c89e4eSSatish Balay 80e5c89e4eSSatish Balay PetscFunctionBegin; 81e5c89e4eSSatish Balay if (!obj) { /* this means remove from list if it is there */ 82e5c89e4eSSatish Balay nlist = *fl; prev = 0; 83e5c89e4eSSatish Balay while (nlist) { 84e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 85e5c89e4eSSatish Balay if (match) { /* found it already in the list */ 864a0791bcSMatthew G. Knepley /* Remove it first to prevent circular derefs */ 87e5c89e4eSSatish Balay if (prev) prev->next = nlist->next; 88a297a907SKarl Rupp else if (nlist->next) *fl = nlist->next; 89a297a907SKarl Rupp else *fl = 0; 904a0791bcSMatthew G. Knepley if (!nlist->skipdereference) { 914a0791bcSMatthew G. Knepley ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 924a0791bcSMatthew G. Knepley } 93e5c89e4eSSatish Balay ierr = PetscFree(nlist);CHKERRQ(ierr); 94e5c89e4eSSatish Balay PetscFunctionReturn(0); 95e5c89e4eSSatish Balay } 96e5c89e4eSSatish Balay prev = nlist; 97e5c89e4eSSatish Balay nlist = nlist->next; 98e5c89e4eSSatish Balay } 99e5c89e4eSSatish Balay PetscFunctionReturn(0); /* did not find it to remove */ 100e5c89e4eSSatish Balay } 101e5c89e4eSSatish Balay /* look for it already in list */ 102e5c89e4eSSatish Balay nlist = *fl; 103e5c89e4eSSatish Balay while (nlist) { 104e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 105e5c89e4eSSatish Balay if (match) { /* found it in the list */ 106e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 10700ac8be1SBarry Smith if (!nlist->skipdereference) { 1087dcf0eaaSdalcinl ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 10900ac8be1SBarry Smith } 11000ac8be1SBarry Smith nlist->skipdereference = PETSC_FALSE; 111e5c89e4eSSatish Balay nlist->obj = obj; 112e5c89e4eSSatish Balay PetscFunctionReturn(0); 113e5c89e4eSSatish Balay } 114e5c89e4eSSatish Balay nlist = nlist->next; 115e5c89e4eSSatish Balay } 116e5c89e4eSSatish Balay 117e5c89e4eSSatish Balay /* add it to list, because it was not already there */ 118b00a9115SJed Brown ierr = PetscNew(&olist);CHKERRQ(ierr); 119e5c89e4eSSatish Balay olist->next = 0; 120e5c89e4eSSatish Balay olist->obj = obj; 121a297a907SKarl Rupp 122e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 123e5c89e4eSSatish Balay ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr); 124e5c89e4eSSatish Balay 125a297a907SKarl Rupp if (!*fl) *fl = olist; 126a297a907SKarl Rupp else { /* go to end of list */ 127e5c89e4eSSatish Balay nlist = *fl; 128e5c89e4eSSatish Balay while (nlist->next) { 129e5c89e4eSSatish Balay nlist = nlist->next; 130e5c89e4eSSatish Balay } 131e5c89e4eSSatish Balay nlist->next = olist; 132e5c89e4eSSatish Balay } 133e5c89e4eSSatish Balay PetscFunctionReturn(0); 134e5c89e4eSSatish Balay } 135e5c89e4eSSatish Balay 1361d0fab5eSBarry Smith /*@C 137140e18c1SBarry Smith PetscObjectListDestroy - Destroy a list of objects 138e5c89e4eSSatish Balay 139e5c89e4eSSatish Balay Input Parameter: 1406bf464f9SBarry Smith . ifl - pointer to list 1411d0fab5eSBarry Smith 142b235ab32SBarry Smith Level: developer 143b235ab32SBarry Smith 144140e18c1SBarry Smith .seealso: PetscObjectListAdd(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 1451d0fab5eSBarry Smith 1461d0fab5eSBarry Smith @*/ 147140e18c1SBarry Smith PetscErrorCode PetscObjectListDestroy(PetscObjectList *ifl) 148e5c89e4eSSatish Balay { 149140e18c1SBarry Smith PetscObjectList tmp,fl = *ifl; 150e5c89e4eSSatish Balay PetscErrorCode ierr; 151e5c89e4eSSatish Balay 152e5c89e4eSSatish Balay PetscFunctionBegin; 1539c666560SBarry Smith while (fl) { 1549c666560SBarry Smith tmp = fl->next; 15500ac8be1SBarry Smith if (!fl->skipdereference) { 15600ac8be1SBarry Smith ierr = PetscObjectDereference(fl->obj);CHKERRQ(ierr); 15700ac8be1SBarry Smith } 1589c666560SBarry Smith ierr = PetscFree(fl);CHKERRQ(ierr); 1599c666560SBarry Smith fl = tmp; 160e5c89e4eSSatish Balay } 1610298fd71SBarry Smith *ifl = NULL; 162e5c89e4eSSatish Balay PetscFunctionReturn(0); 163e5c89e4eSSatish Balay } 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay 1661d0fab5eSBarry Smith /*@C 167140e18c1SBarry Smith PetscObjectListFind - givn a name, find the matching object 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay Input Parameters: 170e5c89e4eSSatish Balay + fl - pointer to list 171e5c89e4eSSatish Balay - name - name string 172e5c89e4eSSatish Balay 173e5c89e4eSSatish Balay Output Parameters: 174e5c89e4eSSatish Balay . ob - the PETSc object 175e5c89e4eSSatish Balay 176b235ab32SBarry Smith Level: developer 177b235ab32SBarry Smith 178e5c89e4eSSatish Balay Notes: 179140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 1803c0c59f3SBarry Smith 1813c0c59f3SBarry Smith The reference count of the object is not increased 182e5c89e4eSSatish Balay 183140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 184e5c89e4eSSatish Balay 1851d0fab5eSBarry Smith @*/ 186140e18c1SBarry Smith PetscErrorCode PetscObjectListFind(PetscObjectList fl,const char name[],PetscObject *obj) 187e5c89e4eSSatish Balay { 188e5c89e4eSSatish Balay PetscErrorCode ierr; 189ace3abfcSBarry Smith PetscBool match; 190e5c89e4eSSatish Balay 191e5c89e4eSSatish Balay PetscFunctionBegin; 192e5c89e4eSSatish Balay *obj = 0; 193e5c89e4eSSatish Balay while (fl) { 194e5c89e4eSSatish Balay ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 195e5c89e4eSSatish Balay if (match) { 196e5c89e4eSSatish Balay *obj = fl->obj; 197e5c89e4eSSatish Balay break; 198e5c89e4eSSatish Balay } 199e5c89e4eSSatish Balay fl = fl->next; 200e5c89e4eSSatish Balay } 201e5c89e4eSSatish Balay PetscFunctionReturn(0); 202e5c89e4eSSatish Balay } 203e5c89e4eSSatish Balay 2041d0fab5eSBarry Smith /*@C 205140e18c1SBarry Smith PetscObjectListReverseFind - given a object, find the matching name if it exists 206e5c89e4eSSatish Balay 207e5c89e4eSSatish Balay Input Parameters: 208e5c89e4eSSatish Balay + fl - pointer to list 209e5c89e4eSSatish Balay - ob - the PETSc object 210e5c89e4eSSatish Balay 211e5c89e4eSSatish Balay Output Parameters: 212bfec8eecSBarry Smith + name - name string 213bfec8eecSBarry Smith - skipdereference - if the object is list but does not have the increased reference count for a circular dependency 214e5c89e4eSSatish Balay 215b235ab32SBarry Smith Level: developer 216b235ab32SBarry Smith 217e5c89e4eSSatish Balay Notes: 218140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 2193c0c59f3SBarry Smith 2203c0c59f3SBarry Smith The reference count of the object is not increased 221e5c89e4eSSatish Balay 222140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListFind(), PetscObjectListDuplicate() 223e5c89e4eSSatish Balay 2241d0fab5eSBarry Smith @*/ 225140e18c1SBarry Smith PetscErrorCode PetscObjectListReverseFind(PetscObjectList fl,PetscObject obj,char **name,PetscBool *skipdereference) 226e5c89e4eSSatish Balay { 227e5c89e4eSSatish Balay PetscFunctionBegin; 228e5c89e4eSSatish Balay *name = 0; 229e5c89e4eSSatish Balay while (fl) { 230e5c89e4eSSatish Balay if (fl->obj == obj) { 231e5c89e4eSSatish Balay *name = fl->name; 232bfec8eecSBarry Smith if (skipdereference) *skipdereference = fl->skipdereference; 233e5c89e4eSSatish Balay break; 234e5c89e4eSSatish Balay } 235e5c89e4eSSatish Balay fl = fl->next; 236e5c89e4eSSatish Balay } 237e5c89e4eSSatish Balay PetscFunctionReturn(0); 238e5c89e4eSSatish Balay } 239e5c89e4eSSatish Balay 2401d0fab5eSBarry Smith /*@C 241140e18c1SBarry Smith PetscObjectListDuplicate - Creates a new list from a give object list. 242e5c89e4eSSatish Balay 243e5c89e4eSSatish Balay Input Parameters: 244e5c89e4eSSatish Balay . fl - pointer to list 245e5c89e4eSSatish Balay 246e5c89e4eSSatish Balay Output Parameters: 247e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 248e5c89e4eSSatish Balay 249b235ab32SBarry Smith Level: developer 250b235ab32SBarry Smith 251140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListReverseFind(), PetscObjectListFind(), PetscObjectListDuplicate() 252e5c89e4eSSatish Balay 2531d0fab5eSBarry Smith @*/ 254140e18c1SBarry Smith PetscErrorCode PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl) 255e5c89e4eSSatish Balay { 256e5c89e4eSSatish Balay PetscErrorCode ierr; 257e5c89e4eSSatish Balay 258e5c89e4eSSatish Balay PetscFunctionBegin; 259e5c89e4eSSatish Balay while (fl) { 260140e18c1SBarry Smith ierr = PetscObjectListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 261e5c89e4eSSatish Balay fl = fl->next; 262e5c89e4eSSatish Balay } 263e5c89e4eSSatish Balay PetscFunctionReturn(0); 264e5c89e4eSSatish Balay } 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay 268e5c89e4eSSatish Balay 269e5c89e4eSSatish Balay 270