Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 185b427

Browse files
committed
Fix some latent bugs in dllist.c (carelessness about setting
all fields that should be set). Add a MoveToFront primitive to speed up one of the hotspots in SearchSysCache.
1 parent 2a44383 commit 185b427

File tree

3 files changed

+73
-40
lines changed

3 files changed

+73
-40
lines changed

src/backend/lib/dllist.c

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.12 1999/02/13 23:15:34 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/lib/dllist.c,v 1.13 1999/05/31 23:48:03 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -30,7 +30,9 @@ DLNewList(void)
3030
return l;
3131
}
3232

33-
/* free up a list and all the nodes in it */
33+
/* free up a list and all the nodes in it --- but *not* whatever the nodes
34+
* might point to!
35+
*/
3436
void
3537
DLFreeList(Dllist *l)
3638
{
@@ -85,7 +87,7 @@ DLGetTail(Dllist *l)
8587
return l ? l->dll_tail : 0;
8688
}
8789

88-
/* get the value stored in the first element */
90+
/* get the value stored in the last element */
8991
#ifdef NOT_USED
9092
void *
9193
DLGetTailVal(Dllist *l)
@@ -112,20 +114,26 @@ DLGetSucc(Dlelem *e) /* get successor */
112114
void
113115
DLRemove(Dlelem *e)
114116
{
115-
Dllist *l;
117+
Dllist *l = e->dle_list;
116118

117119
if (e->dle_prev)
118120
e->dle_prev->dle_next = e->dle_next;
121+
else /* must be the head element */
122+
{
123+
Assert(e == l->dll_head);
124+
l->dll_head = e->dle_next;
125+
}
119126
if (e->dle_next)
120127
e->dle_next->dle_prev = e->dle_prev;
128+
else /* must be the tail element */
129+
{
130+
Assert(e == l->dll_tail);
131+
l->dll_tail = e->dle_prev;
132+
}
121133

122-
/* check to see if we're removing the head or tail */
123-
l = e->dle_list;
124-
if (e == l->dll_head)
125-
DLRemHead(l);
126-
if (e == l->dll_tail)
127-
DLRemTail(l);
128-
134+
e->dle_next = 0;
135+
e->dle_prev = 0;
136+
e->dle_list = 0;
129137
}
130138

131139
void
@@ -134,15 +142,13 @@ DLAddHead(Dllist *l, Dlelem *e)
134142
e->dle_list = l;
135143

136144
if (l->dll_head)
137-
{
138145
l->dll_head->dle_prev = e;
139-
e->dle_next = l->dll_head;
140-
}
146+
e->dle_next = l->dll_head;
141147
e->dle_prev = 0;
142148
l->dll_head = e;
143149

144150
if (l->dll_tail == 0) /* if this is first element added */
145-
l->dll_tail = l->dll_head;
151+
l->dll_tail = e;
146152
}
147153

148154
void
@@ -151,31 +157,28 @@ DLAddTail(Dllist *l, Dlelem *e)
151157
e->dle_list = l;
152158

153159
if (l->dll_tail)
154-
{
155160
l->dll_tail->dle_next = e;
156-
e->dle_prev = l->dll_tail;
157-
}
161+
e->dle_prev = l->dll_tail;
158162
e->dle_next = 0;
159163
l->dll_tail = e;
160164

161165
if (l->dll_head == 0) /* if this is first element added */
162-
l->dll_head = l->dll_tail;
166+
l->dll_head = e;
163167
}
164168

