1 /*-------------------------------------------------------------------------
4 * this is a simple doubly linked list implementation
5 * the elements of the lists are void*
7 * Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
12 * $PostgreSQL: pgsql/src/backend/lib/dllist.c,v 1.29 2004/08/29 04:12:32 momjian Exp $
14 *-------------------------------------------------------------------------
17 /* can be used in frontend or backend */
19 #include "postgres_fe.h"
20 /* No assert checks in frontend ... */
21 #define Assert(condition)
26 #include "lib/dllist.h"
34 l = (Dllist *) malloc(sizeof(Dllist));
38 fprintf(stderr, "memory exhausted in DLNewList\n");
42 (errcode(ERRCODE_OUT_OF_MEMORY),
43 errmsg("out of memory")));
53 DLInitList(Dllist *list)
60 * free up a list and all the nodes in it --- but *not* whatever the nodes
64 DLFreeList(Dllist *list)
68 while ((curr = DLRemHead(list)) != 0)
79 e = (Dlelem *) malloc(sizeof(Dlelem));
83 fprintf(stderr, "memory exhausted in DLNewElem\n");
87 (errcode(ERRCODE_OUT_OF_MEMORY),
88 errmsg("out of memory")));
99 DLInitElem(Dlelem *e, void *val)
108 DLFreeElem(Dlelem *e)
116 Dllist *l = e->dle_list;
119 e->dle_prev->dle_next = e->dle_next;
122 /* must be the head element */
123 Assert(e == l->dll_head);
124 l->dll_head = e->dle_next;
127 e->dle_next->dle_prev = e->dle_prev;
130 /* must be the tail element */
131 Assert(e == l->dll_tail);
132 l->dll_tail = e->dle_prev;
141 DLAddHead(Dllist *l, Dlelem *e)
146 l->dll_head->dle_prev = e;
147 e->dle_next = l->dll_head;
151 if (l->dll_tail == 0) /* if this is first element added */
156 DLAddTail(Dllist *l, Dlelem *e)
161 l->dll_tail->dle_next = e;
162 e->dle_prev = l->dll_tail;
166 if (l->dll_head == 0) /* if this is first element added */
173 /* remove and return the head */
174 Dlelem *result = l->dll_head;
179 if (result->dle_next)
180 result->dle_next->dle_prev = 0;
182 l->dll_head = result->dle_next;
184 if (result == l->dll_tail) /* if the head is also the tail */
187 result->dle_next = 0;
188 result->dle_list = 0;
196 /* remove and return the tail */
197 Dlelem *result = l->dll_tail;
202 if (result->dle_prev)
203 result->dle_prev->dle_next = 0;
205 l->dll_tail = result->dle_prev;
207 if (result == l->dll_head) /* if the tail is also the head */
210 result->dle_prev = 0;
211 result->dle_list = 0;
216 /* Same as DLRemove followed by DLAddHead, but faster */
218 DLMoveToFront(Dlelem *e)
220 Dllist *l = e->dle_list;
222 if (l->dll_head == e)
223 return; /* Fast path if already at front */
225 Assert(e->dle_prev != 0); /* since it's not the head */
226 e->dle_prev->dle_next = e->dle_next;
229 e->dle_next->dle_prev = e->dle_prev;
232 /* must be the tail element */
233 Assert(e == l->dll_tail);
234 l->dll_tail = e->dle_prev;
237 l->dll_head->dle_prev = e;
238 e->dle_next = l->dll_head;
241 /* We need not check dll_tail, since there must have been > 1 entry */