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 82bb46157SSatish Balay struct _n_PetscOList { 9e5c89e4eSSatish Balay char name[256]; 10*6ba4bc90SBarry Smith PetscBool skipdereference; /* when the OList is destroyed do not call PetscObjectDereference() on this object */ 11e5c89e4eSSatish Balay PetscObject obj; 12e5c89e4eSSatish Balay PetscOList next; 13e5c89e4eSSatish Balay }; 14e5c89e4eSSatish Balay 15e5c89e4eSSatish Balay #undef __FUNCT__ 16*6ba4bc90SBarry Smith #define __FUNCT__ "PetscOListRemoveReference" 17*6ba4bc90SBarry Smith /*@C 18*6ba4bc90SBarry Smith PetscOListRemoveReference - Calls PetscObjectDereference() on an object in the list immediately but keeps a pointer to the object in the list. 19*6ba4bc90SBarry Smith 20*6ba4bc90SBarry Smith Input Parameters: 21*6ba4bc90SBarry Smith + fl - the object list 22*6ba4bc90SBarry Smith - name - the name to use for the object 23*6ba4bc90SBarry Smith 24*6ba4bc90SBarry Smith Level: developer 25*6ba4bc90SBarry Smith 26*6ba4bc90SBarry Smith Notes: Use PetscOListAdd(PetscOList,const char name[],PETSC_NULL) to truly remove the object from the list 27*6ba4bc90SBarry Smith 28*6ba4bc90SBarry Smith Use this routine ONLY if you know that the object referenced will remain in existence until the pointing object is destroyed 29*6ba4bc90SBarry Smith 30*6ba4bc90SBarry Smith Developer Note: this is to handle some cases that otherwise would result in having circular references so reference counts never got to zero 31*6ba4bc90SBarry Smith 32*6ba4bc90SBarry Smith .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate(), PetscOListAdd() 33*6ba4bc90SBarry Smith 34*6ba4bc90SBarry Smith @*/ 35*6ba4bc90SBarry Smith PetscErrorCode PetscOListRemoveReference(PetscOList *fl,const char name[]) 36*6ba4bc90SBarry Smith { 37*6ba4bc90SBarry Smith PetscOList nlist,prev; 38*6ba4bc90SBarry Smith PetscErrorCode ierr; 39*6ba4bc90SBarry Smith PetscBool match; 40*6ba4bc90SBarry Smith 41*6ba4bc90SBarry Smith PetscFunctionBegin; 42*6ba4bc90SBarry Smith nlist = *fl; prev = 0; 43*6ba4bc90SBarry Smith while (nlist) { 44*6ba4bc90SBarry Smith ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 45*6ba4bc90SBarry Smith if (match) { /* found it in the list */ 46*6ba4bc90SBarry Smith ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 47*6ba4bc90SBarry Smith nlist->skipdereference = PETSC_TRUE; 48*6ba4bc90SBarry Smith PetscFunctionReturn(0); 49*6ba4bc90SBarry Smith } 50*6ba4bc90SBarry Smith prev = nlist; 51*6ba4bc90SBarry Smith nlist = nlist->next; 52*6ba4bc90SBarry Smith } 53*6ba4bc90SBarry Smith PetscFunctionReturn(0); 54*6ba4bc90SBarry Smith } 55*6ba4bc90SBarry Smith 56*6ba4bc90SBarry Smith #undef __FUNCT__ 57e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListAdd" 581d0fab5eSBarry Smith /*@C 591d0fab5eSBarry Smith PetscOListAdd - Adds a new object to an PetscOList 60e5c89e4eSSatish Balay 611d0fab5eSBarry Smith Input Parameters: 621d0fab5eSBarry Smith + fl - the object list 631d0fab5eSBarry Smith . name - the name to use for the object 641d0fab5eSBarry Smith - obj - the object to attach 65e5c89e4eSSatish Balay 66b235ab32SBarry Smith Level: developer 67b235ab32SBarry Smith 681d0fab5eSBarry Smith Notes: Replaces item if it is already in list. Removes item if you pass in a PETSC_NULL object. 691d0fab5eSBarry Smith 701d0fab5eSBarry Smith Use PetscOListFind() or PetscOListReverseFind() to get the object back 711d0fab5eSBarry Smith 721d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 731d0fab5eSBarry Smith 741d0fab5eSBarry Smith @*/ 757087cfbeSBarry Smith PetscErrorCode PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj) 76e5c89e4eSSatish Balay { 77e5c89e4eSSatish Balay PetscOList olist,nlist,prev; 78e5c89e4eSSatish Balay PetscErrorCode ierr; 79ace3abfcSBarry Smith PetscBool match; 80e5c89e4eSSatish Balay 81e5c89e4eSSatish Balay PetscFunctionBegin; 82e5c89e4eSSatish Balay 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 */ 88e5c89e4eSSatish Balay ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 89e5c89e4eSSatish Balay if (prev) prev->next = nlist->next; 90e5c89e4eSSatish Balay else if (nlist->next) { 91e5c89e4eSSatish Balay *fl = nlist->next; 92e5c89e4eSSatish Balay } else { 93e5c89e4eSSatish Balay *fl = 0; 94e5c89e4eSSatish Balay } 95e5c89e4eSSatish Balay ierr = PetscFree(nlist);CHKERRQ(ierr); 96e5c89e4eSSatish Balay PetscFunctionReturn(0); 97e5c89e4eSSatish Balay } 98e5c89e4eSSatish Balay prev = nlist; 99e5c89e4eSSatish Balay nlist = nlist->next; 100e5c89e4eSSatish Balay } 101e5c89e4eSSatish Balay PetscFunctionReturn(0); /* did not find it to remove */ 102e5c89e4eSSatish Balay } 103e5c89e4eSSatish Balay /* look for it already in list */ 104e5c89e4eSSatish Balay nlist = *fl; 105e5c89e4eSSatish Balay while (nlist) { 106e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 107e5c89e4eSSatish Balay if (match) { /* found it in the list */ 108e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 1097dcf0eaaSdalcinl ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 110e5c89e4eSSatish Balay nlist->obj = obj; 111e5c89e4eSSatish Balay PetscFunctionReturn(0); 112e5c89e4eSSatish Balay } 113e5c89e4eSSatish Balay nlist = nlist->next; 114e5c89e4eSSatish Balay } 115e5c89e4eSSatish Balay 116e5c89e4eSSatish Balay /* add it to list, because it was not already there */ 117e5c89e4eSSatish Balay 1182bb46157SSatish Balay ierr = PetscNew(struct _n_PetscOList,&olist);CHKERRQ(ierr); 119e5c89e4eSSatish Balay olist->next = 0; 120e5c89e4eSSatish Balay olist->obj = obj; 121e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 122e5c89e4eSSatish Balay ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr); 123e5c89e4eSSatish Balay 124e5c89e4eSSatish Balay if (!*fl) { 125e5c89e4eSSatish Balay *fl = olist; 126e5c89e4eSSatish Balay } 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 136e5c89e4eSSatish Balay #undef __FUNCT__ 137e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDestroy" 1381d0fab5eSBarry Smith /*@C 139e5c89e4eSSatish Balay PetscOListDestroy - Destroy a list of objects 140e5c89e4eSSatish Balay 141e5c89e4eSSatish Balay Input Parameter: 1426bf464f9SBarry Smith . ifl - pointer to list 1431d0fab5eSBarry Smith 144b235ab32SBarry Smith Level: developer 145b235ab32SBarry Smith 1461d0fab5eSBarry Smith .seealso: PetscOListAdd(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 1471d0fab5eSBarry Smith 1481d0fab5eSBarry Smith @*/ 1496bf464f9SBarry Smith PetscErrorCode PetscOListDestroy(PetscOList *ifl) 150e5c89e4eSSatish Balay { 1516bf464f9SBarry Smith PetscOList tmp,fl = *ifl; 152e5c89e4eSSatish Balay PetscErrorCode ierr; 153e5c89e4eSSatish Balay 154e5c89e4eSSatish Balay PetscFunctionBegin; 1559c666560SBarry Smith while (fl) { 1569c666560SBarry Smith tmp = fl->next; 157*6ba4bc90SBarry Smith if (!fl->skipdereference) {ierr = PetscObjectDereference(fl->obj);CHKERRQ(ierr);} 1589c666560SBarry Smith ierr = PetscFree(fl);CHKERRQ(ierr); 1599c666560SBarry Smith fl = tmp; 160e5c89e4eSSatish Balay } 1616bf464f9SBarry Smith *ifl = PETSC_NULL; 162e5c89e4eSSatish Balay PetscFunctionReturn(0); 163e5c89e4eSSatish Balay } 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay 166e5c89e4eSSatish Balay #undef __FUNCT__ 167e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListFind" 1681d0fab5eSBarry Smith /*@C 169e5c89e4eSSatish Balay PetscOListFind - givn a name, find the matching object 170e5c89e4eSSatish Balay 171e5c89e4eSSatish Balay Input Parameters: 172e5c89e4eSSatish Balay + fl - pointer to list 173e5c89e4eSSatish Balay - name - name string 174e5c89e4eSSatish Balay 175e5c89e4eSSatish Balay Output Parameters: 176e5c89e4eSSatish Balay . ob - the PETSc object 177e5c89e4eSSatish Balay 178b235ab32SBarry Smith Level: developer 179b235ab32SBarry Smith 180e5c89e4eSSatish Balay Notes: 1813c0c59f3SBarry Smith The name must have been registered with the PetscOListAdd() before calling this routine. 1823c0c59f3SBarry Smith 1833c0c59f3SBarry Smith The reference count of the object is not increased 184e5c89e4eSSatish Balay 1851d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 186e5c89e4eSSatish Balay 1871d0fab5eSBarry Smith @*/ 1887087cfbeSBarry Smith PetscErrorCode PetscOListFind(PetscOList fl,const char name[],PetscObject *obj) 189e5c89e4eSSatish Balay { 190e5c89e4eSSatish Balay PetscErrorCode ierr; 191ace3abfcSBarry Smith PetscBool match; 192e5c89e4eSSatish Balay 193e5c89e4eSSatish Balay PetscFunctionBegin; 194e5c89e4eSSatish Balay *obj = 0; 195e5c89e4eSSatish Balay while (fl) { 196e5c89e4eSSatish Balay ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 197e5c89e4eSSatish Balay if (match) { 198e5c89e4eSSatish Balay *obj = fl->obj; 199e5c89e4eSSatish Balay break; 200e5c89e4eSSatish Balay } 201e5c89e4eSSatish Balay fl = fl->next; 202e5c89e4eSSatish Balay } 203e5c89e4eSSatish Balay PetscFunctionReturn(0); 204e5c89e4eSSatish Balay } 205e5c89e4eSSatish Balay 206e5c89e4eSSatish Balay #undef __FUNCT__ 207e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListReverseFind" 2081d0fab5eSBarry Smith /*@C 209e5c89e4eSSatish Balay PetscOListReverseFind - given a object, find the matching name if it exists 210e5c89e4eSSatish Balay 211e5c89e4eSSatish Balay Input Parameters: 212e5c89e4eSSatish Balay + fl - pointer to list 213e5c89e4eSSatish Balay - ob - the PETSc object 214e5c89e4eSSatish Balay 215e5c89e4eSSatish Balay Output Parameters: 216e5c89e4eSSatish Balay . name - name string 217e5c89e4eSSatish Balay 218b235ab32SBarry Smith Level: developer 219b235ab32SBarry Smith 220e5c89e4eSSatish Balay Notes: 2213c0c59f3SBarry Smith The name must have been registered with the PetscOListAdd() before calling this routine. 2223c0c59f3SBarry Smith 2233c0c59f3SBarry Smith The reference count of the object is not increased 224e5c89e4eSSatish Balay 2251d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListFind(), PetscOListDuplicate() 226e5c89e4eSSatish Balay 2271d0fab5eSBarry Smith @*/ 2287087cfbeSBarry Smith PetscErrorCode PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name) 229e5c89e4eSSatish Balay { 230e5c89e4eSSatish Balay PetscFunctionBegin; 231e5c89e4eSSatish Balay *name = 0; 232e5c89e4eSSatish Balay while (fl) { 233e5c89e4eSSatish Balay if (fl->obj == obj) { 234e5c89e4eSSatish Balay *name = fl->name; 235e5c89e4eSSatish Balay break; 236e5c89e4eSSatish Balay } 237e5c89e4eSSatish Balay fl = fl->next; 238e5c89e4eSSatish Balay } 239e5c89e4eSSatish Balay PetscFunctionReturn(0); 240e5c89e4eSSatish Balay } 241e5c89e4eSSatish Balay 242e5c89e4eSSatish Balay #undef __FUNCT__ 243e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDuplicate" 2441d0fab5eSBarry Smith /*@C 245e5c89e4eSSatish Balay PetscOListDuplicate - Creates a new list from a give object list. 246e5c89e4eSSatish Balay 247e5c89e4eSSatish Balay Input Parameters: 248e5c89e4eSSatish Balay . fl - pointer to list 249e5c89e4eSSatish Balay 250e5c89e4eSSatish Balay Output Parameters: 251e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 252e5c89e4eSSatish Balay 253b235ab32SBarry Smith Level: developer 254b235ab32SBarry Smith 2551d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListReverseFind(), PetscOListFind(), PetscOListDuplicate() 256e5c89e4eSSatish Balay 2571d0fab5eSBarry Smith @*/ 2587087cfbeSBarry Smith PetscErrorCode PetscOListDuplicate(PetscOList fl,PetscOList *nl) 259e5c89e4eSSatish Balay { 260e5c89e4eSSatish Balay PetscErrorCode ierr; 261e5c89e4eSSatish Balay 262e5c89e4eSSatish Balay PetscFunctionBegin; 263e5c89e4eSSatish Balay while (fl) { 264e5c89e4eSSatish Balay ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 265e5c89e4eSSatish Balay fl = fl->next; 266e5c89e4eSSatish Balay } 267e5c89e4eSSatish Balay PetscFunctionReturn(0); 268e5c89e4eSSatish Balay } 269e5c89e4eSSatish Balay 270e5c89e4eSSatish Balay 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay 273e5c89e4eSSatish Balay 274