165169
Dlelem *
166170
DLRemHead(Dllist *l)
167171
{
168172
/* remove and return the head */
169-
Dlelem *result;
173+
Dlelem *result = l->dll_head;
170174

171-
if (l->dll_head == 0)
172-
return 0;
175+
if (result == 0)
176+
return result;
173177

174-
result = l->dll_head;
175-
if (l->dll_head->dle_next)
176-
l->dll_head->dle_next->dle_prev = 0;
178+
if (result->dle_next)
179+
result->dle_next->dle_prev = 0;
177180

178-
l->dll_head = l->dll_head->dle_next;
181+
l->dll_head = result->dle_next;
179182

180183
result->dle_next = 0;
181184
result->dle_list = 0;
@@ -190,15 +193,15 @@ Dlelem *
190193
DLRemTail(Dllist *l)
191194
{
192195
/* remove and return the tail */
193-
Dlelem *result;
196+
Dlelem *result = l->dll_tail;
194197

195-
if (l->dll_tail == 0)
196-
return 0;
198+
if (result == 0)
199+
return result;
197200

198-
result = l->dll_tail;
199-
if (l->dll_tail->dle_prev)
200-
l->dll_tail->dle_prev->dle_next = 0;
201-
l->dll_tail = l->dll_tail->dle_prev;
201+
if (result->dle_prev)
202+
result->dle_prev->dle_next = 0;
203+
204+
l->dll_tail = result->dle_prev;
202205

203206
result->dle_prev = 0;
204207
result->dle_list = 0;
@@ -208,3 +211,30 @@ DLRemTail(Dllist *l)
208211

209212
return result;
210213
}
214+
215+
/* Same as DLRemove followed by DLAddHead, but faster */
216+
void
217+
DLMoveToFront(Dlelem *e)
218+
{
219+
Dllist *l = e->dle_list;
220+
221+
if (l->dll_head == e)
222+
return; /* Fast path if already at front */
223+
224+
Assert(e->dle_prev != 0); /* since it's not the head */
225+
e->dle_prev->dle_next = e->dle_next;
226+
227+
if (e->dle_next)
228+
e->dle_next->dle_prev = e->dle_prev;
229+
else /* must be the tail element */
230+
{
231+
Assert(e == l->dll_tail);
232+
l->dll_tail = e->dle_prev;
233+
}
234+
235+
l->dll_head->dle_prev = e;
236+
e->dle_next = l->dll_head;
237+
e->dle_prev = 0;
238+
l->dll_head = e;
239+
/* We need not check dll_tail, since there must have been > 1 entry */
240+
}

src/backend/utils/cache/catcache.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.41 1999/05/25 16:12:22 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.42 1999/05/31 23:48:04 tgl Exp $
1111
*
1212
* Notes:
1313
* XXX This needs to use exception.h to handle recovery when
@@ -876,16 +876,18 @@ SearchSysCache(struct catcache * cache,
876876

877877
/* ----------------
878878
* if we found a tuple in the cache, move it to the top of the
879-
* lru list, and return it.
879+
* lru list, and return it. We also move it to the front of the
880+
* list for its hashbucket, in order to speed subsequent searches.
881+
* (The most frequently accessed elements in any hashbucket will
882+
* tend to be near the front of the hashbucket's list.)
880883
* ----------------
881884
*/
882885
if (elt)
883886
{
884-
Dlelem *old_lru_elt;
887+
Dlelem *old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
885888

886-
old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
887-
DLRemove(old_lru_elt);
888-
DLAddHead(cache->cc_lrulist, old_lru_elt);
889+
DLMoveToFront(old_lru_elt);
890+
DLMoveToFront(elt);
889891

890892
#ifdef CACHEDEBUG
891893
relation = heap_open(cache->relationId);

src/include/lib/dllist.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
* Copyright (c) 1994, Regents of the University of California
2828
*
29-
* $Id: dllist.h,v 1.9 1999/02/13 23:21:30 momjian Exp $
29+
* $Id: dllist.h,v 1.10 1999/05/31 23:48:03 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -66,6 +66,7 @@ extern void DLRemove(Dlelem *); /* removes node from list */
6666
extern void DLAddHead(Dllist *list, Dlelem *node);
6767
extern void DLAddTail(Dllist *list, Dlelem *node);
6868
extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */
69+
extern void DLMoveToFront(Dlelem *); /* move node to front of its list */
6970

7071
#define DLE_VAL(x) (x->dle_val)
7172

0 commit comments

Comments
 (0)