diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-10-05 17:28:13 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-10-05 17:28:13 +0000 |
commit | 8a52b893b3d83c6dc796fae6a07a4ac30c871fc4 (patch) | |
tree | 65b88475931f536afffe13f489c10167a8b12a12 /src/backend/utils/cache/relcache.c | |
parent | 343318028fb4aca0c69663c7d429d602a32aaf02 (diff) | |
download | postgresql-8a52b893b3d83c6dc796fae6a07a4ac30c871fc4.tar.gz postgresql-8a52b893b3d83c6dc796fae6a07a4ac30c871fc4.zip |
Further cleanup of dynahash.c API, in pursuit of portability and
readability. Bizarre '(long *) TRUE' return convention is gone,
in favor of just raising an error internally in dynahash.c when
we detect hashtable corruption. HashTableWalk is gone, in favor
of using hash_seq_search directly, since it had no hope of working
with non-LONGALIGNable datatypes. Simplify some other code that was
made undesirably grotty by promixity to HashTableWalk.
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 161 |
1 files changed, 71 insertions, 90 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 628e96842d8..8d854871394 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.144 2001/10/01 05:36:16 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.145 2001/10/05 17:28:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -48,12 +48,12 @@ #include "catalog/pg_rewrite.h" #include "catalog/pg_type.h" #include "commands/trigger.h" -#include "lib/hasht.h" #include "miscadmin.h" #include "storage/smgr.h" #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/fmgroids.h" +#include "utils/hsearch.h" #include "utils/memutils.h" #include "utils/relcache.h" #include "utils/temprel.h" @@ -144,38 +144,33 @@ do { \ HASH_ENTER, \ &found); \ if (namehentry == NULL) \ - elog(FATAL, "can't insert into relation descriptor cache"); \ - if (found && !IsBootstrapProcessingMode()) \ - /* used to give notice -- now just keep quiet */ ; \ + elog(ERROR, "out of memory for relation descriptor cache"); \ + /* used to give notice if found -- now just keep quiet */ ; \ namehentry->reldesc = RELATION; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ (void *) &(RELATION->rd_id), \ HASH_ENTER, \ &found); \ if (idhentry == NULL) \ - elog(FATAL, "can't insert into relation descriptor cache"); \ - if (found && !IsBootstrapProcessingMode()) \ - /* used to give notice -- now just keep quiet */ ; \ + elog(ERROR, "out of memory for relation descriptor cache"); \ + /* used to give notice if found -- now just keep quiet */ ; \ idhentry->reldesc = RELATION; \ nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ (void *) &(RELATION->rd_node), \ HASH_ENTER, \ &found); \ if (nodentry == NULL) \ - elog(FATAL, "can't insert into relation descriptor cache"); \ - if (found && !IsBootstrapProcessingMode()) \ - /* used to give notice -- now just keep quiet */ ; \ + elog(ERROR, "out of memory for relation descriptor cache"); \ + /* used to give notice if found -- now just keep quiet */ ; \ nodentry->reldesc = RELATION; \ } while(0) #define RelationNameCacheLookup(NAME, RELATION) \ do { \ - RelNameCacheEnt *hentry; bool found; \ + RelNameCacheEnt *hentry; \ hentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ - (void *) (NAME),HASH_FIND,&found); \ - if (hentry == NULL) \ - elog(FATAL, "error in CACHE"); \ - if (found) \ + (void *) (NAME), HASH_FIND,NULL); \ + if (hentry) \ RELATION = hentry->reldesc; \ else \ RELATION = NULL; \ @@ -184,12 +179,9 @@ do { \ #define RelationIdCacheLookup(ID, RELATION) \ do { \ RelIdCacheEnt *hentry; \ - bool found; \ hentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ - (void *)&(ID),HASH_FIND, &found); \ - if (hentry == NULL) \ - elog(FATAL, "error in CACHE"); \ - if (found) \ + (void *)&(ID), HASH_FIND,NULL); \ + if (hentry) \ RELATION = hentry->reldesc; \ else \ RELATION = NULL; \ @@ -198,12 +190,9 @@ do { \ #define RelationNodeCacheLookup(NODE, RELATION) \ do { \ RelNodeCacheEnt *hentry; \ - bool found; \ hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ - (void *)&(NODE),HASH_FIND, &found); \ - if (hentry == NULL) \ - elog(FATAL, "error in CACHE"); \ - if (found) \ + (void *)&(NODE), HASH_FIND,NULL); \ + if (hentry) \ RELATION = hentry->reldesc; \ else \ RELATION = NULL; \ @@ -212,29 +201,22 @@ do { \ #define RelationCacheDelete(RELATION) \ do { \ RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \ - char *relname; RelNodeCacheEnt *nodentry; bool found; \ + char *relname; RelNodeCacheEnt *nodentry; \ relname = RelationGetPhysicalRelationName(RELATION); \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ relname, \ - HASH_REMOVE, \ - &found); \ + HASH_REMOVE, NULL); \ if (namehentry == NULL) \ - elog(FATAL, "can't delete from relation descriptor cache"); \ - if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ (void *)&(RELATION->rd_id), \ - HASH_REMOVE, &found); \ + HASH_REMOVE, NULL); \ if (idhentry == NULL) \ - elog(FATAL, "can't delete from relation descriptor cache"); \ - if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ (void *)&(RELATION->rd_node), \ - HASH_REMOVE, &found); \ + HASH_REMOVE, NULL); \ if (nodentry == NULL) \ - elog(FATAL, "can't delete from relation descriptor cache"); \ - if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ } while(0) @@ -248,8 +230,6 @@ static void RelationReloadClassinfo(Relation relation); #endif /* ENABLE_REINDEX_NAILED_RELATIONS */ static void RelationFlushRelation(Relation relation); static Relation RelationNameCacheGetRelation(const char *relationName); -static void RelationCacheInvalidateWalker(Relation *relationPtr, Datum listp); -static void RelationCacheAbortWalker(Relation *relationPtr, Datum dummy); static void init_irels(void); static void write_irels(void); @@ -1842,56 +1822,54 @@ RelationFlushIndexes(Relation *r, * * We do this in two phases: the first pass deletes deletable items, and * the second one rebuilds the rebuildable items. This is essential for - * safety, because HashTableWalk only copes with concurrent deletion of + * safety, because hash_seq_search only copes with concurrent deletion of * the element it is currently visiting. If a second SI overflow were to * occur while we are walking the table, resulting in recursive entry to * this routine, we could crash because the inner invocation blows away * the entry next to be visited by the outer scan. But this way is OK, * because (a) during the first pass we won't process any more SI messages, - * so HashTableWalk will complete safely; (b) during the second pass we + * so hash_seq_search will complete safely; (b) during the second pass we * only hold onto pointers to nondeletable entries. */ void RelationCacheInvalidate(void) { + HASH_SEQ_STATUS status; + RelNameCacheEnt *namehentry; + Relation relation; List *rebuildList = NIL; List *l; /* Phase 1 */ - HashTableWalk(RelationNameCache, - (HashtFunc) RelationCacheInvalidateWalker, - PointerGetDatum(&rebuildList)); + hash_seq_init(&status, RelationNameCache); - /* Phase 2: rebuild the items found to need rebuild in phase 1 */ - foreach(l, rebuildList) + while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) { - Relation relation = (Relation) lfirst(l); - - RelationClearRelation(relation, true); - } - freeList(rebuildList); -} + relation = namehentry->reldesc; -static void -RelationCacheInvalidateWalker(Relation *relationPtr, Datum listp) -{ - Relation relation = *relationPtr; - List **rebuildList = (List **) DatumGetPointer(listp); - - /* We can ignore xact-local relations, since they are never SI targets */ - if (relation->rd_myxactonly) - return; + /* Ignore xact-local relations, since they are never SI targets */ + if (relation->rd_myxactonly) + continue; - if (RelationHasReferenceCountZero(relation)) - { - /* Delete this entry immediately */ - RelationClearRelation(relation, false); + if (RelationHasReferenceCountZero(relation)) + { + /* Delete this entry immediately */ + RelationClearRelation(relation, false); + } + else + { + /* Add entry to list of stuff to rebuild in second pass */ + rebuildList = lcons(relation, rebuildList); + } } - else + + /* Phase 2: rebuild the items found to need rebuild in phase 1 */ + foreach(l, rebuildList) { - /* Add entry to list of stuff to rebuild in second pass */ - *rebuildList = lcons(relation, *rebuildList); + relation = (Relation) lfirst(l); + RelationClearRelation(relation, true); } + freeList(rebuildList); } /* @@ -1910,20 +1888,20 @@ RelationCacheInvalidateWalker(Relation *relationPtr, Datum listp) void RelationCacheAbort(void) { - HashTableWalk(RelationNameCache, - (HashtFunc) RelationCacheAbortWalker, - 0); -} + HASH_SEQ_STATUS status; + RelNameCacheEnt *namehentry; -static void -RelationCacheAbortWalker(Relation *relationPtr, Datum dummy) -{ - Relation relation = *relationPtr; + hash_seq_init(&status, RelationNameCache); - if (relation->rd_isnailed) - RelationSetReferenceCount(relation, 1); - else - RelationSetReferenceCount(relation, 0); + while ((namehentry = (RelNameCacheEnt *) hash_seq_search(&status)) != NULL) + { + Relation relation = namehentry->reldesc; + + if (relation->rd_isnailed) + RelationSetReferenceCount(relation, 1); + else + RelationSetReferenceCount(relation, 0); + } } /* @@ -2095,19 +2073,20 @@ RelationCacheInitialize(void) MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(NameData); ctl.entrysize = sizeof(RelNameCacheEnt); - RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM); + RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE, + &ctl, HASH_ELEM); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelIdCacheEnt); ctl.hash = tag_hash; - RelationIdCache = hash_create(INITRELCACHESIZE, &ctl, - HASH_ELEM | HASH_FUNCTION); + RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE, + &ctl, HASH_ELEM | HASH_FUNCTION); ctl.keysize = sizeof(RelFileNode); ctl.entrysize = sizeof(RelNodeCacheEnt); ctl.hash = tag_hash; - RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl, - HASH_ELEM | HASH_FUNCTION); + RelationNodeCache = hash_create("Relcache by rnode", INITRELCACHESIZE, + &ctl, HASH_ELEM | HASH_FUNCTION); /* * initialize the cache with pre-made relation descriptors for some of @@ -2187,19 +2166,21 @@ CreateDummyCaches(void) MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(NameData); ctl.entrysize = sizeof(RelNameCacheEnt); - RelationNameCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM); + RelationNameCache = hash_create("Relcache by name", INITRELCACHESIZE, + &ctl, HASH_ELEM); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelIdCacheEnt); ctl.hash = tag_hash; - RelationIdCache = hash_create(INITRELCACHESIZE, &ctl, - HASH_ELEM | HASH_FUNCTION); + RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE, + &ctl, HASH_ELEM | HASH_FUNCTION); ctl.keysize = sizeof(RelFileNode); ctl.entrysize = sizeof(RelNodeCacheEnt); ctl.hash = tag_hash; - RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl, - HASH_ELEM | HASH_FUNCTION); + RelationNodeCache = hash_create("Relcache by rnode", INITRELCACHESIZE, + &ctl, HASH_ELEM | HASH_FUNCTION); + MemoryContextSwitchTo(oldcxt); } |