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 15e5c89e4eSSatish Balay #undef __FUNCT__ 16140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListRemoveReference" 176ba4bc90SBarry Smith /*@C 18140e18c1SBarry Smith PetscObjectListRemoveReference - Calls PetscObjectDereference() on an object in the list immediately but keeps a pointer to the object in the list. 196ba4bc90SBarry Smith 206ba4bc90SBarry Smith Input Parameters: 216ba4bc90SBarry Smith + fl - the object list 226ba4bc90SBarry Smith - name - the name to use for the object 236ba4bc90SBarry Smith 246ba4bc90SBarry Smith Level: developer 256ba4bc90SBarry Smith 26*0298fd71SBarry Smith Notes: Use PetscObjectListAdd(PetscObjectList,const char name[],NULL) to truly remove the object from the list 276ba4bc90SBarry Smith 286ba4bc90SBarry Smith Use this routine ONLY if you know that the object referenced will remain in existence until the pointing object is destroyed 296ba4bc90SBarry Smith 306ba4bc90SBarry Smith Developer Note: this is to handle some cases that otherwise would result in having circular references so reference counts never got to zero 316ba4bc90SBarry Smith 32140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate(), PetscObjectListAdd() 336ba4bc90SBarry Smith 346ba4bc90SBarry Smith @*/ 35140e18c1SBarry Smith PetscErrorCode PetscObjectListRemoveReference(PetscObjectList *fl,const char name[]) 366ba4bc90SBarry Smith { 37140e18c1SBarry Smith PetscObjectList nlist; 386ba4bc90SBarry Smith PetscErrorCode ierr; 396ba4bc90SBarry Smith PetscBool match; 406ba4bc90SBarry Smith 416ba4bc90SBarry Smith PetscFunctionBegin; 4287130e5eSHong Zhang nlist = *fl; 436ba4bc90SBarry Smith while (nlist) { 446ba4bc90SBarry Smith ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 4500ac8be1SBarry Smith if (match) { /* found it in the list */ 4600ac8be1SBarry Smith if (!nlist->skipdereference) { 476ba4bc90SBarry Smith ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 4800ac8be1SBarry Smith } 496ba4bc90SBarry Smith nlist->skipdereference = PETSC_TRUE; 506ba4bc90SBarry Smith PetscFunctionReturn(0); 516ba4bc90SBarry Smith } 526ba4bc90SBarry Smith nlist = nlist->next; 536ba4bc90SBarry Smith } 546ba4bc90SBarry Smith PetscFunctionReturn(0); 556ba4bc90SBarry Smith } 566ba4bc90SBarry Smith 576ba4bc90SBarry Smith #undef __FUNCT__ 58140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListAdd" 591d0fab5eSBarry Smith /*@C 60140e18c1SBarry Smith PetscObjectListAdd - Adds a new object to an PetscObjectList 61e5c89e4eSSatish Balay 621d0fab5eSBarry Smith Input Parameters: 631d0fab5eSBarry Smith + fl - the object list 641d0fab5eSBarry Smith . name - the name to use for the object 651d0fab5eSBarry Smith - obj - the object to attach 66e5c89e4eSSatish Balay 67b235ab32SBarry Smith Level: developer 68b235ab32SBarry Smith 69*0298fd71SBarry Smith Notes: Replaces item if it is already in list. Removes item if you pass in a NULL object. 701d0fab5eSBarry Smith 71140e18c1SBarry Smith Use PetscObjectListFind() or PetscObjectListReverseFind() to get the object back 721d0fab5eSBarry Smith 73140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 741d0fab5eSBarry Smith 751d0fab5eSBarry Smith @*/ 76140e18c1SBarry Smith PetscErrorCode PetscObjectListAdd(PetscObjectList *fl,const char name[],PetscObject obj) 77e5c89e4eSSatish Balay { 78140e18c1SBarry Smith PetscObjectList olist,nlist,prev; 79e5c89e4eSSatish Balay PetscErrorCode ierr; 80ace3abfcSBarry Smith PetscBool match; 81e5c89e4eSSatish Balay 82e5c89e4eSSatish Balay PetscFunctionBegin; 83e5c89e4eSSatish Balay if (!obj) { /* this means remove from list if it is there */ 84e5c89e4eSSatish Balay nlist = *fl; prev = 0; 85e5c89e4eSSatish Balay while (nlist) { 86e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 87e5c89e4eSSatish Balay if (match) { /* found it already in the list */ 8800ac8be1SBarry Smith if (!nlist->skipdereference) { 89e5c89e4eSSatish Balay ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 9000ac8be1SBarry Smith } 91e5c89e4eSSatish Balay if (prev) prev->next = nlist->next; 92a297a907SKarl Rupp else if (nlist->next) *fl = nlist->next; 93a297a907SKarl Rupp else *fl = 0; 94e5c89e4eSSatish Balay ierr = PetscFree(nlist);CHKERRQ(ierr); 95e5c89e4eSSatish Balay PetscFunctionReturn(0); 96e5c89e4eSSatish Balay } 97e5c89e4eSSatish Balay prev = nlist; 98e5c89e4eSSatish Balay nlist = nlist->next; 99e5c89e4eSSatish Balay } 100e5c89e4eSSatish Balay PetscFunctionReturn(0); /* did not find it to remove */ 101e5c89e4eSSatish Balay } 102e5c89e4eSSatish Balay /* look for it already in list */ 103e5c89e4eSSatish Balay nlist = *fl; 104e5c89e4eSSatish Balay while (nlist) { 105e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 106e5c89e4eSSatish Balay if (match) { /* found it in the list */ 107e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 10800ac8be1SBarry Smith if (!nlist->skipdereference) { 1097dcf0eaaSdalcinl ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 11000ac8be1SBarry Smith } 11100ac8be1SBarry Smith nlist->skipdereference = PETSC_FALSE; 112e5c89e4eSSatish Balay nlist->obj = obj; 113e5c89e4eSSatish Balay PetscFunctionReturn(0); 114e5c89e4eSSatish Balay } 115e5c89e4eSSatish Balay nlist = nlist->next; 116e5c89e4eSSatish Balay } 117e5c89e4eSSatish Balay 118e5c89e4eSSatish Balay /* add it to list, because it was not already there */ 119140e18c1SBarry Smith ierr = PetscNew(struct _n_PetscObjectList,&olist);CHKERRQ(ierr); 120e5c89e4eSSatish Balay olist->next = 0; 121e5c89e4eSSatish Balay olist->obj = obj; 122a297a907SKarl Rupp 123e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 124e5c89e4eSSatish Balay ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr); 125e5c89e4eSSatish Balay 126a297a907SKarl Rupp if (!*fl) *fl = olist; 127a297a907SKarl Rupp else { /* go to end of list */ 128e5c89e4eSSatish Balay nlist = *fl; 129e5c89e4eSSatish Balay while (nlist->next) { 130e5c89e4eSSatish Balay nlist = nlist->next; 131e5c89e4eSSatish Balay } 132e5c89e4eSSatish Balay nlist->next = olist; 133e5c89e4eSSatish Balay } 134e5c89e4eSSatish Balay PetscFunctionReturn(0); 135e5c89e4eSSatish Balay } 136e5c89e4eSSatish Balay 137e5c89e4eSSatish Balay #undef __FUNCT__ 138140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListDestroy" 1391d0fab5eSBarry Smith /*@C 140140e18c1SBarry Smith PetscObjectListDestroy - Destroy a list of objects 141e5c89e4eSSatish Balay 142e5c89e4eSSatish Balay Input Parameter: 1436bf464f9SBarry Smith . ifl - pointer to list 1441d0fab5eSBarry Smith 145b235ab32SBarry Smith Level: developer 146b235ab32SBarry Smith 147140e18c1SBarry Smith .seealso: PetscObjectListAdd(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 1481d0fab5eSBarry Smith 1491d0fab5eSBarry Smith @*/ 150140e18c1SBarry Smith PetscErrorCode PetscObjectListDestroy(PetscObjectList *ifl) 151e5c89e4eSSatish Balay { 152140e18c1SBarry Smith PetscObjectList tmp,fl = *ifl; 153e5c89e4eSSatish Balay PetscErrorCode ierr; 154e5c89e4eSSatish Balay 155e5c89e4eSSatish Balay PetscFunctionBegin; 1569c666560SBarry Smith while (fl) { 1579c666560SBarry Smith tmp = fl->next; 15800ac8be1SBarry Smith if (!fl->skipdereference) { 15900ac8be1SBarry Smith ierr = PetscObjectDereference(fl->obj);CHKERRQ(ierr); 16000ac8be1SBarry Smith } 1619c666560SBarry Smith ierr = PetscFree(fl);CHKERRQ(ierr); 1629c666560SBarry Smith fl = tmp; 163e5c89e4eSSatish Balay } 164*0298fd71SBarry Smith *ifl = NULL; 165e5c89e4eSSatish Balay PetscFunctionReturn(0); 166e5c89e4eSSatish Balay } 167e5c89e4eSSatish Balay 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay #undef __FUNCT__ 170140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListFind" 1711d0fab5eSBarry Smith /*@C 172140e18c1SBarry Smith PetscObjectListFind - givn a name, find the matching object 173e5c89e4eSSatish Balay 174e5c89e4eSSatish Balay Input Parameters: 175e5c89e4eSSatish Balay + fl - pointer to list 176e5c89e4eSSatish Balay - name - name string 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay Output Parameters: 179e5c89e4eSSatish Balay . ob - the PETSc object 180e5c89e4eSSatish Balay 181b235ab32SBarry Smith Level: developer 182b235ab32SBarry Smith 183e5c89e4eSSatish Balay Notes: 184140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 1853c0c59f3SBarry Smith 1863c0c59f3SBarry Smith The reference count of the object is not increased 187e5c89e4eSSatish Balay 188140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate() 189e5c89e4eSSatish Balay 1901d0fab5eSBarry Smith @*/ 191140e18c1SBarry Smith PetscErrorCode PetscObjectListFind(PetscObjectList fl,const char name[],PetscObject *obj) 192e5c89e4eSSatish Balay { 193e5c89e4eSSatish Balay PetscErrorCode ierr; 194ace3abfcSBarry Smith PetscBool match; 195e5c89e4eSSatish Balay 196e5c89e4eSSatish Balay PetscFunctionBegin; 197e5c89e4eSSatish Balay *obj = 0; 198e5c89e4eSSatish Balay while (fl) { 199e5c89e4eSSatish Balay ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 200e5c89e4eSSatish Balay if (match) { 201e5c89e4eSSatish Balay *obj = fl->obj; 202e5c89e4eSSatish Balay break; 203e5c89e4eSSatish Balay } 204e5c89e4eSSatish Balay fl = fl->next; 205e5c89e4eSSatish Balay } 206e5c89e4eSSatish Balay PetscFunctionReturn(0); 207e5c89e4eSSatish Balay } 208e5c89e4eSSatish Balay 209e5c89e4eSSatish Balay #undef __FUNCT__ 210140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListReverseFind" 2111d0fab5eSBarry Smith /*@C 212140e18c1SBarry Smith PetscObjectListReverseFind - given a object, find the matching name if it exists 213e5c89e4eSSatish Balay 214e5c89e4eSSatish Balay Input Parameters: 215e5c89e4eSSatish Balay + fl - pointer to list 216e5c89e4eSSatish Balay - ob - the PETSc object 217e5c89e4eSSatish Balay 218e5c89e4eSSatish Balay Output Parameters: 219bfec8eecSBarry Smith + name - name string 220bfec8eecSBarry Smith - skipdereference - if the object is list but does not have the increased reference count for a circular dependency 221e5c89e4eSSatish Balay 222b235ab32SBarry Smith Level: developer 223b235ab32SBarry Smith 224e5c89e4eSSatish Balay Notes: 225140e18c1SBarry Smith The name must have been registered with the PetscObjectListAdd() before calling this routine. 2263c0c59f3SBarry Smith 2273c0c59f3SBarry Smith The reference count of the object is not increased 228e5c89e4eSSatish Balay 229140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListFind(), PetscObjectListDuplicate() 230e5c89e4eSSatish Balay 2311d0fab5eSBarry Smith @*/ 232140e18c1SBarry Smith PetscErrorCode PetscObjectListReverseFind(PetscObjectList fl,PetscObject obj,char **name,PetscBool *skipdereference) 233e5c89e4eSSatish Balay { 234e5c89e4eSSatish Balay PetscFunctionBegin; 235e5c89e4eSSatish Balay *name = 0; 236e5c89e4eSSatish Balay while (fl) { 237e5c89e4eSSatish Balay if (fl->obj == obj) { 238e5c89e4eSSatish Balay *name = fl->name; 239bfec8eecSBarry Smith if (skipdereference) *skipdereference = fl->skipdereference; 240e5c89e4eSSatish Balay break; 241e5c89e4eSSatish Balay } 242e5c89e4eSSatish Balay fl = fl->next; 243e5c89e4eSSatish Balay } 244e5c89e4eSSatish Balay PetscFunctionReturn(0); 245e5c89e4eSSatish Balay } 246e5c89e4eSSatish Balay 247e5c89e4eSSatish Balay #undef __FUNCT__ 248140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListDuplicate" 2491d0fab5eSBarry Smith /*@C 250140e18c1SBarry Smith PetscObjectListDuplicate - Creates a new list from a give object list. 251e5c89e4eSSatish Balay 252e5c89e4eSSatish Balay Input Parameters: 253e5c89e4eSSatish Balay . fl - pointer to list 254e5c89e4eSSatish Balay 255e5c89e4eSSatish Balay Output Parameters: 256e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 257e5c89e4eSSatish Balay 258b235ab32SBarry Smith Level: developer 259b235ab32SBarry Smith 260140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListReverseFind(), PetscObjectListFind(), PetscObjectListDuplicate() 261e5c89e4eSSatish Balay 2621d0fab5eSBarry Smith @*/ 263140e18c1SBarry Smith PetscErrorCode PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl) 264e5c89e4eSSatish Balay { 265e5c89e4eSSatish Balay PetscErrorCode ierr; 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay PetscFunctionBegin; 268e5c89e4eSSatish Balay while (fl) { 269140e18c1SBarry Smith ierr = PetscObjectListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 270e5c89e4eSSatish Balay fl = fl->next; 271e5c89e4eSSatish Balay } 272e5c89e4eSSatish Balay PetscFunctionReturn(0); 273e5c89e4eSSatish Balay } 274e5c89e4eSSatish Balay 275e5c89e4eSSatish Balay 276e5c89e4eSSatish Balay 277e5c89e4eSSatish Balay 278e5c89e4eSSatish Balay 279