Fix oversight in previous error-reporting patch; mustn't pfree path string
[PostgreSQL.git] / src / backend / lib / dllist.c
blobb771fce38db9ac5f2b82e3a02b4df3cd17fdf00f
1 /*-------------------------------------------------------------------------
3 * dllist.c
4 * this is a simple doubly linked list implementation
5 * the elements of the lists are void*
7 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * IDENTIFICATION
12 * $PostgreSQL$
14 *-------------------------------------------------------------------------
16 #include "postgres.h"
18 #include "lib/dllist.h"
21 Dllist *
22 DLNewList(void)
24 Dllist *l;
26 l = (Dllist *) palloc(sizeof(Dllist));
28 l->dll_head = NULL;
29 l->dll_tail = NULL;
31 return l;
34 void
35 DLInitList(Dllist *list)
37 list->dll_head = NULL;
38 list->dll_tail = NULL;
42 * free up a list and all the nodes in it --- but *not* whatever the nodes
43 * might point to!
45 void
46 DLFreeList(Dllist *list)
48 Dlelem *curr;
50 while ((curr = DLRemHead(list)) != NULL)
51 pfree(curr);
53 pfree(list);
56 Dlelem *
57 DLNewElem(void *val)
59 Dlelem *e;
61 e = (Dlelem *) palloc(sizeof(Dlelem));
63 e->dle_next = NULL;
64 e->dle_prev = NULL;
65 e->dle_val = val;
66 e->dle_list = NULL;
67 return e;
70 void
71 DLInitElem(Dlelem *e, void *val)
73 e->dle_next = NULL;
74 e->dle_prev = NULL;
75 e->dle_val = val;
76 e->dle_list = NULL;
79 void
80 DLFreeElem(Dlelem *e)
82 pfree(e);
85 void
86 DLRemove(Dlelem *e)
88 Dllist *l = e->dle_list;
90 if (e->dle_prev)
91 e->dle_prev->dle_next = e->dle_next;
92 else
94 /* must be the head element */
95 Assert(e == l->dll_head);
96 l->dll_head = e->dle_next;
98 if (e->dle_next)
99 e->dle_next->dle_prev = e->dle_prev;
100 else
102 /* must be the tail element */
103 Assert(e == l->dll_tail);
104 l->dll_tail = e->dle_prev;
107 e->dle_next = NULL;
108 e->dle_prev = NULL;
109 e->dle_list = NULL;
112 void
113 DLAddHead(Dllist *l, Dlelem *e)
115 e->dle_list = l;
117 if (l->dll_head)
118 l->dll_head->dle_prev = e;
119 e->dle_next = l->dll_head;
120 e->dle_prev = NULL;
121 l->dll_head = e;
123 if (l->dll_tail == NULL) /* if this is first element added */
124 l->dll_tail = e;
127 void
128 DLAddTail(Dllist *l, Dlelem *e)
130 e->dle_list = l;
132 if (l->dll_tail)
133 l->dll_tail->dle_next = e;
134 e->dle_prev = l->dll_tail;
135 e->dle_next = NULL;
136 l->dll_tail = e;
138 if (l->dll_head == NULL) /* if this is first element added */
139 l->dll_head = e;
142 Dlelem *
143 DLRemHead(Dllist *l)
145 /* remove and return the head */
146 Dlelem *result = l->dll_head;
148 if (result == NULL)
149 return result;
151 if (result->dle_next)
152 result->dle_next->dle_prev = NULL;
154 l->dll_head = result->dle_next;
156 if (result == l->dll_tail) /* if the head is also the tail */
157 l->dll_tail = NULL;
159 result->dle_next = NULL;
160 result->dle_list = NULL;
162 return result;
165 Dlelem *
166 DLRemTail(Dllist *l)
168 /* remove and return the tail */
169 Dlelem *result = l->dll_tail;
171 if (result == NULL)
172 return result;
174 if (result->dle_prev)
175 result->dle_prev->dle_next = NULL;
177 l->dll_tail = result->dle_prev;
179 if (result == l->dll_head) /* if the tail is also the head */
180 l->dll_head = NULL;
182 result->dle_prev = NULL;
183 result->dle_list = NULL;
185 return result;
188 /* Same as DLRemove followed by DLAddHead, but faster */
189 void
190 DLMoveToFront(Dlelem *e)
192 Dllist *l = e->dle_list;
194 if (l->dll_head == e)
195 return; /* Fast path if already at front */
197 Assert(e->dle_prev != NULL); /* since it's not the head */
198 e->dle_prev->dle_next = e->dle_next;
200 if (e->dle_next)
201 e->dle_next->dle_prev = e->dle_prev;
202 else
204 /* must be the tail element */
205 Assert(e == l->dll_tail);
206 l->dll_tail = e->dle_prev;
209 l->dll_head->dle_prev = e;
210 e->dle_next = l->dll_head;
211 e->dle_prev = NULL;
212 l->dll_head = e;
213 /* We need not check dll_tail, since there must have been > 1 entry */