syscache.c
来自「PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统」· C语言 代码 · 共 731 行 · 第 1/2 页
C
731 行
ProcedureOidIndexId, 0, 1, { ObjectIdAttributeNumber, 0, 0, 0 }}, {RelationRelationId, /* RELNAMENSP */ ClassNameNspIndexId, ObjectIdAttributeNumber, 2, { Anum_pg_class_relname, Anum_pg_class_relnamespace, 0, 0 }}, {RelationRelationId, /* RELOID */ ClassOidIndexId, ObjectIdAttributeNumber, 1, { ObjectIdAttributeNumber, 0, 0, 0 }}, {RewriteRelationId, /* RULERELNAME */ RewriteRelRulenameIndexId, Anum_pg_rewrite_ev_class, 2, { Anum_pg_rewrite_ev_class, Anum_pg_rewrite_rulename, 0, 0 }}, {StatisticRelationId, /* STATRELATT */ StatisticRelidAttnumIndexId, Anum_pg_statistic_starelid, 2, { Anum_pg_statistic_starelid, Anum_pg_statistic_staattnum, 0, 0 }}, {TypeRelationId, /* TYPENAMENSP */ TypeNameNspIndexId, Anum_pg_type_typrelid, 2, { Anum_pg_type_typname, Anum_pg_type_typnamespace, 0, 0 }}, {TypeRelationId, /* TYPEOID */ TypeOidIndexId, Anum_pg_type_typrelid, 1, { ObjectIdAttributeNumber, 0, 0, 0 }}};static CatCache *SysCache[ lengthof(cacheinfo)];static int SysCacheSize = lengthof(cacheinfo);static bool CacheInitialized = false;/* * InitCatalogCache - initialize the caches * * Note that no database access is done here; we only allocate memory * and initialize the cache structure. Interrogation of the database * to complete initialization of a cache happens upon first use * of that cache. */voidInitCatalogCache(void){ int cacheId; Assert(!CacheInitialized); MemSet(SysCache, 0, sizeof(SysCache)); for (cacheId = 0; cacheId < SysCacheSize; cacheId++) { SysCache[cacheId] = InitCatCache(cacheId, cacheinfo[cacheId].reloid, cacheinfo[cacheId].indoid, cacheinfo[cacheId].reloidattr, cacheinfo[cacheId].nkeys, cacheinfo[cacheId].key); if (!PointerIsValid(SysCache[cacheId])) elog(ERROR, "could not initialize cache %u (%d)", cacheinfo[cacheId].reloid, cacheId); } CacheInitialized = true;}/* * InitCatalogCachePhase2 - finish initializing the caches * * Finish initializing all the caches, including necessary database * access. * * This is *not* essential; normally we allow syscaches to be initialized * on first use. However, it is useful as a mechanism to preload the * relcache with entries for the most-commonly-used system catalogs. * Therefore, we invoke this routine when we need to write a new relcache * init file. */voidInitCatalogCachePhase2(void){ int cacheId; Assert(CacheInitialized); for (cacheId = 0; cacheId < SysCacheSize; cacheId++) InitCatCachePhase2(SysCache[cacheId]);}/* * SearchSysCache * * A layer on top of SearchCatCache that does the initialization and * key-setting for you. * * Returns the cache copy of the tuple if one is found, NULL if not. * The tuple is the 'cache' copy and must NOT be modified! * * When the caller is done using the tuple, call ReleaseSysCache() * to release the reference count grabbed by SearchSysCache(). If this * is not done, the tuple will remain locked in cache until end of * transaction, which is tolerable but not desirable. * * CAUTION: The tuple that is returned must NOT be freed by the caller! */HeapTupleSearchSysCache(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4){ if (cacheId < 0 || cacheId >= SysCacheSize || !PointerIsValid(SysCache[cacheId])) elog(ERROR, "invalid cache id: %d", cacheId); return SearchCatCache(SysCache[cacheId], key1, key2, key3, key4);}/* * ReleaseSysCache * Release previously grabbed reference count on a tuple */voidReleaseSysCache(HeapTuple tuple){ ReleaseCatCache(tuple);}/* * SearchSysCacheCopy * * A convenience routine that does SearchSysCache and (if successful) * returns a modifiable copy of the syscache entry. The original * syscache entry is released before returning. The caller should * heap_freetuple() the result when done with it. */HeapTupleSearchSysCacheCopy(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4){ HeapTuple tuple, newtuple; tuple = SearchSysCache(cacheId, key1, key2, key3, key4); if (!HeapTupleIsValid(tuple)) return tuple; newtuple = heap_copytuple(tuple); ReleaseSysCache(tuple); return newtuple;}/* * SearchSysCacheExists * * A convenience routine that just probes to see if a tuple can be found. * No lock is retained on the syscache entry. */boolSearchSysCacheExists(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4){ HeapTuple tuple; tuple = SearchSysCache(cacheId, key1, key2, key3, key4); if (!HeapTupleIsValid(tuple)) return false; ReleaseSysCache(tuple); return true;}/* * GetSysCacheOid * * A convenience routine that does SearchSysCache and returns the OID * of the found tuple, or InvalidOid if no tuple could be found. * No lock is retained on the syscache entry. */OidGetSysCacheOid(int cacheId, Datum key1, Datum key2, Datum key3, Datum key4){ HeapTuple tuple; Oid result; tuple = SearchSysCache(cacheId, key1, key2, key3, key4); if (!HeapTupleIsValid(tuple)) return InvalidOid; result = HeapTupleGetOid(tuple); ReleaseSysCache(tuple); return result;}/* * SearchSysCacheAttName * * This routine is equivalent to SearchSysCache on the ATTNAME cache, * except that it will return NULL if the found attribute is marked * attisdropped. This is convenient for callers that want to act as * though dropped attributes don't exist. */HeapTupleSearchSysCacheAttName(Oid relid, const char *attname){ HeapTuple tuple; tuple = SearchSysCache(ATTNAME, ObjectIdGetDatum(relid), CStringGetDatum(attname), 0, 0); if (!HeapTupleIsValid(tuple)) return NULL; if (((Form_pg_attribute) GETSTRUCT(tuple))->attisdropped) { ReleaseSysCache(tuple); return NULL; } return tuple;}/* * SearchSysCacheCopyAttName * * As above, an attisdropped-aware version of SearchSysCacheCopy. */HeapTupleSearchSysCacheCopyAttName(Oid relid, const char *attname){ HeapTuple tuple, newtuple; tuple = SearchSysCacheAttName(relid, attname); if (!HeapTupleIsValid(tuple)) return tuple; newtuple = heap_copytuple(tuple); ReleaseSysCache(tuple); return newtuple;}/* * SearchSysCacheExistsAttName * * As above, an attisdropped-aware version of SearchSysCacheExists. */boolSearchSysCacheExistsAttName(Oid relid, const char *attname){ HeapTuple tuple; tuple = SearchSysCacheAttName(relid, attname); if (!HeapTupleIsValid(tuple)) return false; ReleaseSysCache(tuple); return true;}/* * SysCacheGetAttr * * Given a tuple previously fetched by SearchSysCache(), * extract a specific attribute. * * This is equivalent to using heap_getattr() on a tuple fetched * from a non-cached relation. Usually, this is only used for attributes * that could be NULL or variable length; the fixed-size attributes in * a system table are accessed just by mapping the tuple onto the C struct * declarations from include/catalog/. * * As with heap_getattr(), if the attribute is of a pass-by-reference type * then a pointer into the tuple data area is returned --- the caller must * not modify or pfree the datum! */DatumSysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull){ /* * We just need to get the TupleDesc out of the cache entry, and then we * can apply heap_getattr(). We expect that the cache control data is * currently valid --- if the caller recently fetched the tuple, then it * should be. */ if (cacheId < 0 || cacheId >= SysCacheSize) elog(ERROR, "invalid cache id: %d", cacheId); if (!PointerIsValid(SysCache[cacheId]) || !PointerIsValid(SysCache[cacheId]->cc_tupdesc)) elog(ERROR, "missing cache data for cache id %d", cacheId); return heap_getattr(tup, attributeNumber, SysCache[cacheId]->cc_tupdesc, isNull);}/* * List-search interface */struct catclist *SearchSysCacheList(int cacheId, int nkeys, Datum key1, Datum key2, Datum key3, Datum key4){ if (cacheId < 0 || cacheId >= SysCacheSize || !PointerIsValid(SysCache[cacheId])) elog(ERROR, "invalid cache id: %d", cacheId); return SearchCatCacheList(SysCache[cacheId], nkeys, key1, key2, key3, key4);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?