xref: /petsc/src/sys/objects/olist.c (revision 0298fd7132830bec7daee99a80be0eddb2b310a5)
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