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:
100
src/backend/utils/cache/relcache.c
vendored
100
src/backend/utils/cache/relcache.c
vendored
@ -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
|
||||
|
Reference in New Issue
Block a user