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]; 106ba4bc90SBarry 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__ 166ba4bc90SBarry Smith #define __FUNCT__ "PetscOListRemoveReference" 176ba4bc90SBarry Smith /*@C 186ba4bc90SBarry Smith PetscOListRemoveReference - 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 266ba4bc90SBarry Smith Notes: Use PetscOListAdd(PetscOList,const char name[],PETSC_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 326ba4bc90SBarry Smith .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate(), PetscOListAdd() 336ba4bc90SBarry Smith 346ba4bc90SBarry Smith @*/ 356ba4bc90SBarry Smith PetscErrorCode PetscOListRemoveReference(PetscOList *fl,const char name[]) 366ba4bc90SBarry Smith { 3787130e5eSHong Zhang PetscOList 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); 45*00ac8be1SBarry Smith if (match) { /* found it in the list */ 46*00ac8be1SBarry Smith if (!nlist->skipdereference) { 476ba4bc90SBarry Smith ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 48*00ac8be1SBarry 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__ 58e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListAdd" 591d0fab5eSBarry Smith /*@C 601d0fab5eSBarry Smith PetscOListAdd - Adds a new object to an PetscOList 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 691d0fab5eSBarry Smith Notes: Replaces item if it is already in list. Removes item if you pass in a PETSC_NULL object. 701d0fab5eSBarry Smith 711d0fab5eSBarry Smith Use PetscOListFind() or PetscOListReverseFind() to get the object back 721d0fab5eSBarry Smith 731d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 741d0fab5eSBarry Smith 751d0fab5eSBarry Smith @*/ 767087cfbeSBarry Smith PetscErrorCode PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj) 77e5c89e4eSSatish Balay { 78e5c89e4eSSatish Balay PetscOList olist,nlist,prev; 79e5c89e4eSSatish Balay PetscErrorCode ierr; 80ace3abfcSBarry Smith PetscBool match; 81e5c89e4eSSatish Balay 82e5c89e4eSSatish Balay PetscFunctionBegin; 83e5c89e4eSSatish Balay 84e5c89e4eSSatish Balay if (!obj) { /* this means remove from list if it is there */ 85e5c89e4eSSatish Balay nlist = *fl; prev = 0; 86e5c89e4eSSatish Balay while (nlist) { 87e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 88e5c89e4eSSatish Balay if (match) { /* found it already in the list */ 89*00ac8be1SBarry Smith if (!nlist->skipdereference) { 90e5c89e4eSSatish Balay ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 91*00ac8be1SBarry Smith } 92e5c89e4eSSatish Balay if (prev) prev->next = nlist->next; 93e5c89e4eSSatish Balay else if (nlist->next) { 94e5c89e4eSSatish Balay *fl = nlist->next; 95e5c89e4eSSatish Balay } else { 96e5c89e4eSSatish Balay *fl = 0; 97e5c89e4eSSatish Balay } 98e5c89e4eSSatish Balay ierr = PetscFree(nlist);CHKERRQ(ierr); 99e5c89e4eSSatish Balay PetscFunctionReturn(0); 100e5c89e4eSSatish Balay } 101e5c89e4eSSatish Balay prev = nlist; 102e5c89e4eSSatish Balay nlist = nlist->next; 103e5c89e4eSSatish Balay } 104e5c89e4eSSatish Balay PetscFunctionReturn(0); /* did not find it to remove */ 105e5c89e4eSSatish Balay } 106e5c89e4eSSatish Balay /* look for it already in list */ 107e5c89e4eSSatish Balay nlist = *fl; 108e5c89e4eSSatish Balay while (nlist) { 109e5c89e4eSSatish Balay ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 110e5c89e4eSSatish Balay if (match) { /* found it in the list */ 111e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 112*00ac8be1SBarry Smith if (!nlist->skipdereference) { 1137dcf0eaaSdalcinl ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 114*00ac8be1SBarry Smith } 115*00ac8be1SBarry Smith nlist->skipdereference = PETSC_FALSE; 116e5c89e4eSSatish Balay nlist->obj = obj; 117e5c89e4eSSatish Balay PetscFunctionReturn(0); 118e5c89e4eSSatish Balay } 119e5c89e4eSSatish Balay nlist = nlist->next; 120e5c89e4eSSatish Balay } 121e5c89e4eSSatish Balay 122e5c89e4eSSatish Balay /* add it to list, because it was not already there */ 1232bb46157SSatish Balay ierr = PetscNew(struct _n_PetscOList,&olist);CHKERRQ(ierr); 124e5c89e4eSSatish Balay olist->next = 0; 125e5c89e4eSSatish Balay olist->obj = obj; 126e5c89e4eSSatish Balay ierr = PetscObjectReference(obj);CHKERRQ(ierr); 127e5c89e4eSSatish Balay ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr); 128e5c89e4eSSatish Balay 129e5c89e4eSSatish Balay if (!*fl) { 130e5c89e4eSSatish Balay *fl = olist; 131e5c89e4eSSatish Balay } else { /* go to end of list */ 132e5c89e4eSSatish Balay nlist = *fl; 133e5c89e4eSSatish Balay while (nlist->next) { 134e5c89e4eSSatish Balay nlist = nlist->next; 135e5c89e4eSSatish Balay } 136e5c89e4eSSatish Balay nlist->next = olist; 137e5c89e4eSSatish Balay } 138e5c89e4eSSatish Balay PetscFunctionReturn(0); 139e5c89e4eSSatish Balay } 140e5c89e4eSSatish Balay 141e5c89e4eSSatish Balay #undef __FUNCT__ 142e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDestroy" 1431d0fab5eSBarry Smith /*@C 144e5c89e4eSSatish Balay PetscOListDestroy - Destroy a list of objects 145e5c89e4eSSatish Balay 146e5c89e4eSSatish Balay Input Parameter: 1476bf464f9SBarry Smith . ifl - pointer to list 1481d0fab5eSBarry Smith 149b235ab32SBarry Smith Level: developer 150b235ab32SBarry Smith 1511d0fab5eSBarry Smith .seealso: PetscOListAdd(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 1521d0fab5eSBarry Smith 1531d0fab5eSBarry Smith @*/ 1546bf464f9SBarry Smith PetscErrorCode PetscOListDestroy(PetscOList *ifl) 155e5c89e4eSSatish Balay { 1566bf464f9SBarry Smith PetscOList tmp,fl = *ifl; 157e5c89e4eSSatish Balay PetscErrorCode ierr; 158e5c89e4eSSatish Balay 159e5c89e4eSSatish Balay PetscFunctionBegin; 1609c666560SBarry Smith while (fl) { 1619c666560SBarry Smith tmp = fl->next; 162*00ac8be1SBarry Smith if (!fl->skipdereference) { 163*00ac8be1SBarry Smith ierr = PetscObjectDereference(fl->obj);CHKERRQ(ierr); 164*00ac8be1SBarry Smith } 1659c666560SBarry Smith ierr = PetscFree(fl);CHKERRQ(ierr); 1669c666560SBarry Smith fl = tmp; 167e5c89e4eSSatish Balay } 1686bf464f9SBarry Smith *ifl = PETSC_NULL; 169e5c89e4eSSatish Balay PetscFunctionReturn(0); 170e5c89e4eSSatish Balay } 171e5c89e4eSSatish Balay 172e5c89e4eSSatish Balay 173e5c89e4eSSatish Balay #undef __FUNCT__ 174e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListFind" 1751d0fab5eSBarry Smith /*@C 176e5c89e4eSSatish Balay PetscOListFind - givn a name, find the matching object 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay Input Parameters: 179e5c89e4eSSatish Balay + fl - pointer to list 180e5c89e4eSSatish Balay - name - name string 181e5c89e4eSSatish Balay 182e5c89e4eSSatish Balay Output Parameters: 183e5c89e4eSSatish Balay . ob - the PETSc object 184e5c89e4eSSatish Balay 185b235ab32SBarry Smith Level: developer 186b235ab32SBarry Smith 187e5c89e4eSSatish Balay Notes: 1883c0c59f3SBarry Smith The name must have been registered with the PetscOListAdd() before calling this routine. 1893c0c59f3SBarry Smith 1903c0c59f3SBarry Smith The reference count of the object is not increased 191e5c89e4eSSatish Balay 1921d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate() 193e5c89e4eSSatish Balay 1941d0fab5eSBarry Smith @*/ 1957087cfbeSBarry Smith PetscErrorCode PetscOListFind(PetscOList fl,const char name[],PetscObject *obj) 196e5c89e4eSSatish Balay { 197e5c89e4eSSatish Balay PetscErrorCode ierr; 198ace3abfcSBarry Smith PetscBool match; 199e5c89e4eSSatish Balay 200e5c89e4eSSatish Balay PetscFunctionBegin; 201e5c89e4eSSatish Balay *obj = 0; 202e5c89e4eSSatish Balay while (fl) { 203e5c89e4eSSatish Balay ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 204e5c89e4eSSatish Balay if (match) { 205e5c89e4eSSatish Balay *obj = fl->obj; 206e5c89e4eSSatish Balay break; 207e5c89e4eSSatish Balay } 208e5c89e4eSSatish Balay fl = fl->next; 209e5c89e4eSSatish Balay } 210e5c89e4eSSatish Balay PetscFunctionReturn(0); 211e5c89e4eSSatish Balay } 212e5c89e4eSSatish Balay 213e5c89e4eSSatish Balay #undef __FUNCT__ 214e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListReverseFind" 2151d0fab5eSBarry Smith /*@C 216e5c89e4eSSatish Balay PetscOListReverseFind - given a object, find the matching name if it exists 217e5c89e4eSSatish Balay 218e5c89e4eSSatish Balay Input Parameters: 219e5c89e4eSSatish Balay + fl - pointer to list 220e5c89e4eSSatish Balay - ob - the PETSc object 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay Output Parameters: 223e5c89e4eSSatish Balay . name - name string 224e5c89e4eSSatish Balay 225b235ab32SBarry Smith Level: developer 226b235ab32SBarry Smith 227e5c89e4eSSatish Balay Notes: 2283c0c59f3SBarry Smith The name must have been registered with the PetscOListAdd() before calling this routine. 2293c0c59f3SBarry Smith 2303c0c59f3SBarry Smith The reference count of the object is not increased 231e5c89e4eSSatish Balay 2321d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListFind(), PetscOListDuplicate() 233e5c89e4eSSatish Balay 2341d0fab5eSBarry Smith @*/ 2357087cfbeSBarry Smith PetscErrorCode PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name) 236e5c89e4eSSatish Balay { 237e5c89e4eSSatish Balay PetscFunctionBegin; 238e5c89e4eSSatish Balay *name = 0; 239e5c89e4eSSatish Balay while (fl) { 240e5c89e4eSSatish Balay if (fl->obj == obj) { 241e5c89e4eSSatish Balay *name = fl->name; 242e5c89e4eSSatish Balay break; 243e5c89e4eSSatish Balay } 244e5c89e4eSSatish Balay fl = fl->next; 245e5c89e4eSSatish Balay } 246e5c89e4eSSatish Balay PetscFunctionReturn(0); 247e5c89e4eSSatish Balay } 248e5c89e4eSSatish Balay 249e5c89e4eSSatish Balay #undef __FUNCT__ 250e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDuplicate" 2511d0fab5eSBarry Smith /*@C 252e5c89e4eSSatish Balay PetscOListDuplicate - Creates a new list from a give object list. 253e5c89e4eSSatish Balay 254e5c89e4eSSatish Balay Input Parameters: 255e5c89e4eSSatish Balay . fl - pointer to list 256e5c89e4eSSatish Balay 257e5c89e4eSSatish Balay Output Parameters: 258e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 259e5c89e4eSSatish Balay 260b235ab32SBarry Smith Level: developer 261b235ab32SBarry Smith 2621d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListReverseFind(), PetscOListFind(), PetscOListDuplicate() 263e5c89e4eSSatish Balay 2641d0fab5eSBarry Smith @*/ 2657087cfbeSBarry Smith PetscErrorCode PetscOListDuplicate(PetscOList fl,PetscOList *nl) 266e5c89e4eSSatish Balay { 267e5c89e4eSSatish Balay PetscErrorCode ierr; 268e5c89e4eSSatish Balay 269e5c89e4eSSatish Balay PetscFunctionBegin; 270e5c89e4eSSatish Balay while (fl) { 271e5c89e4eSSatish Balay ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 272e5c89e4eSSatish Balay fl = fl->next; 273e5c89e4eSSatish Balay } 274e5c89e4eSSatish Balay PetscFunctionReturn(0); 275e5c89e4eSSatish Balay } 276e5c89e4eSSatish Balay 277e5c89e4eSSatish Balay 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay 280e5c89e4eSSatish Balay 281