Actual source code: olist.c
petsc-3.3-p7 2013-05-11
2: /*
3: Provides a general mechanism to maintain a linked list of PETSc objects.
4: This is used to allow PETSc objects to carry a list of "composed" objects
5: */
6: #include <petscsys.h>
8: struct _n_PetscOList {
9: char name[256];
10: PetscBool skipdereference; /* when the OList is destroyed do not call PetscObjectDereference() on this object */
11: PetscObject obj;
12: PetscOList next;
13: };
17: /*@C
18: PetscOListRemoveReference - Calls PetscObjectDereference() on an object in the list immediately but keeps a pointer to the object in the list.
20: Input Parameters:
21: + fl - the object list
22: - name - the name to use for the object
24: Level: developer
26: Notes: Use PetscOListAdd(PetscOList,const char name[],PETSC_NULL) to truly remove the object from the list
27:
28: Use this routine ONLY if you know that the object referenced will remain in existence until the pointing object is destroyed
30: Developer Note: this is to handle some cases that otherwise would result in having circular references so reference counts never got to zero
32: .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate(), PetscOListAdd()
34: @*/
35: PetscErrorCode PetscOListRemoveReference(PetscOList *fl,const char name[])
36: {
37: PetscOList nlist;
39: PetscBool match;
42: nlist = *fl;
43: while (nlist) {
44: PetscStrcmp(name,nlist->name,&match);
45: if (match) { /* found it in the list */
46: if (!nlist->skipdereference) {
47: PetscObjectDereference(nlist->obj);
48: }
49: nlist->skipdereference = PETSC_TRUE;
50: return(0);
51: }
52: nlist = nlist->next;
53: }
54: return(0);
55: }
59: /*@C
60: PetscOListAdd - Adds a new object to an PetscOList
62: Input Parameters:
63: + fl - the object list
64: . name - the name to use for the object
65: - obj - the object to attach
67: Level: developer
69: Notes: Replaces item if it is already in list. Removes item if you pass in a PETSC_NULL object.
70:
71: Use PetscOListFind() or PetscOListReverseFind() to get the object back
73: .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
75: @*/
76: PetscErrorCode PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
77: {
78: PetscOList olist,nlist,prev;
80: PetscBool match;
84: if (!obj) { /* this means remove from list if it is there */
85: nlist = *fl; prev = 0;
86: while (nlist) {
87: PetscStrcmp(name,nlist->name,&match);
88: if (match) { /* found it already in the list */
89: if (!nlist->skipdereference) {
90: PetscObjectDereference(nlist->obj);
91: }
92: if (prev) prev->next = nlist->next;
93: else if (nlist->next) {
94: *fl = nlist->next;
95: } else {
96: *fl = 0;
97: }
98: PetscFree(nlist);
99: return(0);
100: }
101: prev = nlist;
102: nlist = nlist->next;
103: }
104: return(0); /* did not find it to remove */
105: }
106: /* look for it already in list */
107: nlist = *fl;
108: while (nlist) {
109: PetscStrcmp(name,nlist->name,&match);
110: if (match) { /* found it in the list */
111: PetscObjectReference(obj);
112: if (!nlist->skipdereference) {
113: PetscObjectDereference(nlist->obj);
114: }
115: nlist->skipdereference = PETSC_FALSE;
116: nlist->obj = obj;
117: return(0);
118: }
119: nlist = nlist->next;
120: }
122: /* add it to list, because it was not already there */
123: PetscNew(struct _n_PetscOList,&olist);
124: olist->next = 0;
125: olist->obj = obj;
126: PetscObjectReference(obj);
127: PetscStrcpy(olist->name,name);
129: if (!*fl) {
130: *fl = olist;
131: } else { /* go to end of list */
132: nlist = *fl;
133: while (nlist->next) {
134: nlist = nlist->next;
135: }
136: nlist->next = olist;
137: }
138: return(0);
139: }
143: /*@C
144: PetscOListDestroy - Destroy a list of objects
146: Input Parameter:
147: . ifl - pointer to list
149: Level: developer
151: .seealso: PetscOListAdd(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
153: @*/
154: PetscErrorCode PetscOListDestroy(PetscOList *ifl)
155: {
156: PetscOList tmp,fl = *ifl;
160: while (fl) {
161: tmp = fl->next;
162: if (!fl->skipdereference) {
163: PetscObjectDereference(fl->obj);
164: }
165: PetscFree(fl);
166: fl = tmp;
167: }
168: *ifl = PETSC_NULL;
169: return(0);
170: }
175: /*@C
176: PetscOListFind - givn a name, find the matching object
178: Input Parameters:
179: + fl - pointer to list
180: - name - name string
182: Output Parameters:
183: . ob - the PETSc object
185: Level: developer
187: Notes:
188: The name must have been registered with the PetscOListAdd() before calling this routine.
190: The reference count of the object is not increased
192: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()
194: @*/
195: PetscErrorCode PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
196: {
198: PetscBool match;
201: *obj = 0;
202: while (fl) {
203: PetscStrcmp(name,fl->name,&match);
204: if (match) {
205: *obj = fl->obj;
206: break;
207: }
208: fl = fl->next;
209: }
210: return(0);
211: }
215: /*@C
216: PetscOListReverseFind - given a object, find the matching name if it exists
218: Input Parameters:
219: + fl - pointer to list
220: - ob - the PETSc object
222: Output Parameters:
223: + name - name string
224: - skipdereference - if the object is list but does not have the increased reference count for a circular dependency
226: Level: developer
228: Notes:
229: The name must have been registered with the PetscOListAdd() before calling this routine.
231: The reference count of the object is not increased
233: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListFind(), PetscOListDuplicate()
235: @*/
236: PetscErrorCode PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name,PetscBool *skipdereference)
237: {
239: *name = 0;
240: while (fl) {
241: if (fl->obj == obj) {
242: *name = fl->name;
243: if (skipdereference) *skipdereference = fl->skipdereference;
244: break;
245: }
246: fl = fl->next;
247: }
248: return(0);
249: }
253: /*@C
254: PetscOListDuplicate - Creates a new list from a give object list.
256: Input Parameters:
257: . fl - pointer to list
259: Output Parameters:
260: . nl - the new list (should point to 0 to start, otherwise appends)
262: Level: developer
264: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListReverseFind(), PetscOListFind(), PetscOListDuplicate()
266: @*/
267: PetscErrorCode PetscOListDuplicate(PetscOList fl,PetscOList *nl)
268: {
272: while (fl) {
273: PetscOListAdd(nl,fl->name,fl->obj);
274: fl = fl->next;
275: }
276: return(0);
277: }