xref: /petsc/src/sys/objects/olist.c (revision 140e18c1ab5d6e82cb97419c1b69bc894c9508d2)
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 
8*140e18c1SBarry Smith struct _n_PetscObjectList {
9e5c89e4eSSatish Balay     char             name[256];
10*140e18c1SBarry Smith     PetscBool        skipdereference;   /* when the PetscObjectList is destroyed do not call PetscObjectDereference() on this object */
11e5c89e4eSSatish Balay     PetscObject      obj;
12*140e18c1SBarry Smith     PetscObjectList  next;
13e5c89e4eSSatish Balay };
14e5c89e4eSSatish Balay 
15e5c89e4eSSatish Balay #undef __FUNCT__
16*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListRemoveReference"
176ba4bc90SBarry Smith /*@C
18*140e18c1SBarry 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*140e18c1SBarry Smith        Notes: Use PetscObjectListAdd(PetscObjectList,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 
32*140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate(), PetscObjectListAdd()
336ba4bc90SBarry Smith 
346ba4bc90SBarry Smith @*/
35*140e18c1SBarry Smith PetscErrorCode  PetscObjectListRemoveReference(PetscObjectList *fl,const char name[])
366ba4bc90SBarry Smith {
37*140e18c1SBarry 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__
58*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListAdd"
591d0fab5eSBarry Smith /*@C
60*140e18c1SBarry 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 
691d0fab5eSBarry Smith        Notes: Replaces item if it is already in list. Removes item if you pass in a PETSC_NULL object.
701d0fab5eSBarry Smith 
71*140e18c1SBarry Smith         Use PetscObjectListFind() or PetscObjectListReverseFind() to get the object back
721d0fab5eSBarry Smith 
73*140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate()
741d0fab5eSBarry Smith 
751d0fab5eSBarry Smith @*/
76*140e18c1SBarry Smith PetscErrorCode  PetscObjectListAdd(PetscObjectList *fl,const char name[],PetscObject obj)
77e5c89e4eSSatish Balay {
78*140e18c1SBarry Smith   PetscObjectList 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 */
8900ac8be1SBarry Smith         if (!nlist->skipdereference) {
90e5c89e4eSSatish Balay           ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr);
9100ac8be1SBarry 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);
11200ac8be1SBarry Smith       if (!nlist->skipdereference) {
1137dcf0eaaSdalcinl         ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr);
11400ac8be1SBarry Smith       }
11500ac8be1SBarry 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 */
123*140e18c1SBarry Smith   ierr        = PetscNew(struct _n_PetscObjectList,&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__
142*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListDestroy"
1431d0fab5eSBarry Smith /*@C
144*140e18c1SBarry Smith     PetscObjectListDestroy - 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 
151*140e18c1SBarry Smith .seealso: PetscObjectListAdd(), PetscObjectListFind(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate()
1521d0fab5eSBarry Smith 
1531d0fab5eSBarry Smith @*/
154*140e18c1SBarry Smith PetscErrorCode  PetscObjectListDestroy(PetscObjectList *ifl)
155e5c89e4eSSatish Balay {
156*140e18c1SBarry Smith   PetscObjectList tmp,fl = *ifl;
157e5c89e4eSSatish Balay   PetscErrorCode  ierr;
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay   PetscFunctionBegin;
1609c666560SBarry Smith   while (fl) {
1619c666560SBarry Smith     tmp   = fl->next;
16200ac8be1SBarry Smith     if (!fl->skipdereference) {
16300ac8be1SBarry Smith       ierr  = PetscObjectDereference(fl->obj);CHKERRQ(ierr);
16400ac8be1SBarry 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__
174*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListFind"
1751d0fab5eSBarry Smith /*@C
176*140e18c1SBarry Smith     PetscObjectListFind - 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:
188*140e18c1SBarry Smith     The name must have been registered with the PetscObjectListAdd() before calling this routine.
1893c0c59f3SBarry Smith 
1903c0c59f3SBarry Smith     The reference count of the object is not increased
191e5c89e4eSSatish Balay 
192*140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListReverseFind(), PetscObjectListDuplicate()
193e5c89e4eSSatish Balay 
1941d0fab5eSBarry Smith @*/
195*140e18c1SBarry Smith PetscErrorCode  PetscObjectListFind(PetscObjectList 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__
214*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListReverseFind"
2151d0fab5eSBarry Smith /*@C
216*140e18c1SBarry Smith     PetscObjectListReverseFind - 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:
223bfec8eecSBarry Smith +  name - name string
224bfec8eecSBarry Smith -  skipdereference - if the object is list but does not have the increased reference count for a circular dependency
225e5c89e4eSSatish Balay 
226b235ab32SBarry Smith     Level: developer
227b235ab32SBarry Smith 
228e5c89e4eSSatish Balay     Notes:
229*140e18c1SBarry Smith     The name must have been registered with the PetscObjectListAdd() before calling this routine.
2303c0c59f3SBarry Smith 
2313c0c59f3SBarry Smith     The reference count of the object is not increased
232e5c89e4eSSatish Balay 
233*140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListDuplicate(), PetscObjectListFind(), PetscObjectListDuplicate()
234e5c89e4eSSatish Balay 
2351d0fab5eSBarry Smith @*/
236*140e18c1SBarry Smith PetscErrorCode  PetscObjectListReverseFind(PetscObjectList fl,PetscObject obj,char **name,PetscBool *skipdereference)
237e5c89e4eSSatish Balay {
238e5c89e4eSSatish Balay   PetscFunctionBegin;
239e5c89e4eSSatish Balay   *name = 0;
240e5c89e4eSSatish Balay   while (fl) {
241e5c89e4eSSatish Balay     if (fl->obj == obj) {
242e5c89e4eSSatish Balay       *name = fl->name;
243bfec8eecSBarry Smith       if (skipdereference) *skipdereference = fl->skipdereference;
244e5c89e4eSSatish Balay       break;
245e5c89e4eSSatish Balay     }
246e5c89e4eSSatish Balay     fl = fl->next;
247e5c89e4eSSatish Balay   }
248e5c89e4eSSatish Balay   PetscFunctionReturn(0);
249e5c89e4eSSatish Balay }
250e5c89e4eSSatish Balay 
251e5c89e4eSSatish Balay #undef __FUNCT__
252*140e18c1SBarry Smith #define __FUNCT__ "PetscObjectListDuplicate"
2531d0fab5eSBarry Smith /*@C
254*140e18c1SBarry Smith     PetscObjectListDuplicate - Creates a new list from a give object list.
255e5c89e4eSSatish Balay 
256e5c89e4eSSatish Balay     Input Parameters:
257e5c89e4eSSatish Balay .   fl   - pointer to list
258e5c89e4eSSatish Balay 
259e5c89e4eSSatish Balay     Output Parameters:
260e5c89e4eSSatish Balay .   nl - the new list (should point to 0 to start, otherwise appends)
261e5c89e4eSSatish Balay 
262b235ab32SBarry Smith     Level: developer
263b235ab32SBarry Smith 
264*140e18c1SBarry Smith .seealso: PetscObjectListDestroy(), PetscObjectListAdd(), PetscObjectListReverseFind(), PetscObjectListFind(), PetscObjectListDuplicate()
265e5c89e4eSSatish Balay 
2661d0fab5eSBarry Smith @*/
267*140e18c1SBarry Smith PetscErrorCode  PetscObjectListDuplicate(PetscObjectList fl,PetscObjectList *nl)
268e5c89e4eSSatish Balay {
269e5c89e4eSSatish Balay   PetscErrorCode ierr;
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay   PetscFunctionBegin;
272e5c89e4eSSatish Balay   while (fl) {
273*140e18c1SBarry Smith     ierr = PetscObjectListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr);
274e5c89e4eSSatish Balay     fl = fl->next;
275e5c89e4eSSatish Balay   }
276e5c89e4eSSatish Balay   PetscFunctionReturn(0);
277e5c89e4eSSatish Balay }
278e5c89e4eSSatish Balay 
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay 
281e5c89e4eSSatish Balay 
282e5c89e4eSSatish Balay 
283