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