]> granicus.if.org Git - postgresql/blobdiff - src/backend/lib/dllist.c
Fix some latent bugs in dllist.c (carelessness about setting
[postgresql] / src / backend / lib / dllist.c
index 9aeb82f266c42bfdffae6e5bff6c17e2b95fc301..3ca7cf03c74ac245173c0ccbaa52ea570c6d45f9 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.12 1999/02/13 23:15:34 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.13 1999/05/31 23:48:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,7 +30,9 @@ DLNewList(void)
        return l;
 }
 
- /* free up a list and all the nodes in it */
+/* free up a list and all the nodes in it --- but *not* whatever the nodes
+ * might point to!
+ */
 void
 DLFreeList(Dllist *l)
 {
@@ -85,7 +87,7 @@ DLGetTail(Dllist *l)
        return l ? l->dll_tail : 0;
 }
 
-/* get the value stored in the first element */
+/* get the value stored in the last element */
 #ifdef NOT_USED
 void *
 DLGetTailVal(Dllist *l)
@@ -112,20 +114,26 @@ DLGetSucc(Dlelem *e)                      /* get successor */
 void
 DLRemove(Dlelem *e)
 {
-       Dllist     *l;
+       Dllist     *l = e->dle_list;
 
        if (e->dle_prev)
                e->dle_prev->dle_next = e->dle_next;
+       else                                            /* must be the head element */
+       {
+               Assert(e == l->dll_head);
+               l->dll_head = e->dle_next;
+       }
        if (e->dle_next)
                e->dle_next->dle_prev = e->dle_prev;
+       else                                            /* must be the tail element */
+       {
+               Assert(e == l->dll_tail);
+               l->dll_tail = e->dle_prev;
+       }
 
-       /* check to see if we're removing the head or tail */
-       l = e->dle_list;
-       if (e == l->dll_head)
-               DLRemHead(l);
-       if (e == l->dll_tail)
-               DLRemTail(l);
-
+       e->dle_next = 0;
+       e->dle_prev = 0;
+       e->dle_list = 0;
 }
 
 void
@@ -134,15 +142,13 @@ DLAddHead(Dllist *l, Dlelem *e)
        e->dle_list = l;
 
        if (l->dll_head)
-       {
                l->dll_head->dle_prev = e;
-               e->dle_next = l->dll_head;
-       }
+       e->dle_next = l->dll_head;
        e->dle_prev = 0;
        l->dll_head = e;
 
        if (l->dll_tail == 0)           /* if this is first element added */
-               l->dll_tail = l->dll_head;
+               l->dll_tail = e;
 }
 
 void
@@ -151,31 +157,28 @@ DLAddTail(Dllist *l, Dlelem *e)
        e->dle_list = l;
 
        if (l->dll_tail)
-       {
                l->dll_tail->dle_next = e;
-               e->dle_prev = l->dll_tail;
-       }
+       e->dle_prev = l->dll_tail;
        e->dle_next = 0;
        l->dll_tail = e;
 
        if (l->dll_head == 0)           /* if this is first element added */
-               l->dll_head = l->dll_tail;
+               l->dll_head = e;
 }
 
 Dlelem *
 DLRemHead(Dllist *l)
 {
        /* remove and return the head */
-       Dlelem     *result;
+       Dlelem     *result = l->dll_head;
 
-       if (l->dll_head == 0)
-               return 0;
+       if (result == 0)
+               return result;
 
-       result = l->dll_head;
-       if (l->dll_head->dle_next)
-               l->dll_head->dle_next->dle_prev = 0;
+       if (result->dle_next)
+               result->dle_next->dle_prev = 0;
 
-       l->dll_head = l->dll_head->dle_next;
+       l->dll_head = result->dle_next;
 
        result->dle_next = 0;
        result->dle_list = 0;
@@ -190,15 +193,15 @@ Dlelem *
 DLRemTail(Dllist *l)
 {
        /* remove and return the tail */
-       Dlelem     *result;
+       Dlelem     *result = l->dll_tail;
 
-       if (l->dll_tail == 0)
-               return 0;
+       if (result == 0)
+               return result;
 
-       result = l->dll_tail;
-       if (l->dll_tail->dle_prev)
-               l->dll_tail->dle_prev->dle_next = 0;
-       l->dll_tail = l->dll_tail->dle_prev;
+       if (result->dle_prev)
+               result->dle_prev->dle_next = 0;
+
+       l->dll_tail = result->dle_prev;
 
        result->dle_prev = 0;
        result->dle_list = 0;
@@ -208,3 +211,30 @@ DLRemTail(Dllist *l)
 
        return result;
 }
+
+/* Same as DLRemove followed by DLAddHead, but faster */
+void
+DLMoveToFront(Dlelem *e)
+{
+       Dllist     *l = e->dle_list;
+
+       if (l->dll_head == e)
+               return;                                 /* Fast path if already at front */
+
+       Assert(e->dle_prev != 0);       /* since it's not the head */
+       e->dle_prev->dle_next = e->dle_next;
+
+       if (e->dle_next)
+               e->dle_next->dle_prev = e->dle_prev;
+       else                                            /* must be the tail element */
+       {
+               Assert(e == l->dll_tail);
+               l->dll_tail = e->dle_prev;
+       }
+
+       l->dll_head->dle_prev = e;
+       e->dle_next = l->dll_head;
+       e->dle_prev = 0;
+       l->dll_head = e;
+       /* We need not check dll_tail, since there must have been > 1 entry */
+}