0003-Remove-current-users-of-dllist.h.patch
text/x-patch
Filename: 0003-Remove-current-users-of-dllist.h.patch
Type: text/x-patch
Part: 2
Message:
Re: embedded list v3
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0003
Subject: Remove current users of dllist.h
| File | + | − |
|---|---|---|
| src/backend/postmaster/autovacuum.c | 64 | 64 |
| src/backend/postmaster/postmaster.c | 27 | 32 |
| src/backend/utils/cache/catcache.c | 74 | 70 |
| src/include/utils/catcache.h | 10 | 9 |
From 610e58e256ca6240fbfbdc78e527d4f1c4de6882 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 28 Sep 2012 16:42:03 +0200
Subject: [PATCH 3/4] Remove current users of dllist.h
Alvaro, Andres
---
src/backend/postmaster/autovacuum.c | 128 ++++++++++++++++----------------
src/backend/postmaster/postmaster.c | 59 +++++++--------
src/backend/utils/cache/catcache.c | 144 ++++++++++++++++++------------------
src/include/utils/catcache.h | 19 ++---
4 files changed, 175 insertions(+), 175 deletions(-)
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 74db821..c3ac219 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -77,7 +77,7 @@
#include "catalog/pg_database.h"
#include "commands/dbcommands.h"
#include "commands/vacuum.h"
-#include "lib/dllist.h"
+#include "lib/ilist.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
@@ -152,6 +152,7 @@ typedef struct avl_dbase
Oid adl_datid; /* hash key -- must be first */
TimestampTz adl_next_worker;
int adl_score;
+ dlist_node adl_node;
} avl_dbase;
/* struct to keep track of databases in worker */
@@ -258,8 +259,11 @@ typedef struct
static AutoVacuumShmemStruct *AutoVacuumShmem;
-/* the database list in the launcher, and the context that contains it */
-static Dllist *DatabaseList = NULL;
+/*
+ * the database list (of avl_dbase elements) in the launcher, and the context
+ * that contains it
+ */
+static dlist_head DatabaseList = DLIST_STATIC_INIT(DatabaseList);
static MemoryContext DatabaseListCxt = NULL;
/* Pointer to my own WorkerInfo, valid on each worker */
@@ -508,7 +512,7 @@ AutoVacLauncherMain(int argc, char *argv[])
/* don't leave dangling pointers to freed memory */
DatabaseListCxt = NULL;
- DatabaseList = NULL;
+ dlist_init(&DatabaseList);
/*
* Make sure pgstat also considers our stat data as gone. Note: we
@@ -576,7 +580,7 @@ AutoVacLauncherMain(int argc, char *argv[])
struct timeval nap;
TimestampTz current_time = 0;
bool can_launch;
- Dlelem *elem;
+ avl_dbase *avdb;
int rc;
/*
@@ -738,20 +742,7 @@ AutoVacLauncherMain(int argc, char *argv[])
/* We're OK to start a new worker */
- elem = DLGetTail(DatabaseList);
- if (elem != NULL)
- {
- avl_dbase *avdb = DLE_VAL(elem);
-
- /*
- * launch a worker if next_worker is right now or it is in the
- * past
- */
- if (TimestampDifferenceExceeds(avdb->adl_next_worker,
- current_time, 0))
- launch_worker(current_time);
- }
- else
+ if (dlist_is_empty(&DatabaseList))
{
/*
* Special case when the list is empty: start a worker right away.
@@ -763,6 +754,23 @@ AutoVacLauncherMain(int argc, char *argv[])
*/
launch_worker(current_time);
}
+ else
+ {
+ /*
+ * because rebuild_database_list constructs a list with most
+ * distant adl_next_worker first, we obtain our database from the
+ * tail of the list.
+ */
+ avdb = dlist_tail_element(avl_dbase, adl_node, &DatabaseList);
+
+ /*
+ * launch a worker if next_worker is right now or it is in the
+ * past
+ */
+ if (TimestampDifferenceExceeds(avdb->adl_next_worker,
+ current_time, 0))
+ launch_worker(current_time);
+ }
}
/* Normal exit from the autovac launcher is here */
@@ -783,7 +791,7 @@ AutoVacLauncherMain(int argc, char *argv[])
static void
launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
{
- Dlelem *elem;
+ avl_dbase *avdb;
/*
* We sleep until the next scheduled vacuum. We trust that when the
@@ -796,14 +804,15 @@ launcher_determine_sleep(bool canlaunch, bool recursing, struct timeval * nap)
nap->tv_sec = autovacuum_naptime;
nap->tv_usec = 0;
}
- else if ((elem = DLGetTail(DatabaseList)) != NULL)
+ else if (!dlist_is_empty(&DatabaseList))
{
- avl_dbase *avdb = DLE_VAL(elem);
TimestampTz current_time = GetCurrentTimestamp();
TimestampTz next_wakeup;
long secs;
int usecs;
+ avdb = dlist_tail_element(avl_dbase, adl_node, &DatabaseList);
+
next_wakeup = avdb->adl_next_worker;
TimestampDifference(current_time, next_wakeup, &secs, &usecs);
@@ -867,6 +876,7 @@ rebuild_database_list(Oid newdb)
int score;
int nelems;
HTAB *dbhash;
+ dlist_iter iter;
/* use fresh stats */
autovac_refresh_stats();
@@ -927,36 +937,28 @@ rebuild_database_list(Oid newdb)
}
/* Now insert the databases from the existing list */
- if (DatabaseList != NULL)
+ dlist_foreach(iter, &DatabaseList)
{
- Dlelem *elem;
-
- elem = DLGetHead(DatabaseList);
- while (elem != NULL)
- {
- avl_dbase *avdb = DLE_VAL(elem);
- avl_dbase *db;
- bool found;
- PgStat_StatDBEntry *entry;
-
- elem = DLGetSucc(elem);
+ avl_dbase *avdb = dlist_container(avl_dbase, adl_node, iter.cur);
+ avl_dbase *db;
+ bool found;
+ PgStat_StatDBEntry *entry;
- /*
- * skip databases with no stat entries -- in particular, this gets
- * rid of dropped databases
- */
- entry = pgstat_fetch_stat_dbentry(avdb->adl_datid);
- if (entry == NULL)
- continue;
+ /*
+ * skip databases with no stat entries -- in particular, this gets
+ * rid of dropped databases
+ */
+ entry = pgstat_fetch_stat_dbentry(avdb->adl_datid);
+ if (entry == NULL)
+ continue;
- db = hash_search(dbhash, &(avdb->adl_datid), HASH_ENTER, &found);
+ db = hash_search(dbhash, &(avdb->adl_datid), HASH_ENTER, &found);
- if (!found)
- {
- /* hash_search already filled in the key */
- db->adl_score = score++;
- /* next_worker is filled in later */
- }
+ if (!found)
+ {
+ /* hash_search already filled in the key */
+ db->adl_score = score++;
+ /* next_worker is filled in later */
}
}
@@ -987,7 +989,7 @@ rebuild_database_list(Oid newdb)
/* from here on, the allocated memory belongs to the new list */
MemoryContextSwitchTo(newcxt);
- DatabaseList = DLNewList();
+ dlist_init(&DatabaseList);
if (nelems > 0)
{
@@ -1029,15 +1031,13 @@ rebuild_database_list(Oid newdb)
for (i = 0; i < nelems; i++)
{
avl_dbase *db = &(dbary[i]);
- Dlelem *elem;
current_time = TimestampTzPlusMilliseconds(current_time,
millis_increment);
db->adl_next_worker = current_time;
- elem = DLNewElem(db);
/* later elements should go closer to the head of the list */
- DLAddHead(DatabaseList, elem);
+ dlist_push_head(&DatabaseList, &db->adl_node);
}
}
@@ -1147,7 +1147,7 @@ do_start_worker(void)
foreach(cell, dblist)
{
avw_dbase *tmp = lfirst(cell);
- Dlelem *elem;
+ dlist_iter iter;
/* Check to see if this one is at risk of wraparound */
if (TransactionIdPrecedes(tmp->adw_frozenxid, xidForceLimit))
@@ -1179,11 +1179,10 @@ do_start_worker(void)
* autovacuum time yet.
*/
skipit = false;
- elem = DatabaseList ? DLGetTail(DatabaseList) : NULL;
- while (elem != NULL)
+ dlist_reverse_foreach(iter, &DatabaseList)
{
- avl_dbase *dbp = DLE_VAL(elem);
+ avl_dbase *dbp = dlist_container(avl_dbase, adl_node, iter.cur);
if (dbp->adl_datid == tmp->adw_datid)
{
@@ -1200,7 +1199,6 @@ do_start_worker(void)
break;
}
- elem = DLGetPred(elem);
}
if (skipit)
continue;
@@ -1274,22 +1272,25 @@ static void
launch_worker(TimestampTz now)
{
Oid dbid;
- Dlelem *elem;
+ dlist_iter iter;
dbid = do_start_worker();
if (OidIsValid(dbid))
{
+ bool found = false;
+
/*
* Walk the database list and update the corresponding entry. If the
* database is not on the list, we'll recreate the list.
*/
- elem = (DatabaseList == NULL) ? NULL : DLGetHead(DatabaseList);
- while (elem != NULL)
+ dlist_foreach(iter, &DatabaseList)
{
- avl_dbase *avdb = DLE_VAL(elem);
+ avl_dbase *avdb = dlist_container(avl_dbase, adl_node, iter.cur);
if (avdb->adl_datid == dbid)
{
+ found = true;
+
/*
* add autovacuum_naptime seconds to the current time, and use
* that as the new "next_worker" field for this database.
@@ -1297,10 +1298,9 @@ launch_worker(TimestampTz now)
avdb->adl_next_worker =
TimestampTzPlusMilliseconds(now, autovacuum_naptime * 1000);
- DLMoveToFront(elem);
+ dlist_move_head(&DatabaseList, iter.cur);
break;
}
- elem = DLGetSucc(elem);
}
/*
@@ -1310,7 +1310,7 @@ launch_worker(TimestampTz now)
* pgstat entry, but this is not a problem because we don't want to
* schedule workers regularly into those in any case.
*/
- if (elem == NULL)
+ if (!found)
rebuild_database_list(dbid);
}
}
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index dff4c71..7060a1f 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -95,7 +95,7 @@
#include "access/xlog.h"
#include "bootstrap/bootstrap.h"
#include "catalog/pg_control.h"
-#include "lib/dllist.h"
+#include "lib/ilist.h"
#include "libpq/auth.h"
#include "libpq/ip.h"
#include "libpq/libpq.h"
@@ -146,10 +146,10 @@ typedef struct bkend
int child_slot; /* PMChildSlot for this backend, if any */
bool is_autovacuum; /* is it an autovacuum process? */
bool dead_end; /* is it going to send an error and quit? */
- Dlelem elem; /* list link in BackendList */
+ dlist_node elem; /* list link in BackendList */
} Backend;
-static Dllist *BackendList;
+static dlist_head BackendList = DLIST_STATIC_INIT(BackendList);
#ifdef EXEC_BACKEND
static Backend *ShmemBackendArray;
@@ -157,8 +157,10 @@ static Backend *ShmemBackendArray;
/* The socket number we are listening for connections on */
int PostPortNumber;
+
/* The directory names for Unix socket(s) */
char *Unix_socket_directories;
+
/* The TCP listen address(es) */
char *ListenAddresses;
@@ -1028,11 +1030,6 @@ PostmasterMain(int argc, char *argv[])
set_stack_base();
/*
- * Initialize the list of active backends.
- */
- BackendList = DLNewList();
-
- /*
* Initialize pipe (or process handle on Windows) that allows children to
* wake up from sleep on postmaster death.
*/
@@ -1872,7 +1869,7 @@ processCancelRequest(Port *port, void *pkt)
Backend *bp;
#ifndef EXEC_BACKEND
- Dlelem *curr;
+ dlist_iter iter;
#else
int i;
#endif
@@ -1886,9 +1883,9 @@ processCancelRequest(Port *port, void *pkt)
* duplicate array in shared memory.
*/
#ifndef EXEC_BACKEND
- for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
+ dlist_foreach(iter, &BackendList)
{
- bp = (Backend *) DLE_VAL(curr);
+ bp = dlist_container(Backend, elem, iter.cur);
#else
for (i = MaxLivePostmasterChildren() - 1; i >= 0; i--)
{
@@ -2648,7 +2645,7 @@ static void
CleanupBackend(int pid,
int exitstatus) /* child's exit status. */
{
- Dlelem *curr;
+ dlist_mutable_iter iter;
LogChildExit(DEBUG2, _("server process"), pid, exitstatus);
@@ -2680,9 +2677,9 @@ CleanupBackend(int pid,
return;
}
- for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
+ dlist_foreach_modify(iter, &BackendList)
{
- Backend *bp = (Backend *) DLE_VAL(curr);
+ Backend *bp = dlist_container(Backend, elem, iter.cur);
if (bp->pid == pid)
{
@@ -2701,7 +2698,7 @@ CleanupBackend(int pid,
ShmemBackendArrayRemove(bp);
#endif
}
- DLRemove(curr);
+ dlist_delete(&BackendList, iter.cur);
free(bp);
break;
}
@@ -2718,8 +2715,7 @@ CleanupBackend(int pid,
static void
HandleChildCrash(int pid, int exitstatus, const char *procname)
{
- Dlelem *curr,
- *next;
+ dlist_mutable_iter iter;
Backend *bp;
/*
@@ -2734,10 +2730,10 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
}
/* Process regular backends */
- for (curr = DLGetHead(BackendList); curr; curr = next)
+ dlist_foreach_modify(iter, &BackendList)
{
- next = DLGetSucc(curr);
- bp = (Backend *) DLE_VAL(curr);
+ bp = dlist_container(Backend, elem, iter.cur);
+
if (bp->pid == pid)
{
/*
@@ -2750,7 +2746,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
ShmemBackendArrayRemove(bp);
#endif
}
- DLRemove(curr);
+ dlist_delete(&BackendList, iter.cur);
free(bp);
/* Keep looping so we can signal remaining backends */
}
@@ -3113,7 +3109,7 @@ PostmasterStateMachine(void)
* normal state transition leading up to PM_WAIT_DEAD_END, or during
* FatalError processing.
*/
- if (DLGetHead(BackendList) == NULL &&
+ if (dlist_is_empty(&BackendList) &&
PgArchPID == 0 && PgStatPID == 0)
{
/* These other guys should be dead already */
@@ -3239,12 +3235,12 @@ signal_child(pid_t pid, int signal)
static bool
SignalSomeChildren(int signal, int target)
{
- Dlelem *curr;
+ dlist_iter iter;
bool signaled = false;
- for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
+ dlist_foreach(iter, &BackendList)
{
- Backend *bp = (Backend *) DLE_VAL(curr);
+ Backend *bp = dlist_container(Backend, elem, iter.cur);
if (bp->dead_end)
continue;
@@ -3382,8 +3378,8 @@ BackendStartup(Port *port)
*/
bn->pid = pid;
bn->is_autovacuum = false;
- DLInitElem(&bn->elem, bn);
- DLAddHead(BackendList, &bn->elem);
+ dlist_push_head(&BackendList, &bn->elem);
+
#ifdef EXEC_BACKEND
if (!bn->dead_end)
ShmemBackendArrayAdd(bn);
@@ -4498,12 +4494,12 @@ PostmasterRandom(void)
static int
CountChildren(int target)
{
- Dlelem *curr;
+ dlist_iter iter;
int cnt = 0;
- for (curr = DLGetHead(BackendList); curr; curr = DLGetSucc(curr))
+ dlist_foreach(iter, &BackendList)
{
- Backend *bp = (Backend *) DLE_VAL(curr);
+ Backend *bp = dlist_container(Backend, elem, iter.cur);
if (bp->dead_end)
continue;
@@ -4682,8 +4678,7 @@ StartAutovacuumWorker(void)
if (bn->pid > 0)
{
bn->is_autovacuum = true;
- DLInitElem(&bn->elem, bn);
- DLAddHead(BackendList, &bn->elem);
+ dlist_push_head(&BackendList, &bn->elem);
#ifdef EXEC_BACKEND
ShmemBackendArrayAdd(bn);
#endif
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index d6f6b1c..230ddf4 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -291,7 +291,7 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
static void
CatCachePrintStats(int code, Datum arg)
{
- CatCache *cache;
+ slist_iter iter;
long cc_searches = 0;
long cc_hits = 0;
long cc_neg_hits = 0;
@@ -300,8 +300,10 @@ CatCachePrintStats(int code, Datum arg)
long cc_lsearches = 0;
long cc_lhits = 0;
- for (cache = CacheHdr->ch_caches; cache; cache = cache->cc_next)
+ slist_foreach(iter, &CacheHdr->ch_caches)
{
+ CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
+
if (cache->cc_ntup == 0 && cache->cc_searches == 0)
continue; /* don't print unused caches */
elog(DEBUG2, "catcache %s/%u: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lsrch, %ld lhits",
@@ -368,8 +370,7 @@ CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
return; /* nothing left to do */
}
- /* delink from linked list */
- DLRemove(&ct->cache_elem);
+ dlist_delete(ct->cache_bucket, &ct->cache_elem);
/* free associated tuple data */
if (ct->tuple.t_data != NULL)
@@ -412,7 +413,7 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
}
/* delink from linked list */
- DLRemove(&cl->cache_elem);
+ dlist_delete(&cache->cc_lists, &cl->cache_elem);
/* free associated tuple data */
if (cl->tuple.t_data != NULL)
@@ -442,18 +443,18 @@ CatCacheRemoveCList(CatCache *cache, CatCList *cl)
void
CatalogCacheIdInvalidate(int cacheId, uint32 hashValue)
{
- CatCache *ccp;
+ slist_iter cache_iter;
CACHE1_elog(DEBUG2, "CatalogCacheIdInvalidate: called");
/*
* inspect caches to find the proper cache
*/
- for (ccp = CacheHdr->ch_caches; ccp; ccp = ccp->cc_next)
+ slist_foreach(cache_iter, &CacheHdr->ch_caches)
{
Index hashIndex;
- Dlelem *elt,
- *nextelt;
+ dlist_mutable_iter iter;
+ CatCache *ccp = slist_container(CatCache, cc_next, cache_iter.cur);
if (cacheId != ccp->id)
continue;
@@ -468,11 +469,9 @@ CatalogCacheIdInvalidate(int cacheId, uint32 hashValue)
* Invalidate *all* CatCLists in this cache; it's too hard to tell
* which searches might still be correct, so just zap 'em all.
*/
- for (elt = DLGetHead(&ccp->cc_lists); elt; elt = nextelt)
+ dlist_foreach_modify(iter, &ccp->cc_lists)
{
- CatCList *cl = (CatCList *) DLE_VAL(elt);
-
- nextelt = DLGetSucc(elt);
+ CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
if (cl->refcount > 0)
cl->dead = true;
@@ -484,12 +483,9 @@ CatalogCacheIdInvalidate(int cacheId, uint32 hashValue)
* inspect the proper hash bucket for tuple matches
*/
hashIndex = HASH_INDEX(hashValue, ccp->cc_nbuckets);
-
- for (elt = DLGetHead(&ccp->cc_bucket[hashIndex]); elt; elt = nextelt)
+ dlist_foreach_modify(iter, &ccp->cc_bucket[hashIndex])
{
- CatCTup *ct = (CatCTup *) DLE_VAL(elt);
-
- nextelt = DLGetSucc(elt);
+ CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
if (hashValue == ct->hash_value)
{
@@ -557,17 +553,18 @@ AtEOXact_CatCache(bool isCommit)
#ifdef USE_ASSERT_CHECKING
if (assert_enabled)
{
- CatCache *ccp;
+ slist_iter cache_iter;
- for (ccp = CacheHdr->ch_caches; ccp; ccp = ccp->cc_next)
+ slist_foreach(cache_iter, &(CacheHdr->ch_caches))
{
- Dlelem *elt;
+ CatCache *ccp = slist_container(CatCache, cc_next, cache_iter.cur);
+ dlist_iter iter;
int i;
/* Check CatCLists */
- for (elt = DLGetHead(&ccp->cc_lists); elt; elt = DLGetSucc(elt))
+ dlist_foreach(iter, &ccp->cc_lists)
{
- CatCList *cl = (CatCList *) DLE_VAL(elt);
+ CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
Assert(cl->cl_magic == CL_MAGIC);
Assert(cl->refcount == 0);
@@ -577,11 +574,11 @@ AtEOXact_CatCache(bool isCommit)
/* Check individual tuples */
for (i = 0; i < ccp->cc_nbuckets; i++)
{
- for (elt = DLGetHead(&ccp->cc_bucket[i]);
- elt;
- elt = DLGetSucc(elt))
+ dlist_head *bucket = &ccp->cc_bucket[i];
+
+ dlist_foreach(iter, bucket)
{
- CatCTup *ct = (CatCTup *) DLE_VAL(elt);
+ CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
Assert(ct->ct_magic == CT_MAGIC);
Assert(ct->refcount == 0);
@@ -604,16 +601,13 @@ AtEOXact_CatCache(bool isCommit)
static void
ResetCatalogCache(CatCache *cache)
{
- Dlelem *elt,
- *nextelt;
+ dlist_mutable_iter iter;
int i;
/* Remove each list in this cache, or at least mark it dead */
- for (elt = DLGetHead(&cache->cc_lists); elt; elt = nextelt)
+ dlist_foreach_modify(iter, &cache->cc_lists)
{
- CatCList *cl = (CatCList *) DLE_VAL(elt);
-
- nextelt = DLGetSucc(elt);
+ CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
if (cl->refcount > 0)
cl->dead = true;
@@ -624,11 +618,11 @@ ResetCatalogCache(CatCache *cache)
/* Remove each tuple in this cache, or at least mark it dead */
for (i = 0; i < cache->cc_nbuckets; i++)
{
- for (elt = DLGetHead(&cache->cc_bucket[i]); elt; elt = nextelt)
- {
- CatCTup *ct = (CatCTup *) DLE_VAL(elt);
+ dlist_head *bucket = &cache->cc_bucket[i];
- nextelt = DLGetSucc(elt);
+ dlist_foreach_modify(iter, bucket)
+ {
+ CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
if (ct->refcount > 0 ||
(ct->c_list && ct->c_list->refcount > 0))
@@ -654,12 +648,16 @@ ResetCatalogCache(CatCache *cache)
void
ResetCatalogCaches(void)
{
- CatCache *cache;
+ slist_iter iter;
CACHE1_elog(DEBUG2, "ResetCatalogCaches called");
- for (cache = CacheHdr->ch_caches; cache; cache = cache->cc_next)
+ slist_foreach(iter, &CacheHdr->ch_caches)
+ {
+ CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
+
ResetCatalogCache(cache);
+ }
CACHE1_elog(DEBUG2, "end of ResetCatalogCaches call");
}
@@ -680,12 +678,14 @@ ResetCatalogCaches(void)
void
CatalogCacheFlushCatalog(Oid catId)
{
- CatCache *cache;
+ slist_iter iter;
CACHE2_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
- for (cache = CacheHdr->ch_caches; cache; cache = cache->cc_next)
+ slist_foreach(iter, &(CacheHdr->ch_caches))
{
+ CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
+
/* Does this cache store tuples of the target catalog? */
if (cache->cc_reloid == catId)
{
@@ -760,7 +760,7 @@ InitCatCache(int id,
if (CacheHdr == NULL)
{
CacheHdr = (CatCacheHeader *) palloc(sizeof(CatCacheHeader));
- CacheHdr->ch_caches = NULL;
+ slist_init(&CacheHdr->ch_caches);
CacheHdr->ch_ntup = 0;
#ifdef CATCACHE_STATS
/* set up to dump stats at backend exit */
@@ -770,10 +770,8 @@ InitCatCache(int id,
/*
* allocate a new cache structure
- *
- * Note: we assume zeroing initializes the Dllist headers correctly
*/
- cp = (CatCache *) palloc0(sizeof(CatCache) + nbuckets * sizeof(Dllist));
+ cp = (CatCache *) palloc0(sizeof(CatCache) + nbuckets * sizeof(dlist_node));
/*
* initialize the cache's relation information for the relation
@@ -792,6 +790,11 @@ InitCatCache(int id,
for (i = 0; i < nkeys; ++i)
cp->cc_key[i] = key[i];
+ dlist_init(&cp->cc_lists);
+
+ for (i = 0; i < nbuckets; i++)
+ dlist_init(&cp->cc_bucket[i]);
+
/*
* new cache is initialized as far as we can go for now. print some
* debugging information, if appropriate.
@@ -801,8 +804,7 @@ InitCatCache(int id,
/*
* add completed cache to top of group header's list
*/
- cp->cc_next = CacheHdr->ch_caches;
- CacheHdr->ch_caches = cp;
+ slist_push_head(&CacheHdr->ch_caches, &cp->cc_next);
/*
* back to the old context before we return...
@@ -1060,7 +1062,8 @@ SearchCatCache(CatCache *cache,
ScanKeyData cur_skey[CATCACHE_MAXKEYS];
uint32 hashValue;
Index hashIndex;
- Dlelem *elt;
+ dlist_mutable_iter iter;
+ dlist_head *bucket;
CatCTup *ct;
Relation relation;
SysScanDesc scandesc;
@@ -1094,13 +1097,13 @@ SearchCatCache(CatCache *cache,
/*
* scan the hash bucket until we find a match or exhaust our tuples
*/
- for (elt = DLGetHead(&cache->cc_bucket[hashIndex]);
- elt;
- elt = DLGetSucc(elt))
+ bucket = &cache->cc_bucket[hashIndex];
+
+ dlist_foreach_modify(iter, bucket)
{
bool res;
- ct = (CatCTup *) DLE_VAL(elt);
+ ct = dlist_container(CatCTup, cache_elem, iter.cur);
if (ct->dead)
continue; /* ignore dead entries */
@@ -1125,7 +1128,7 @@ SearchCatCache(CatCache *cache,
* most frequently accessed elements in any hashbucket will tend to be
* near the front of the hashbucket's list.)
*/
- DLMoveToFront(&ct->cache_elem);
+ dlist_move_head(bucket, &ct->cache_elem);
/*
* If it's a positive entry, bump its refcount and return it. If it's
@@ -1340,7 +1343,7 @@ SearchCatCacheList(CatCache *cache,
{
ScanKeyData cur_skey[CATCACHE_MAXKEYS];
uint32 lHashValue;
- Dlelem *elt;
+ dlist_iter iter;
CatCList *cl;
CatCTup *ct;
List *volatile ctlist;
@@ -1382,13 +1385,11 @@ SearchCatCacheList(CatCache *cache,
/*
* scan the items until we find a match or exhaust our list
*/
- for (elt = DLGetHead(&cache->cc_lists);
- elt;
- elt = DLGetSucc(elt))
+ dlist_foreach(iter, &cache->cc_lists)
{
bool res;
- cl = (CatCList *) DLE_VAL(elt);
+ cl = dlist_container(CatCList, cache_elem, iter.cur);
if (cl->dead)
continue; /* ignore dead entries */
@@ -1416,7 +1417,7 @@ SearchCatCacheList(CatCache *cache,
* since there's no point in that unless they are searched for
* individually.)
*/
- DLMoveToFront(&cl->cache_elem);
+ dlist_move_head(&cache->cc_lists, &cl->cache_elem);
/* Bump the list's refcount and return it */
ResourceOwnerEnlargeCatCacheListRefs(CurrentResourceOwner);
@@ -1468,6 +1469,8 @@ SearchCatCacheList(CatCache *cache,
{
uint32 hashValue;
Index hashIndex;
+ bool found = false;
+ dlist_head *bucket;
/*
* See if there's an entry for this tuple already.
@@ -1476,11 +1479,10 @@ SearchCatCacheList(CatCache *cache,
hashValue = CatalogCacheComputeTupleHashValue(cache, ntp);
hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
- for (elt = DLGetHead(&cache->cc_bucket[hashIndex]);
- elt;
- elt = DLGetSucc(elt))
+ bucket = &cache->cc_bucket[hashIndex];
+ dlist_foreach(iter, bucket)
{
- ct = (CatCTup *) DLE_VAL(elt);
+ ct = dlist_container(CatCTup, cache_elem, iter.cur);
if (ct->dead || ct->negative)
continue; /* ignore dead and negative entries */
@@ -1498,10 +1500,11 @@ SearchCatCacheList(CatCache *cache,
if (ct->c_list)
continue;
+ found = true;
break; /* A-OK */
}
- if (elt == NULL)
+ if (!found)
{
/* We didn't find a usable entry, so make a new one */
ct = CatalogCacheCreateEntry(cache, ntp,
@@ -1564,7 +1567,6 @@ SearchCatCacheList(CatCache *cache,
cl->cl_magic = CL_MAGIC;
cl->my_cache = cache;
- DLInitElem(&cl->cache_elem, cl);
cl->refcount = 0; /* for the moment */
cl->dead = false;
cl->ordered = ordered;
@@ -1587,7 +1589,7 @@ SearchCatCacheList(CatCache *cache,
}
Assert(i == nmembers);
- DLAddHead(&cache->cc_lists, &cl->cache_elem);
+ dlist_push_head(&cache->cc_lists, &cl->cache_elem);
/* Finally, bump the list's refcount and return it */
cl->refcount++;
@@ -1664,14 +1666,15 @@ CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp,
*/
ct->ct_magic = CT_MAGIC;
ct->my_cache = cache;
- DLInitElem(&ct->cache_elem, (void *) ct);
+ ct->cache_bucket = &cache->cc_bucket[hashIndex];
+
ct->c_list = NULL;
ct->refcount = 0; /* for the moment */
ct->dead = false;
ct->negative = negative;
ct->hash_value = hashValue;
- DLAddHead(&cache->cc_bucket[hashIndex], &ct->cache_elem);
+ dlist_push_head(ct->cache_bucket, &ct->cache_elem);
cache->cc_ntup++;
CacheHdr->ch_ntup++;
@@ -1785,7 +1788,7 @@ PrepareToInvalidateCacheTuple(Relation relation,
HeapTuple newtuple,
void (*function) (int, uint32, Oid))
{
- CatCache *ccp;
+ slist_iter iter;
Oid reloid;
CACHE1_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
@@ -1808,10 +1811,11 @@ PrepareToInvalidateCacheTuple(Relation relation,
* ----------------
*/
- for (ccp = CacheHdr->ch_caches; ccp; ccp = ccp->cc_next)
+ slist_foreach(iter, &(CacheHdr->ch_caches))
{
uint32 hashvalue;
Oid dbid;
+ CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
if (ccp->cc_reloid != reloid)
continue;
diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h
index d91700a..cc6dab2 100644
--- a/src/include/utils/catcache.h
+++ b/src/include/utils/catcache.h
@@ -22,7 +22,7 @@
#include "access/htup.h"
#include "access/skey.h"
-#include "lib/dllist.h"
+#include "lib/ilist.h"
#include "utils/relcache.h"
/*
@@ -37,7 +37,7 @@
typedef struct catcache
{
int id; /* cache identifier --- see syscache.h */
- struct catcache *cc_next; /* link to next catcache */
+ slist_node cc_next; /* list link */
const char *cc_relname; /* name of relation the tuples come from */
Oid cc_reloid; /* OID of relation the tuples come from */
Oid cc_indexoid; /* OID of index matching cache keys */
@@ -51,7 +51,7 @@ typedef struct catcache
ScanKeyData cc_skey[CATCACHE_MAXKEYS]; /* precomputed key info for
* heap scans */
bool cc_isname[CATCACHE_MAXKEYS]; /* flag "name" key columns */
- Dllist cc_lists; /* list of CatCList structs */
+ dlist_head cc_lists; /* list of CatCList structs */
#ifdef CATCACHE_STATS
long cc_searches; /* total # searches against this cache */
long cc_hits; /* # of matches against existing entry */
@@ -66,7 +66,7 @@ typedef struct catcache
long cc_lsearches; /* total # list-searches */
long cc_lhits; /* # of matches against existing lists */
#endif
- Dllist cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */
+ dlist_head cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */
} CatCache; /* VARIABLE LENGTH STRUCT */
@@ -77,11 +77,12 @@ typedef struct catctup
CatCache *my_cache; /* link to owning catcache */
/*
- * Each tuple in a cache is a member of a Dllist that stores the elements
- * of its hash bucket. We keep each Dllist in LRU order to speed repeated
+ * Each tuple in a cache is a member of a dlist that stores the elements
+ * of its hash bucket. We keep each dlist in LRU order to speed repeated
* lookups.
*/
- Dlelem cache_elem; /* list member of per-bucket list */
+ dlist_node cache_elem; /* list member of per-bucket list */
+ dlist_head *cache_bucket; /* containing bucket dlist */
/*
* The tuple may also be a member of at most one CatCList. (If a single
@@ -139,7 +140,7 @@ typedef struct catclist
* might not be true during bootstrap or recovery operations. (namespace.c
* is able to save some cycles when it is true.)
*/
- Dlelem cache_elem; /* list member of per-catcache list */
+ dlist_node cache_elem; /* list member of per-catcache list */
int refcount; /* number of active references */
bool dead; /* dead but not yet removed? */
bool ordered; /* members listed in index order? */
@@ -153,7 +154,7 @@ typedef struct catclist
typedef struct catcacheheader
{
- CatCache *ch_caches; /* head of list of CatCache structs */
+ slist_head ch_caches; /* head of list of CatCache structs */
int ch_ntup; /* # of tuples in all caches */
} CatCacheHeader;
--
1.7.12.289.g0ce9864.dirty