dllist.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:4k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * dllist.c
  4.  *   this is a simple doubly linked list implementation
  5.  *   replaces the old simplelists stuff
  6.  *   the elements of the lists are void*
  7.  *
  8.  * Copyright (c) 1994, Regents of the University of California
  9.  *
  10.  *
  11.  * IDENTIFICATION
  12.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/lib/dllist.c,v 1.14 1999/06/03 01:28:24 tgl Exp $
  13.  *
  14.  *-------------------------------------------------------------------------
  15.  */
  16. #include <postgres.h>
  17. #include <lib/dllist.h>
  18. /* When this file is compiled for inclusion in libpq,
  19.  * it can't use assert checking.  Probably this fix ought to be
  20.  * in c.h or somewhere like that...
  21.  */
  22. #ifdef FRONTEND
  23. #undef Assert
  24. #define Assert(condition)
  25. #endif
  26. Dllist *
  27. DLNewList(void)
  28. {
  29. Dllist    *l;
  30. l = malloc(sizeof(Dllist));
  31. l->dll_head = 0;
  32. l->dll_tail = 0;
  33. return l;
  34. }
  35. /* free up a list and all the nodes in it --- but *not* whatever the nodes
  36.  * might point to!
  37.  */
  38. void
  39. DLFreeList(Dllist *l)
  40. {
  41. Dlelem    *curr;
  42. while ((curr = DLRemHead(l)) != 0)
  43. free(curr);
  44. free(l);
  45. }
  46. Dlelem *
  47. DLNewElem(void *val)
  48. {
  49. Dlelem    *e;
  50. e = malloc(sizeof(Dlelem));
  51. e->dle_next = 0;
  52. e->dle_prev = 0;
  53. e->dle_val = val;
  54. e->dle_list = 0;
  55. return e;
  56. }
  57. void
  58. DLFreeElem(Dlelem *e)
  59. {
  60. free(e);
  61. }
  62. Dlelem *
  63. DLGetHead(Dllist *l)
  64. {
  65. return l ? l->dll_head : 0;
  66. }
  67. /* get the value stored in the first element */
  68. #ifdef NOT_USED
  69. void *
  70. DLGetHeadVal(Dllist *l)
  71. {
  72. Dlelem    *e = DLGetHead(l);
  73. return e ? e->dle_val : 0;
  74. }
  75. #endif
  76. Dlelem *
  77. DLGetTail(Dllist *l)
  78. {
  79. return l ? l->dll_tail : 0;
  80. }
  81. /* get the value stored in the last element */
  82. #ifdef NOT_USED
  83. void *
  84. DLGetTailVal(Dllist *l)
  85. {
  86. Dlelem    *e = DLGetTail(l);
  87. return e ? e->dle_val : 0;
  88. }
  89. #endif
  90. Dlelem *
  91. DLGetPred(Dlelem *e) /* get predecessor */
  92. {
  93. return e ? e->dle_prev : 0;
  94. }
  95. Dlelem *
  96. DLGetSucc(Dlelem *e) /* get successor */
  97. {
  98. return e ? e->dle_next : 0;
  99. }
  100. void
  101. DLRemove(Dlelem *e)
  102. {
  103. Dllist    *l = e->dle_list;
  104. if (e->dle_prev)
  105. e->dle_prev->dle_next = e->dle_next;
  106. else /* must be the head element */
  107. {
  108. Assert(e == l->dll_head);
  109. l->dll_head = e->dle_next;
  110. }
  111. if (e->dle_next)
  112. e->dle_next->dle_prev = e->dle_prev;
  113. else /* must be the tail element */
  114. {
  115. Assert(e == l->dll_tail);
  116. l->dll_tail = e->dle_prev;
  117. }
  118. e->dle_next = 0;
  119. e->dle_prev = 0;
  120. e->dle_list = 0;
  121. }
  122. void
  123. DLAddHead(Dllist *l, Dlelem *e)
  124. {
  125. e->dle_list = l;
  126. if (l->dll_head)
  127. l->dll_head->dle_prev = e;
  128. e->dle_next = l->dll_head;
  129. e->dle_prev = 0;
  130. l->dll_head = e;
  131. if (l->dll_tail == 0) /* if this is first element added */
  132. l->dll_tail = e;
  133. }
  134. void
  135. DLAddTail(Dllist *l, Dlelem *e)
  136. {
  137. e->dle_list = l;
  138. if (l->dll_tail)
  139. l->dll_tail->dle_next = e;
  140. e->dle_prev = l->dll_tail;
  141. e->dle_next = 0;
  142. l->dll_tail = e;
  143. if (l->dll_head == 0) /* if this is first element added */
  144. l->dll_head = e;
  145. }
  146. Dlelem *
  147. DLRemHead(Dllist *l)
  148. {
  149. /* remove and return the head */
  150. Dlelem    *result = l->dll_head;
  151. if (result == 0)
  152. return result;
  153. if (result->dle_next)
  154. result->dle_next->dle_prev = 0;
  155. l->dll_head = result->dle_next;
  156. result->dle_next = 0;
  157. result->dle_list = 0;
  158. if (result == l->dll_tail) /* if the head is also the tail */
  159. l->dll_tail = 0;
  160. return result;
  161. }
  162. Dlelem *
  163. DLRemTail(Dllist *l)
  164. {
  165. /* remove and return the tail */
  166. Dlelem    *result = l->dll_tail;
  167. if (result == 0)
  168. return result;
  169. if (result->dle_prev)
  170. result->dle_prev->dle_next = 0;
  171. l->dll_tail = result->dle_prev;
  172. result->dle_prev = 0;
  173. result->dle_list = 0;
  174. if (result == l->dll_head) /* if the tail is also the head */
  175. l->dll_head = 0;
  176. return result;
  177. }
  178. /* Same as DLRemove followed by DLAddHead, but faster */
  179. void
  180. DLMoveToFront(Dlelem *e)
  181. {
  182. Dllist    *l = e->dle_list;
  183. if (l->dll_head == e)
  184. return; /* Fast path if already at front */
  185. Assert(e->dle_prev != 0); /* since it's not the head */
  186. e->dle_prev->dle_next = e->dle_next;
  187. if (e->dle_next)
  188. e->dle_next->dle_prev = e->dle_prev;
  189. else /* must be the tail element */
  190. {
  191. Assert(e == l->dll_tail);
  192. l->dll_tail = e->dle_prev;
  193. }
  194. l->dll_head->dle_prev = e;
  195. e->dle_next = l->dll_head;
  196. e->dle_prev = 0;
  197. l->dll_head = e;
  198. /* We need not check dll_tail, since there must have been > 1 entry */
  199. }