Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+63-33
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

+8-6
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

+2-1
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)