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 */ 6*5f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.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 2495452b02SPatrick Sanan Notes: 2595452b02SPatrick 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 PetscBool match; 386ba4bc90SBarry Smith 396ba4bc90SBarry Smith PetscFunctionBegin; 40*5f80ce2aSJacob Faibussowitsch PetscValidPointer(fl,1); 41*5f80ce2aSJacob Faibussowitsch PetscValidCharPointer(name,2); 4287130e5eSHong Zhang nlist = *fl; 436ba4bc90SBarry Smith while (nlist) { 44*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(name,nlist->name,&match)); 4500ac8be1SBarry Smith if (match) { /* found it in the list */ 46*5f80ce2aSJacob Faibussowitsch if (!nlist->skipdereference) CHKERRQ(PetscObjectDereference(nlist->obj)); 476ba4bc90SBarry Smith nlist->skipdereference = PETSC_TRUE; 486ba4bc90SBarry Smith PetscFunctionReturn(0); 496ba4bc90SBarry Smith } 506ba4bc90SBarry Smith nlist = nlist->next; 516ba4bc90SBarry Smith } 526ba4bc90SBarry Smith PetscFunctionReturn(0); 536ba4bc90SBarry Smith } 546ba4bc90SBarry Smith 551d0fab5eSBarry Smith /*@C 56140e18c1SBarry Smith PetscObjectListAdd - Adds a new object to an PetscObjectList 57e5c89e4eSSatish Balay 581d0fab5eSBarry Smith Input Parameters: 591d0fab5eSBarry Smith + fl - the object list 601d0fab5eSBarry Smith . name - the name to use for the object 611d0fab5eSBarry Smith - obj - the object to attach 62e5c89e4eSSatish Balay 63b235ab32SBarry Smith Level: developer 64b235ab32SBarry Smith 6595452b02SPatrick Sanan Notes: 6695452b02SPatrick Sanan Replaces item if it is already in list. Removes item if you pass in a NULL object. 671d0fab5eSBarry Smith 68140e18c1SBarry Smith Use PetscObjectListFind() or PetscObjectListReverseFind() to get the object back 691d0fab5eSBarry Smith 70140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 711d0fab5eSBarry Smith 721d0fab5eSBarry Smith @*/ 73140e18c1SBarry Smith PetscErrorCode PetscObjectListAdd(PetscObjectList *fl,const char name[],PetscObject obj) 74e5c89e4eSSatish Balay { 75140e18c1SBarry Smith PetscObjectList olist,nlist,prev; 76ace3abfcSBarry Smith PetscBool match; 77e5c89e4eSSatish Balay 78e5c89e4eSSatish Balay PetscFunctionBegin; 79*5f80ce2aSJacob Faibussowitsch PetscValidPointer(fl,1); 80e5c89e4eSSatish Balay if (!obj) { /* this means remove from list if it is there */ 8102c9f0b5SLisandro Dalcin nlist = *fl; prev = NULL; 82e5c89e4eSSatish Balay while (nlist) { 83*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(name,nlist->name,&match)); 84e5c89e4eSSatish Balay if (match) { /* found it already in the list */ 854a0791bcSMatthew G. Knepley /* Remove it first to prevent circular derefs */ 86e5c89e4eSSatish Balay if (prev) prev->next = nlist->next; 87a297a907SKarl Rupp else if (nlist->next) *fl = nlist->next; 8802c9f0b5SLisandro Dalcin else *fl = NULL; 89*5f80ce2aSJacob Faibussowitsch if (!nlist->skipdereference) CHKERRQ(PetscObjectDereference(nlist->obj)); 90*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nlist)); 91e5c89e4eSSatish Balay PetscFunctionReturn(0); 92e5c89e4eSSatish Balay } 93e5c89e4eSSatish Balay prev = nlist; 94e5c89e4eSSatish Balay nlist = nlist->next; 95e5c89e4eSSatish Balay } 96e5c89e4eSSatish Balay PetscFunctionReturn(0); /* did not find it to remove */ 97e5c89e4eSSatish Balay } 98e5c89e4eSSatish Balay /* look for it already in list */ 99e5c89e4eSSatish Balay nlist = *fl; 100e5c89e4eSSatish Balay while (nlist) { 101*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(name,nlist->name,&match)); 102e5c89e4eSSatish Balay if (match) { /* found it in the list */ 103*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference(obj)); 104*5f80ce2aSJacob Faibussowitsch if (!nlist->skipdereference) CHKERRQ(PetscObjectDereference(nlist->obj)); 10500ac8be1SBarry Smith nlist->skipdereference = PETSC_FALSE; 106e5c89e4eSSatish Balay nlist->obj = obj; 107e5c89e4eSSatish Balay PetscFunctionReturn(0); 108e5c89e4eSSatish Balay } 109e5c89e4eSSatish Balay nlist = nlist->next; 110e5c89e4eSSatish Balay } 111e5c89e4eSSatish Balay 112e5c89e4eSSatish Balay /* add it to list, because it was not already there */ 113*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNew(&olist)); 11402c9f0b5SLisandro Dalcin olist->next = NULL; 115e5c89e4eSSatish Balay olist->obj = obj; 116a297a907SKarl Rupp 117*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference(obj)); 118*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcpy(olist->name,name)); 119e5c89e4eSSatish Balay 120a297a907SKarl Rupp if (!*fl) *fl = olist; 121a297a907SKarl Rupp else { /* go to end of list */ 122e5c89e4eSSatish Balay nlist = *fl; 123*5f80ce2aSJacob Faibussowitsch while (nlist->next) nlist = nlist->next; 124e5c89e4eSSatish Balay nlist->next = olist; 125e5c89e4eSSatish Balay } 126e5c89e4eSSatish Balay PetscFunctionReturn(0); 127e5c89e4eSSatish Balay } 128e5c89e4eSSatish Balay 1291d0fab5eSBarry Smith /*@C 130140e18c1SBarry Smith PetscObjectListDestroy - Destroy a list of objects 131e5c89e4eSSatish Balay 132e5c89e4eSSatish Balay Input Parameter: 1336bf464f9SBarry Smith . ifl - pointer to list 1341d0fab5eSBarry Smith 135b235ab32SBarry Smith Level: developer 136b235ab32SBarry Smith 137140e18c1SBarry Smith .seealso: PetscObjectListAdd(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 1381d0fab5eSBarry Smith 1391d0fab5eSBarry Smith @*/ 140140e18c1SBarry Smith PetscErrorCode PetscObjectListDestroy(PetscObjectList *ifl) 141e5c89e4eSSatish Balay { 142*5f80ce2aSJacob Faibussowitsch PetscObjectList tmp,fl; 143e5c89e4eSSatish Balay 144e5c89e4eSSatish Balay PetscFunctionBegin; 145*5f80ce2aSJacob Faibussowitsch PetscValidPointer(ifl,1); 146*5f80ce2aSJacob Faibussowitsch fl = *ifl; 1479c666560SBarry Smith while (fl) { 1489c666560SBarry Smith tmp = fl->next; 149*5f80ce2aSJacob Faibussowitsch if (!fl->skipdereference) CHKERRQ(PetscObjectDereference(fl->obj)); 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(fl)); 1519c666560SBarry Smith fl = tmp; 152e5c89e4eSSatish Balay } 1530298fd71SBarry Smith *ifl = NULL; 154e5c89e4eSSatish Balay PetscFunctionReturn(0); 155e5c89e4eSSatish Balay } 156e5c89e4eSSatish Balay 1571d0fab5eSBarry Smith /*@C 158140e18c1SBarry Smith PetscObjectListFind - givn a name, find the matching object 159e5c89e4eSSatish Balay 160e5c89e4eSSatish Balay Input Parameters: 161e5c89e4eSSatish Balay + fl - pointer to list 162e5c89e4eSSatish Balay - name - name string 163e5c89e4eSSatish Balay 164e5c89e4eSSatish Balay Output Parameters: 1657243573dSPierre Jolivet . obj - the PETSc object 166e5c89e4eSSatish Balay 167b235ab32SBarry Smith Level: developer 168b235ab32SBarry Smith 169e5c89e4eSSatish Balay Notes: 170140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 1713c0c59f3SBarry Smith 1723c0c59f3SBarry Smith The reference count of the object is not increased 173e5c89e4eSSatish Balay 174140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 175e5c89e4eSSatish Balay 1761d0fab5eSBarry Smith @*/ 177140e18c1SBarry Smith PetscErrorCode PetscObjectListFind(PetscObjectList fl,const char name[],PetscObject *obj) 178e5c89e4eSSatish Balay { 179e5c89e4eSSatish Balay PetscFunctionBegin; 180*5f80ce2aSJacob Faibussowitsch PetscValidPointer(obj,3); 18102c9f0b5SLisandro Dalcin *obj = NULL; 182e5c89e4eSSatish Balay while (fl) { 183*5f80ce2aSJacob Faibussowitsch PetscBool match; 184*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(name,fl->name,&match)); 185e5c89e4eSSatish Balay if (match) { 186e5c89e4eSSatish Balay *obj = fl->obj; 187e5c89e4eSSatish Balay break; 188e5c89e4eSSatish Balay } 189e5c89e4eSSatish Balay fl = fl->next; 190e5c89e4eSSatish Balay } 191e5c89e4eSSatish Balay PetscFunctionReturn(0); 192e5c89e4eSSatish Balay } 193e5c89e4eSSatish Balay 1941d0fab5eSBarry Smith /*@C 195140e18c1SBarry Smith PetscObjectListReverseFind - given a object, find the matching name if it exists 196e5c89e4eSSatish Balay 197e5c89e4eSSatish Balay Input Parameters: 198e5c89e4eSSatish Balay + fl - pointer to list 1997243573dSPierre Jolivet - obj - the PETSc object 200e5c89e4eSSatish Balay 201e5c89e4eSSatish Balay Output Parameters: 202bfec8eecSBarry Smith + name - name string 2035e8f358bSStefano Zampini - skipdereference - if the object is in list but does not have the increased reference count for a circular dependency 204e5c89e4eSSatish Balay 205b235ab32SBarry Smith Level: developer 206b235ab32SBarry Smith 207e5c89e4eSSatish Balay Notes: 208140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 2093c0c59f3SBarry Smith 2103c0c59f3SBarry Smith The reference count of the object is not increased 211e5c89e4eSSatish Balay 212140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListFind(), PetscObjectListDuplicate() 213e5c89e4eSSatish Balay 2141d0fab5eSBarry Smith @*/ 215140e18c1SBarry Smith PetscErrorCode PetscObjectListReverseFind(PetscObjectList fl,PetscObject obj,char **name,PetscBool *skipdereference) 216e5c89e4eSSatish Balay { 217e5c89e4eSSatish Balay PetscFunctionBegin; 218*5f80ce2aSJacob Faibussowitsch PetscValidPointer(name,3); 219*5f80ce2aSJacob Faibussowitsch if (skipdereference) PetscValidBoolPointer(skipdereference,4); 22002c9f0b5SLisandro Dalcin *name = NULL; 221e5c89e4eSSatish Balay while (fl) { 222e5c89e4eSSatish Balay if (fl->obj == obj) { 223e5c89e4eSSatish Balay *name = fl->name; 224bfec8eecSBarry Smith if (skipdereference) *skipdereference = fl->skipdereference; 225e5c89e4eSSatish Balay break; 226e5c89e4eSSatish Balay } 227e5c89e4eSSatish Balay fl = fl->next; 228e5c89e4eSSatish Balay } 229e5c89e4eSSatish Balay PetscFunctionReturn(0); 230e5c89e4eSSatish Balay } 231e5c89e4eSSatish Balay 2321d0fab5eSBarry Smith /*@C 2335e8f358bSStefano Zampini PetscObjectListDuplicate - Creates a new list from a given object list. 234e5c89e4eSSatish Balay 235e5c89e4eSSatish Balay Input Parameters: 236e5c89e4eSSatish Balay . fl - pointer to list 237e5c89e4eSSatish Balay 238e5c89e4eSSatish Balay Output Parameters: 239e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 240e5c89e4eSSatish Balay 241b235ab32SBarry Smith Level: developer 242b235ab32SBarry Smith 243140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListReverseFind(), PetscObjectListFind(), PetscObjectListDuplicate() 244e5c89e4eSSatish Balay 2451d0fab5eSBarry Smith @*/ 246140e18c1SBarry Smith PetscErrorCode PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl) 247e5c89e4eSSatish Balay { 248e5c89e4eSSatish Balay PetscFunctionBegin; 249*5f80ce2aSJacob Faibussowitsch PetscValidPointer(nl,2); 250e5c89e4eSSatish Balay while (fl) { 251*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectListAdd(nl,fl->name,fl->obj)); 252e5c89e4eSSatish Balay fl = fl->next; 253e5c89e4eSSatish Balay } 254e5c89e4eSSatish Balay PetscFunctionReturn(0); 255e5c89e4eSSatish Balay } 256