mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
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.
This commit is contained in:
parent
2a44383a2d
commit
185b427284
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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
|
void
|
||||||
DLFreeList(Dllist *l)
|
DLFreeList(Dllist *l)
|
||||||
{
|
{
|
||||||
@ -85,7 +87,7 @@ DLGetTail(Dllist *l)
|
|||||||
return l ? l->dll_tail : 0;
|
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
|
#ifdef NOT_USED
|
||||||
void *
|
void *
|
||||||
DLGetTailVal(Dllist *l)
|
DLGetTailVal(Dllist *l)
|
||||||
@ -112,20 +114,26 @@ DLGetSucc(Dlelem *e) /* get successor */
|
|||||||
void
|
void
|
||||||
DLRemove(Dlelem *e)
|
DLRemove(Dlelem *e)
|
||||||
{
|
{
|
||||||
Dllist *l;
|
Dllist *l = e->dle_list;
|
||||||
|
|
||||||
if (e->dle_prev)
|
if (e->dle_prev)
|
||||||
e->dle_prev->dle_next = e->dle_next;
|
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)
|
if (e->dle_next)
|
||||||
e->dle_next->dle_prev = e->dle_prev;
|
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 */
|
e->dle_next = 0;
|
||||||
l = e->dle_list;
|
e->dle_prev = 0;
|
||||||
if (e == l->dll_head)
|
e->dle_list = 0;
|
||||||
DLRemHead(l);
|
|
||||||
if (e == l->dll_tail)
|
|
||||||
DLRemTail(l);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -134,15 +142,13 @@ DLAddHead(Dllist *l, Dlelem *e)
|
|||||||
e->dle_list = l;
|
e->dle_list = l;
|
||||||
|
|
||||||
if (l->dll_head)
|
if (l->dll_head)
|
||||||
{
|
|
||||||
l->dll_head->dle_prev = e;
|
l->dll_head->dle_prev = e;
|
||||||
e->dle_next = l->dll_head;
|
e->dle_next = l->dll_head;
|
||||||
}
|
|
||||||
e->dle_prev = 0;
|
e->dle_prev = 0;
|
||||||
l->dll_head = e;
|
l->dll_head = e;
|
||||||
|
|
||||||
if (l->dll_tail == 0) /* if this is first element added */
|
if (l->dll_tail == 0) /* if this is first element added */
|
||||||
l->dll_tail = l->dll_head;
|
l->dll_tail = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -151,31 +157,28 @@ DLAddTail(Dllist *l, Dlelem *e)
|
|||||||
e->dle_list = l;
|
e->dle_list = l;
|
||||||
|
|
||||||
if (l->dll_tail)
|
if (l->dll_tail)
|
||||||
{
|
|
||||||
l->dll_tail->dle_next = e;
|
l->dll_tail->dle_next = e;
|
||||||
e->dle_prev = l->dll_tail;
|
e->dle_prev = l->dll_tail;
|
||||||
}
|
|
||||||
e->dle_next = 0;
|
e->dle_next = 0;
|
||||||
l->dll_tail = e;
|
l->dll_tail = e;
|
||||||
|
|
||||||
if (l->dll_head == 0) /* if this is first element added */
|
if (l->dll_head == 0) /* if this is first element added */
|
||||||
l->dll_head = l->dll_tail;
|
l->dll_head = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dlelem *
|
Dlelem *
|
||||||
DLRemHead(Dllist *l)
|
DLRemHead(Dllist *l)
|
||||||
{
|
{
|
||||||
/* remove and return the head */
|
/* remove and return the head */
|
||||||
Dlelem *result;
|
Dlelem *result = l->dll_head;
|
||||||
|
|
||||||
if (l->dll_head == 0)
|
if (result == 0)
|
||||||
return 0;
|
return result;
|
||||||
|
|
||||||
result = l->dll_head;
|
if (result->dle_next)
|
||||||
if (l->dll_head->dle_next)
|
result->dle_next->dle_prev = 0;
|
||||||
l->dll_head->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_next = 0;
|
||||||
result->dle_list = 0;
|
result->dle_list = 0;
|
||||||
@ -190,15 +193,15 @@ Dlelem *
|
|||||||
DLRemTail(Dllist *l)
|
DLRemTail(Dllist *l)
|
||||||
{
|
{
|
||||||
/* remove and return the tail */
|
/* remove and return the tail */
|
||||||
Dlelem *result;
|
Dlelem *result = l->dll_tail;
|
||||||
|
|
||||||
if (l->dll_tail == 0)
|
if (result == 0)
|
||||||
return 0;
|
return result;
|
||||||
|
|
||||||
result = l->dll_tail;
|
if (result->dle_prev)
|
||||||
if (l->dll_tail->dle_prev)
|
result->dle_prev->dle_next = 0;
|
||||||
l->dll_tail->dle_prev->dle_next = 0;
|
|
||||||
l->dll_tail = l->dll_tail->dle_prev;
|
l->dll_tail = result->dle_prev;
|
||||||
|
|
||||||
result->dle_prev = 0;
|
result->dle_prev = 0;
|
||||||
result->dle_list = 0;
|
result->dle_list = 0;
|
||||||
@ -208,3 +211,30 @@ DLRemTail(Dllist *l)
|
|||||||
|
|
||||||
return result;
|
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 */
|
||||||
|
}
|
||||||
|
14
src/backend/utils/cache/catcache.c
vendored
14
src/backend/utils/cache/catcache.c
vendored
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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:
|
* Notes:
|
||||||
* XXX This needs to use exception.h to handle recovery when
|
* 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
|
* 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)
|
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;
|
DLMoveToFront(old_lru_elt);
|
||||||
DLRemove(old_lru_elt);
|
DLMoveToFront(elt);
|
||||||
DLAddHead(cache->cc_lrulist, old_lru_elt);
|
|
||||||
|
|
||||||
#ifdef CACHEDEBUG
|
#ifdef CACHEDEBUG
|
||||||
relation = heap_open(cache->relationId);
|
relation = heap_open(cache->relationId);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* 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 DLAddHead(Dllist *list, Dlelem *node);
|
||||||
extern void DLAddTail(Dllist *list, Dlelem *node);
|
extern void DLAddTail(Dllist *list, Dlelem *node);
|
||||||
extern Dlelem *DLRemHead(Dllist *list); /* remove and return the head */
|
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)
|
#define DLE_VAL(x) (x->dle_val)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user