aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-05-31 23:48:04 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-05-31 23:48:04 +0000
commit185b4272844970a9e1b46eb3d1d16d4e5ecca939 (patch)
tree9bfdfa7e5323f5bcf0ecc8a357fb737dd4821bf0 /src
parent2a44383a2d38ac4655e419cb8c2c654efe960285 (diff)
downloadpostgresql-185b4272844970a9e1b46eb3d1d16d4e5ecca939.tar.gz
postgresql-185b4272844970a9e1b46eb3d1d16d4e5ecca939.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/lib/dllist.c96
-rw-r--r--src/backend/utils/cache/catcache.c14
-rw-r--r--src/include/lib/dllist.h3
3 files changed, 73 insertions, 40 deletions
diff --git a/src/backend/lib/dllist.c b/src/backend/lib/dllist.c
index 9aeb82f266c..3ca7cf03c74 100644
--- a/src/backend/lib/dllist.c
+++ b/src/backend/lib/dllist.c
@@ -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 */
+}
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 80444d0a143..cc76acdd747 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.41 1999/05/25 16:12:22 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.42 1999/05/31 23:48:04 tgl Exp $
*
* Notes:
* XXX This needs to use exception.h to handle recovery when
@@ -876,16 +876,18 @@ SearchSysCache(struct catcache * cache,
/* ----------------
* if we found a tuple in the cache, move it to the top of the
- * lru list, and return it.
+ * lru list, and return it. We also move it to the front of the
+ * list for its hashbucket, in order to speed subsequent searches.
+ * (The most frequently accessed elements in any hashbucket will
+ * tend to be near the front of the hashbucket's list.)
* ----------------
*/
if (elt)
{
- Dlelem *old_lru_elt;
+ Dlelem *old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
- old_lru_elt = ((CatCTup *) DLE_VAL(elt))->ct_node;
- DLRemove(old_lru_elt);
- DLAddHead(cache->cc_lrulist, old_lru_elt);
+ DLMoveToFront(old_lru_elt);
+ DLMoveToFront(elt);
#ifdef CACHEDEBUG
relation = heap_open(cache->relationId);
diff --git a/src/include/lib/dllist.h b/src/include/lib/dllist.h
index 7c3707afcab..a367450185c 100644
--- a/src/include/lib/dllist.h
+++ b/src/include/lib/dllist.h
@@ -26,7 +26,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: dllist.h,v 1.9 1999/02/13 23:21:30 momjian Exp $
+ * $Id: dllist.h,v 1.10 1999/05/31 23:48:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,6 +66,7 @@ extern void DLRemove(Dlelem *); /* removes node from list */
extern void DLAddHead(Dllist *list, Dlelem *node);
extern void DLAddTail(Dllist *list, Dlelem *node);
extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */
+extern void DLMoveToFront(Dlelem *); /* move node to front of its list */
#define DLE_VAL(x) (x->dle_val)