diff options
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 100 |
1 files changed, 84 insertions, 16 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 755359e2514..de3e3c4a8d3 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.112 2000/10/16 14:52:13 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.113 2000/10/23 04:10:08 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -84,6 +84,13 @@ static HTAB *RelationNameCache; static HTAB *RelationIdCache; /* + * Bufmgr uses RelFileNode for lookup. Actually, I would like to do + * not pass Relation to bufmgr & beyond at all and keep some cache + * in smgr, but no time to do it right way now. -- vadim 10/22/2000 + */ +static HTAB *RelationNodeCache; + +/* * newlyCreatedRelns - * relations created during this transaction. We need to keep track of * these. @@ -114,17 +121,23 @@ typedef struct RelationBuildDescInfo } i; } RelationBuildDescInfo; +typedef struct relnamecacheent +{ + NameData relname; + Relation reldesc; +} RelNameCacheEnt; + typedef struct relidcacheent { Oid reloid; Relation reldesc; } RelIdCacheEnt; -typedef struct relnamecacheent +typedef struct relnodecacheent { - NameData relname; + RelFileNode relnode; Relation reldesc; -} RelNameCacheEnt; +} RelNodeCacheEnt; /* ----------------- * macros to manipulate name cache and id cache @@ -133,7 +146,7 @@ typedef struct relnamecacheent #define RelationCacheInsert(RELATION) \ do { \ RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \ - char *relname; Oid reloid; bool found; \ + char *relname; RelNodeCacheEnt *nodentry; bool found; \ relname = RelationGetPhysicalRelationName(RELATION); \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ relname, \ @@ -144,9 +157,8 @@ do { \ if (found && !IsBootstrapProcessingMode()) \ /* used to give notice -- now just keep quiet */ ; \ namehentry->reldesc = RELATION; \ - reloid = RELATION->rd_id; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ - (char *)&reloid, \ + (char *)&(RELATION->rd_id), \ HASH_ENTER, \ &found); \ if (idhentry == NULL) \ @@ -154,6 +166,15 @@ do { \ if (found && !IsBootstrapProcessingMode()) \ /* used to give notice -- now just keep quiet */ ; \ idhentry->reldesc = RELATION; \ + nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ + (char *)&(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 */ ; \ + nodentry->reldesc = RELATION; \ } while(0) #define RelationNameCacheLookup(NAME, RELATION) \ @@ -183,10 +204,24 @@ do { \ RELATION = NULL; \ } while(0) +#define RelationNodeCacheLookup(NODE, RELATION) \ +do { \ + RelNodeCacheEnt *hentry; \ + bool found; \ + hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \ + (char *)&(NODE),HASH_FIND, &found); \ + if (hentry == NULL) \ + elog(FATAL, "error in CACHE"); \ + if (found) \ + RELATION = hentry->reldesc; \ + else \ + RELATION = NULL; \ +} while(0) + #define RelationCacheDelete(RELATION) \ do { \ RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \ - char *relname; Oid reloid; bool found; \ + char *relname; RelNodeCacheEnt *nodentry; bool found; \ relname = RelationGetPhysicalRelationName(RELATION); \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ relname, \ @@ -196,14 +231,20 @@ do { \ elog(FATAL, "can't delete from relation descriptor cache"); \ if (!found) \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \ - reloid = RELATION->rd_id; \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ - (char *)&reloid, \ + (char *)&(RELATION->rd_id), \ HASH_REMOVE, &found); \ 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, \ + (char *)&(RELATION->rd_node), \ + HASH_REMOVE, &found); \ + 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) /* non-export function prototypes */ @@ -1192,12 +1233,6 @@ formrdesc(char *relationName, */ RelationInitLockInfo(relation); /* see lmgr.c */ - /* ---------------- - * add new reldesc to relcache - * ---------------- - */ - RelationCacheInsert(relation); - if (IsSharedSystemRelationName(relationName)) relation->rd_node.tblNode = InvalidOid; else @@ -1205,6 +1240,12 @@ formrdesc(char *relationName, relation->rd_node.relNode = relation->rd_rel->relfilenode = RelationGetRelid(relation); + /* ---------------- + * add new reldesc to relcache + * ---------------- + */ + RelationCacheInsert(relation); + /* * Determining this requires a scan on pg_class, but to do the scan * the rdesc for pg_class must already exist. Therefore we must do @@ -1343,6 +1384,28 @@ RelationNameCacheGetRelation(const char *relationName) return rd; } +Relation +RelationNodeCacheGetRelation(RelFileNode rnode) +{ + Relation rd; + + RelationNodeCacheLookup(rnode, rd); + + if (RelationIsValid(rd)) + { + if (rd->rd_fd == -1 && rd->rd_rel->relkind != RELKIND_VIEW) + { + rd->rd_fd = smgropen(DEFAULT_SMGR, rd); + Assert(rd->rd_fd != -1 || rd->rd_unlinked); + } + + RelationIncrementReferenceCount(rd); + + } + + return rd; +} + /* -------------------------------- * RelationIdGetRelation * @@ -1942,6 +2005,11 @@ RelationCacheInitialize(void) RelationIdCache = hash_create(INITRELCACHESIZE, &ctl, HASH_ELEM | HASH_FUNCTION); + ctl.keysize = sizeof(RelFileNode); + ctl.hash = tag_hash; + RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl, + HASH_ELEM | HASH_FUNCTION); + /* ---------------- * initialize the cache with pre-made relation descriptors * for some of the more important system relations. These |