1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

New relcache hash table with RelFileNode as key to be used

from bufmgr - it would be nice to have separate hash in smgr
for node <--> fd mappings, but for the moment it's easy to
add new hash to relcache.
Fixed small bug in xlog.c:ReadRecord.
This commit is contained in:
Vadim B. Mikheev
2000-10-23 04:10:24 +00:00
parent c82c9559a7
commit 4b65a2840b
8 changed files with 114 additions and 101 deletions

View File

@ -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 $
*
*-------------------------------------------------------------------------
*/
@ -83,6 +83,13 @@ static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
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
@ -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