Skip to content
Snippets Groups Projects
Commit 185b4272 authored by Tom Lane's avatar Tom Lane
Browse files

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.
parent 2a44383a
No related branches found
No related tags found
No related merge requests found
......@@ -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_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_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 */
}
......@@ -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);
......
......@@ -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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment