35 #include "utils/fmgroids.h" 50 #define HASH_INDEX(h, sz) ((Index) ((h) & ((sz) - 1))) 58 #define CACHE_elog(...) elog(__VA_ARGS__) 60 #define CACHE_elog(...) 83 const Datum *cachekeys,
84 const Datum *searchkeys);
87 static void CatCachePrintStats(
int code,
Datum arg);
143 return hash_any((
unsigned char *) key, strlen(key));
237 case REGPROCEDUREOID:
243 case REGDICTIONARYOID:
245 case REGNAMESPACEOID:
253 *eqfunc = F_OIDVECTOREQ;
256 elog(
FATAL,
"type %u not supported as catcache key", keytype);
283 oneHash = (cc_hashfunc[3]) (v4);
285 hashValue ^= oneHash << 24;
286 hashValue ^= oneHash >> 8;
289 oneHash = (cc_hashfunc[2]) (v3);
291 hashValue ^= oneHash << 16;
292 hashValue ^= oneHash >> 16;
295 oneHash = (cc_hashfunc[1]) (v2);
297 hashValue ^= oneHash << 8;
298 hashValue ^= oneHash >> 24;
301 oneHash = (cc_hashfunc[0]) (v1);
303 hashValue ^= oneHash;
306 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
361 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
375 const Datum *cachekeys,
376 const Datum *searchkeys)
381 for (i = 0; i < nkeys; i++)
383 if (!(cc_fastequal[i]) (cachekeys[i], searchkeys[i]))
390 #ifdef CATCACHE_STATS 393 CatCachePrintStats(
int code,
Datum arg)
396 long cc_searches = 0;
398 long cc_neg_hits = 0;
399 long cc_newloads = 0;
401 long cc_lsearches = 0;
408 if (cache->
cc_ntup == 0 && cache->cc_searches == 0)
410 elog(
DEBUG2,
"catcache %s/%u: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lsrch, %ld lhits",
417 cache->cc_hits + cache->cc_neg_hits,
419 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits - cache->cc_newloads,
420 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits,
424 cc_searches += cache->cc_searches;
425 cc_hits += cache->cc_hits;
426 cc_neg_hits += cache->cc_neg_hits;
427 cc_newloads += cache->cc_newloads;
428 cc_invals += cache->cc_invals;
429 cc_lsearches += cache->cc_lsearches;
430 cc_lhits += cache->cc_lhits;
432 elog(
DEBUG2,
"catcache totals: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lsrch, %ld lhits",
437 cc_hits + cc_neg_hits,
439 cc_searches - cc_hits - cc_neg_hits - cc_newloads,
440 cc_searches - cc_hits - cc_neg_hits,
515 #ifndef CATCACHE_FORCE_RELEASE
598 #ifdef CATCACHE_STATS 628 "CacheMemoryContext",
676 #ifdef CATCACHE_STATS 752 #define InitCatCache_DEBUG2 \ 754 elog(DEBUG2, "InitCatCache: rel=%u ind=%u id=%d nkeys=%d size=%d", \ 755 cp->cc_reloid, cp->cc_indexoid, cp->id, \ 756 cp->cc_nkeys, cp->cc_nbuckets); \ 759 #define InitCatCache_DEBUG2 786 Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
800 if (CacheHdr == NULL)
805 #ifdef CATCACHE_STATS 834 for (i = 0; i < nkeys; ++
i)
866 elog(
DEBUG1,
"rehashing catalog cache id %d for %s; %d tups, %d buckets",
902 #define CatalogCacheInitializeCache_DEBUG1 \ 903 elog(DEBUG2, "CatalogCacheInitializeCache: cache @%p rel=%u", cache, \ 906 #define CatalogCacheInitializeCache_DEBUG2 \ 908 if (cache->cc_keyno[i] > 0) { \ 909 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d, %u", \ 910 i+1, cache->cc_nkeys, cache->cc_keyno[i], \ 911 TupleDescAttr(tupdesc, cache->cc_keyno[i] - 1)->atttypid); \ 913 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d", \ 914 i+1, cache->cc_nkeys, cache->cc_keyno[i]); \ 918 #define CatalogCacheInitializeCache_DEBUG1 919 #define CatalogCacheInitializeCache_DEBUG2 979 keytype = attr->atttypid;
986 elog(
FATAL,
"sys attributes are not supported in caches");
1223 #ifdef CATCACHE_STATS 1224 cache->cc_searches++;
1280 #ifdef CATCACHE_STATS 1291 #ifdef CATCACHE_STATS 1292 cache->cc_neg_hits++;
1371 hashValue, hashIndex,
1400 hashValue, hashIndex,
1421 #ifdef CATCACHE_STATS 1422 cache->cc_newloads++;
1453 #ifndef CATCACHE_FORCE_RELEASE
1518 List *
volatile ctlist;
1532 Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1534 #ifdef CATCACHE_STATS 1535 cache->cc_lsearches++;
1570 if (cl->
nkeys != nkeys)
1593 #ifdef CATCACHE_STATS 1640 ordered = (scandesc->
irel != NULL);
1685 hashValue, hashIndex,
1707 arguments, cl->
keys);
1721 foreach(ctlist_item, ctlist)
1728 #ifndef CATCACHE_FORCE_RELEASE
1750 foreach(ctlist_item, ctlist)
1791 #ifndef CATCACHE_FORCE_RELEASE
1836 MAXIMUM_ALIGNOF + dtp->
t_len);
1844 (
const char *) dtp->
t_data,
1852 for (i = 0; i < cache->
cc_nkeys; i++)
1876 arguments, ct->
keys);
1915 for (i = 0; i < nkeys; i++)
1946 for (i = 0; i < nkeys; i++)
1959 if (att->atttypid == NAMEOID)
2023 Assert(CacheHdr != NULL);
2051 (*function) (ccp->
id, hashvalue, dbid);
2059 if (newhashvalue != hashvalue)
2060 (*function) (ccp->
id, newhashvalue, dbid);
2079 elog(
WARNING,
"cache reference leak: cache %s (%d), tuple %u/%u has count %d",
2089 elog(
WARNING,
"cache reference leak: cache %s (%d), list %p has count %d",
#define PG_CACHE_LINE_SIZE
int cc_keyno[CATCACHE_MAXKEYS]
void PrintCatCacheListLeakWarning(CatCList *list)
void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
#define AllocSetContextCreate
void table_close(Relation relation, LOCKMODE lockmode)
static void ResetCatalogCache(CatCache *cache)
void systable_endscan(SysScanDesc sysscan)
#define fastgetattr(tup, attnum, tupleDesc, isnull)
#define CatalogCacheInitializeCache_DEBUG1
#define dlist_foreach_modify(iter, lhead)
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
static CatCacheHeader * CacheHdr
#define RelationGetDescr(relation)
#define HASH_INDEX(h, sz)
static void dlist_push_head(dlist_head *head, dlist_node *node)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void namestrcpy(Name name, const char *str)
void on_proc_exit(pg_on_exit_callback function, Datum arg)
HeapTupleHeaderData * HeapTupleHeader
#define TupleDescAttr(tupdesc, i)
#define dlist_foreach(iter, lhead)
ResourceOwner CurrentResourceOwner
CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]
#define RelationGetForm(relation)
char * pstrdup(const char *in)
static uint32 namehashfast(Datum datum)
static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static void slist_push_head(slist_head *head, slist_node *node)
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner)
void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
static uint32 murmurhash32(uint32 data)
bool criticalSharedRelcachesBuilt
#define DirectFunctionCall1(func, arg1)
static bool texteqfast(Datum a, Datum b)
void heap_freetuple(HeapTuple htup)
Datum keys[CATCACHE_MAXKEYS]
static void CatalogCacheInitializeCache(CatCache *cache)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Datum keys[CATCACHE_MAXKEYS]
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *srckeys, Datum *dstkeys)
void ReleaseCatCacheList(CatCList *list)
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
#define dlist_container(type, membername, ptr)
HeapTuple systable_getnext(SysScanDesc sysscan)
static bool nameeqfast(Datum a, Datum b)
void pfree(void *pointer)
static void slist_init(slist_head *head)
static void RehashCatCache(CatCache *cp)
#define DatumGetCString(X)
#define RelationIsValid(relation)
StrategyNumber sk_strategy
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, Datum *arguments, uint32 hashValue, Index hashIndex, bool negative)
Datum hashtext(PG_FUNCTION_ARGS)
#define ALLOCSET_DEFAULT_SIZES
Datum texteq(PG_FUNCTION_ARGS)
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
static uint32 int2hashfast(Datum datum)
#define RelationGetRelationName(relation)
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
FormData_pg_attribute * Form_pg_attribute
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
#define CatalogCacheInitializeCache_DEBUG2
static Datum hash_any(const unsigned char *k, int keylen)
static void dlist_delete(dlist_node *node)
TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
static void GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
Datum datumCopy(Datum value, bool typByVal, int typLen)
MemoryContext TopMemoryContext
List * lappend(List *list, void *datum)
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
static bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
#define heap_getattr(tup, attnum, tupleDesc, isnull)
static bool oidvectoreqfast(Datum a, Datum b)
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
static bool chareqfast(Datum a, Datum b)
#define slist_container(type, membername, ptr)
static uint32 charhashfast(Datum datum)
void * palloc0(Size size)
static bool IndexScanOK(CatCache *cache, ScanKey cur_skey)
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
void PrintCatCacheLeakWarning(HeapTuple tuple)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void ReleaseCatCache(HeapTuple tuple)
void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
#define InitCatCache_DEBUG2
#define HeapTupleIsValid(tuple)
#define Assert(condition)
void CatalogCacheFlushCatalog(Oid catId)
#define CACHELINEALIGN(LEN)
CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]
static bool int2eqfast(Datum a, Datum b)
void CreateCacheMemoryContext(void)
uint32(* CCHashFN)(Datum datum)
static int list_length(const List *l)
bool IsTransactionState(void)
#define ItemPointerGetOffsetNumber(pointer)
void ResetCatalogCaches(void)
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
void index_close(Relation relation, LOCKMODE lockmode)
#define DatumGetPointer(X)
static void dlist_move_head(dlist_head *head, dlist_node *node)
#define IsBootstrapProcessingMode()
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
#define slist_foreach(iter, lhead)
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
struct TupleDescData * TupleDesc
#define HeapTupleHasExternal(tuple)
static bool int4eqfast(Datum a, Datum b)
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Datum hashoidvector(PG_FUNCTION_ARGS)
static uint32 texthashfast(Datum datum)
void InitCatCachePhase2(CatCache *cache, bool touch_index)
#define ItemPointerGetBlockNumber(pointer)
bool criticalRelcachesBuilt
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Relation table_open(Oid relationId, LOCKMODE lockmode)
Datum oidvectoreq(PG_FUNCTION_ARGS)
static uint32 int4hashfast(Datum datum)
bool(* CCFastEqualFN)(Datum a, Datum b)
#define PointerIsValid(pointer)
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
#define RelationGetRelid(relation)
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner)
Relation index_open(Oid relationId, LOCKMODE lockmode)
#define DirectFunctionCall2(func, arg1, arg2)
#define BTEqualStrategyNumber
#define offsetof(type, field)
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
static uint32 oidvectorhashfast(Datum datum)
MemoryContext CacheMemoryContext
void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)