xref: /petsc/src/sys/objects/olist.c (revision 87130e5e82fb2b41934ca3b59eb675f6ee2458d6)
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 {
37*87130e5eSHong Zhang   PetscOList     nlist;
386ba4bc90SBarry Smith   PetscErrorCode ierr;
396ba4bc90SBarry Smith   PetscBool      match;
406ba4bc90SBarry Smith 
416ba4bc90SBarry Smith   PetscFunctionBegin;
42*87130e5eSHong Zhang   nlist = *fl;
436ba4bc90SBarry Smith   while (nlist) {
446ba4bc90SBarry Smith     ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr);
456ba4bc90SBarry Smith     if (match) {  /* found it in the list */
466ba4bc90SBarry Smith       ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr);
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 
556ba4bc90SBarry Smith #undef __FUNCT__
56e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListAdd"
571d0fab5eSBarry Smith /*@C
581d0fab5eSBarry Smith      PetscOListAdd - Adds a new object to an PetscOList
59e5c89e4eSSatish Balay 
601d0fab5eSBarry Smith     Input Parameters:
611d0fab5eSBarry Smith +     fl - the object list
621d0fab5eSBarry Smith .     name - the name to use for the object
631d0fab5eSBarry Smith -     obj - the object to attach
64e5c89e4eSSatish Balay 
65b235ab32SBarry Smith     Level: developer
66b235ab32SBarry Smith 
671d0fab5eSBarry Smith        Notes: Replaces item if it is already in list. Removes item if you pass in a PETSC_NULL object.
681d0fab5eSBarry Smith 
691d0fab5eSBarry Smith         Use PetscOListFind() or PetscOListReverseFind() to get the object back
701d0fab5eSBarry Smith 
711d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
721d0fab5eSBarry Smith 
731d0fab5eSBarry Smith @*/
747087cfbeSBarry Smith PetscErrorCode  PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
75e5c89e4eSSatish Balay {
76e5c89e4eSSatish Balay   PetscOList     olist,nlist,prev;
77e5c89e4eSSatish Balay   PetscErrorCode ierr;
78ace3abfcSBarry Smith   PetscBool      match;
79e5c89e4eSSatish Balay 
80e5c89e4eSSatish Balay   PetscFunctionBegin;
81e5c89e4eSSatish Balay 
82e5c89e4eSSatish Balay   if (!obj) { /* this means remove from list if it is there */
83e5c89e4eSSatish Balay     nlist = *fl; prev = 0;
84e5c89e4eSSatish Balay     while (nlist) {
85e5c89e4eSSatish Balay       ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr);
86e5c89e4eSSatish Balay       if (match) {  /* found it already in the list */
87e5c89e4eSSatish Balay         ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr);
88e5c89e4eSSatish Balay         if (prev) prev->next = nlist->next;
89e5c89e4eSSatish Balay         else if (nlist->next) {
90e5c89e4eSSatish Balay           *fl = nlist->next;
91e5c89e4eSSatish Balay         } else {
92e5c89e4eSSatish Balay           *fl = 0;
93e5c89e4eSSatish Balay         }
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);
1087dcf0eaaSdalcinl       ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr);
109e5c89e4eSSatish Balay       nlist->obj = obj;
110e5c89e4eSSatish Balay       PetscFunctionReturn(0);
111e5c89e4eSSatish Balay     }
112e5c89e4eSSatish Balay     nlist = nlist->next;
113e5c89e4eSSatish Balay   }
114e5c89e4eSSatish Balay 
115e5c89e4eSSatish Balay   /* add it to list, because it was not already there */
116e5c89e4eSSatish Balay 
1172bb46157SSatish Balay   ierr        = PetscNew(struct _n_PetscOList,&olist);CHKERRQ(ierr);
118e5c89e4eSSatish Balay   olist->next = 0;
119e5c89e4eSSatish Balay   olist->obj  = obj;
120e5c89e4eSSatish Balay   ierr = PetscObjectReference(obj);CHKERRQ(ierr);
121e5c89e4eSSatish Balay   ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr);
122e5c89e4eSSatish Balay 
123e5c89e4eSSatish Balay   if (!*fl) {
124e5c89e4eSSatish Balay     *fl = olist;
125e5c89e4eSSatish Balay   } else { /* go to end of list */
126e5c89e4eSSatish Balay     nlist = *fl;
127e5c89e4eSSatish Balay     while (nlist->next) {
128e5c89e4eSSatish Balay       nlist = nlist->next;
129e5c89e4eSSatish Balay     }
130e5c89e4eSSatish Balay     nlist->next = olist;
131e5c89e4eSSatish Balay   }
132e5c89e4eSSatish Balay   PetscFunctionReturn(0);
133e5c89e4eSSatish Balay }
134e5c89e4eSSatish Balay 
135e5c89e4eSSatish Balay #undef __FUNCT__
136e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDestroy"
1371d0fab5eSBarry Smith /*@C
138e5c89e4eSSatish Balay     PetscOListDestroy - Destroy a list of objects
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay     Input Parameter:
1416bf464f9SBarry Smith .   ifl   - pointer to list
1421d0fab5eSBarry Smith 
143b235ab32SBarry Smith     Level: developer
144b235ab32SBarry Smith 
1451d0fab5eSBarry Smith .seealso: PetscOListAdd(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
1461d0fab5eSBarry Smith 
1471d0fab5eSBarry Smith @*/
1486bf464f9SBarry Smith PetscErrorCode  PetscOListDestroy(PetscOList *ifl)
149e5c89e4eSSatish Balay {
1506bf464f9SBarry Smith   PetscOList     tmp,fl = *ifl;
151e5c89e4eSSatish Balay   PetscErrorCode ierr;
152e5c89e4eSSatish Balay 
153e5c89e4eSSatish Balay   PetscFunctionBegin;
1549c666560SBarry Smith   while (fl) {
1559c666560SBarry Smith     tmp   = fl->next;
1566ba4bc90SBarry Smith     if (!fl->skipdereference) {ierr  = PetscObjectDereference(fl->obj);CHKERRQ(ierr);}
1579c666560SBarry Smith     ierr  = PetscFree(fl);CHKERRQ(ierr);
1589c666560SBarry Smith     fl    = tmp;
159e5c89e4eSSatish Balay   }
1606bf464f9SBarry Smith   *ifl = PETSC_NULL;
161e5c89e4eSSatish Balay   PetscFunctionReturn(0);
162e5c89e4eSSatish Balay }
163e5c89e4eSSatish Balay 
164e5c89e4eSSatish Balay 
165e5c89e4eSSatish Balay #undef __FUNCT__
166e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListFind"
1671d0fab5eSBarry Smith /*@C
168e5c89e4eSSatish Balay     PetscOListFind - givn a name, find the matching object
169e5c89e4eSSatish Balay 
170e5c89e4eSSatish Balay     Input Parameters:
171e5c89e4eSSatish Balay +   fl   - pointer to list
172e5c89e4eSSatish Balay -   name - name string
173e5c89e4eSSatish Balay 
174e5c89e4eSSatish Balay     Output Parameters:
175e5c89e4eSSatish Balay .   ob - the PETSc object
176e5c89e4eSSatish Balay 
177b235ab32SBarry Smith     Level: developer
178b235ab32SBarry Smith 
179e5c89e4eSSatish Balay     Notes:
1803c0c59f3SBarry Smith     The name must have been registered with the PetscOListAdd() before calling this routine.
1813c0c59f3SBarry Smith 
1823c0c59f3SBarry Smith     The reference count of the object is not increased
183e5c89e4eSSatish Balay 
1841d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
185e5c89e4eSSatish Balay 
1861d0fab5eSBarry Smith @*/
1877087cfbeSBarry Smith PetscErrorCode  PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
188e5c89e4eSSatish Balay {
189e5c89e4eSSatish Balay   PetscErrorCode ierr;
190ace3abfcSBarry Smith   PetscBool      match;
191e5c89e4eSSatish Balay 
192e5c89e4eSSatish Balay   PetscFunctionBegin;
193e5c89e4eSSatish Balay   *obj = 0;
194e5c89e4eSSatish Balay   while (fl) {
195e5c89e4eSSatish Balay     ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr);
196e5c89e4eSSatish Balay     if (match) {
197e5c89e4eSSatish Balay       *obj = fl->obj;
198e5c89e4eSSatish Balay       break;
199e5c89e4eSSatish Balay     }
200e5c89e4eSSatish Balay     fl = fl->next;
201e5c89e4eSSatish Balay   }
202e5c89e4eSSatish Balay   PetscFunctionReturn(0);
203e5c89e4eSSatish Balay }
204e5c89e4eSSatish Balay 
205e5c89e4eSSatish Balay #undef __FUNCT__
206e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListReverseFind"
2071d0fab5eSBarry Smith /*@C
208e5c89e4eSSatish Balay     PetscOListReverseFind - given a object, find the matching name if it exists
209e5c89e4eSSatish Balay 
210e5c89e4eSSatish Balay     Input Parameters:
211e5c89e4eSSatish Balay +   fl   - pointer to list
212e5c89e4eSSatish Balay -   ob - the PETSc object
213e5c89e4eSSatish Balay 
214e5c89e4eSSatish Balay     Output Parameters:
215e5c89e4eSSatish Balay .   name - name string
216e5c89e4eSSatish Balay 
217b235ab32SBarry Smith     Level: developer
218b235ab32SBarry Smith 
219e5c89e4eSSatish Balay     Notes:
2203c0c59f3SBarry Smith     The name must have been registered with the PetscOListAdd() before calling this routine.
2213c0c59f3SBarry Smith 
2223c0c59f3SBarry Smith     The reference count of the object is not increased
223e5c89e4eSSatish Balay 
2241d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListFind(), PetscOListDuplicate()
225e5c89e4eSSatish Balay 
2261d0fab5eSBarry Smith @*/
2277087cfbeSBarry Smith PetscErrorCode  PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
228e5c89e4eSSatish Balay {
229e5c89e4eSSatish Balay   PetscFunctionBegin;
230e5c89e4eSSatish Balay   *name = 0;
231e5c89e4eSSatish Balay   while (fl) {
232e5c89e4eSSatish Balay     if (fl->obj == obj) {
233e5c89e4eSSatish Balay       *name = fl->name;
234e5c89e4eSSatish Balay       break;
235e5c89e4eSSatish Balay     }
236e5c89e4eSSatish Balay     fl = fl->next;
237e5c89e4eSSatish Balay   }
238e5c89e4eSSatish Balay   PetscFunctionReturn(0);
239e5c89e4eSSatish Balay }
240e5c89e4eSSatish Balay 
241e5c89e4eSSatish Balay #undef __FUNCT__
242e5c89e4eSSatish Balay #define __FUNCT__ "PetscOListDuplicate"
2431d0fab5eSBarry Smith /*@C
244e5c89e4eSSatish Balay     PetscOListDuplicate - Creates a new list from a give object list.
245e5c89e4eSSatish Balay 
246e5c89e4eSSatish Balay     Input Parameters:
247e5c89e4eSSatish Balay .   fl   - pointer to list
248e5c89e4eSSatish Balay 
249e5c89e4eSSatish Balay     Output Parameters:
250e5c89e4eSSatish Balay .   nl - the new list (should point to 0 to start, otherwise appends)
251e5c89e4eSSatish Balay 
252b235ab32SBarry Smith     Level: developer
253b235ab32SBarry Smith 
2541d0fab5eSBarry Smith .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListReverseFind(), PetscOListFind(), PetscOListDuplicate()
255e5c89e4eSSatish Balay 
2561d0fab5eSBarry Smith @*/
2577087cfbeSBarry Smith PetscErrorCode  PetscOListDuplicate(PetscOList fl,PetscOList *nl)
258e5c89e4eSSatish Balay {
259e5c89e4eSSatish Balay   PetscErrorCode ierr;
260e5c89e4eSSatish Balay 
261e5c89e4eSSatish Balay   PetscFunctionBegin;
262e5c89e4eSSatish Balay   while (fl) {
263e5c89e4eSSatish Balay     ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr);
264e5c89e4eSSatish Balay     fl = fl->next;
265e5c89e4eSSatish Balay   }
266e5c89e4eSSatish Balay   PetscFunctionReturn(0);
267e5c89e4eSSatish Balay }
268e5c89e4eSSatish Balay 
269e5c89e4eSSatish Balay 
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay 
272e5c89e4eSSatish Balay 
273