36 #include "utils/fmgroids.h"
51 #define HASH_INDEX(h, sz) ((Index) ((h) & ((sz) - 1)))
59 #define CACHE_elog(...) elog(__VA_ARGS__)
61 #define CACHE_elog(...)
84 const Datum *cachekeys,
85 const Datum *searchkeys);
88 static void CatCachePrintStats(
int code,
Datum arg);
122 .
name =
"catcache reference",
132 .
name =
"catcache list reference",
292 case REGPROCEDUREOID:
297 case REGCOLLATIONOID:
299 case REGDICTIONARYOID:
301 case REGNAMESPACEOID:
309 *eqfunc = F_OIDVECTOREQ;
312 elog(
FATAL,
"type %u not supported as catcache key", keytype);
339 oneHash = (cc_hashfunc[3]) (v4);
343 oneHash = (cc_hashfunc[2]) (v3);
347 oneHash = (cc_hashfunc[1]) (v2);
351 oneHash = (cc_hashfunc[0]) (v1);
352 hashValue ^= oneHash;
355 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
410 elog(
FATAL,
"wrong number of hash keys: %d", nkeys);
424 const Datum *cachekeys,
425 const Datum *searchkeys)
430 for (
i = 0;
i < nkeys;
i++)
432 if (!(cc_fastequal[
i]) (cachekeys[
i], searchkeys[
i]))
439 #ifdef CATCACHE_STATS
442 CatCachePrintStats(
int code,
Datum arg)
445 long cc_searches = 0;
447 long cc_neg_hits = 0;
448 long cc_newloads = 0;
451 long cc_lsearches = 0;
458 if (cache->
cc_ntup == 0 && cache->cc_searches == 0)
460 elog(
DEBUG2,
"catcache %s/%u: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %d lists, %ld lsrch, %ld lhits",
467 cache->cc_hits + cache->cc_neg_hits,
469 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits - cache->cc_newloads,
470 cache->cc_searches - cache->cc_hits - cache->cc_neg_hits,
475 cc_searches += cache->cc_searches;
476 cc_hits += cache->cc_hits;
477 cc_neg_hits += cache->cc_neg_hits;
478 cc_newloads += cache->cc_newloads;
479 cc_invals += cache->cc_invals;
481 cc_lsearches += cache->cc_lsearches;
482 cc_lhits += cache->cc_lhits;
484 elog(
DEBUG2,
"catcache totals: %d tup, %ld srch, %ld+%ld=%ld hits, %ld+%ld=%ld loads, %ld invals, %ld lists, %ld lsrch, %ld lhits",
489 cc_hits + cc_neg_hits,
491 cc_searches - cc_hits - cc_neg_hits - cc_newloads,
492 cc_searches - cc_hits - cc_neg_hits,
568 #ifndef CATCACHE_FORCE_RELEASE
658 #ifdef CATCACHE_STATS
688 "CacheMemoryContext",
741 #ifdef CATCACHE_STATS
817 #define InitCatCache_DEBUG2 \
819 elog(DEBUG2, "InitCatCache: rel=%u ind=%u id=%d nkeys=%d size=%d", \
820 cp->cc_reloid, cp->cc_indexoid, cp->id, \
821 cp->cc_nkeys, cp->cc_nbuckets); \
824 #define InitCatCache_DEBUG2
850 Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
869 #ifdef CATCACHE_STATS
906 for (
i = 0;
i < nkeys; ++
i)
941 elog(
DEBUG1,
"rehashing catalog cache id %d for %s; %d tups, %d buckets",
979 elog(
DEBUG1,
"rehashing catalog cache id %d for %s; %d lists, %d buckets",
1015 #define CatalogCacheInitializeCache_DEBUG1 \
1016 elog(DEBUG2, "CatalogCacheInitializeCache: cache @%p rel=%u", cache, \
1019 #define CatalogCacheInitializeCache_DEBUG2 \
1021 if (cache->cc_keyno[i] > 0) { \
1022 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d, %u", \
1023 i+1, cache->cc_nkeys, cache->cc_keyno[i], \
1024 TupleDescAttr(tupdesc, cache->cc_keyno[i] - 1)->atttypid); \
1026 elog(DEBUG2, "CatalogCacheInitializeCache: load %d/%d w/%d", \
1027 i+1, cache->cc_nkeys, cache->cc_keyno[i]); \
1031 #define CatalogCacheInitializeCache_DEBUG1
1032 #define CatalogCacheInitializeCache_DEBUG2
1092 keytype = attr->atttypid;
1094 Assert(attr->attnotnull);
1099 elog(
FATAL,
"sys attributes are not supported in caches");
1151 cache->
id != AMOID &&
1152 cache->
id != AMNAME)
1226 case AUTHMEMMEMROLE:
1338 #ifdef CATCACHE_STATS
1339 cache->cc_searches++;
1395 #ifdef CATCACHE_STATS
1406 #ifdef CATCACHE_STATS
1407 cache->cc_neg_hits++;
1496 hashValue, hashIndex);
1531 hashValue, hashIndex);
1554 #ifdef CATCACHE_STATS
1555 cache->cc_newloads++;
1593 #ifndef CATCACHE_FORCE_RELEASE
1660 List *
volatile ctlist;
1674 Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1676 #ifdef CATCACHE_STATS
1677 cache->cc_lsearches++;
1738 if (cl->
nkeys != nkeys)
1761 #ifdef CATCACHE_STATS
1810 ordered = (scandesc->
irel != NULL);
1857 hashValue, hashIndex);
1870 foreach(ctlist_item, ctlist)
1919 foreach(ctlist_item, ctlist)
1926 #ifndef CATCACHE_FORCE_RELEASE
1948 foreach(ctlist_item, ctlist)
2001 #ifndef CATCACHE_FORCE_RELEASE
2004 list->refcount == 0)
2021 return (alen == blen &&
2022 memcmp((
char *)
a->t_data,
2023 (
char *)
b->t_data, blen) == 0);
2062 #ifdef USE_ASSERT_CHECKING
2078 bool matches =
true;
2116 MAXIMUM_ALIGNOF + dtp->
t_len);
2124 (
const char *) dtp->
t_data,
2195 for (
i = 0;
i < nkeys;
i++)
2226 for (
i = 0;
i < nkeys;
i++)
2239 if (att->atttypid == NAMEOID)
2289 void (*
function) (
int,
uint32,
Oid,
void *),
2331 (*function) (ccp->
id, hashvalue, dbid,
context);
2339 if (newhashvalue != hashvalue)
2340 (*function) (ccp->
id, newhashvalue, dbid,
context);
2363 return psprintf(
"cache %s (%d), tuple %u/%u has count %d",
2381 return psprintf(
"cache %s (%d), list %p has count %d",
2382 list->my_cache->cc_relname,
list->my_cache->id,
#define AttributeNumberIsValid(attributeNumber)
#define Assert(condition)
#define PointerIsValid(pointer)
bool IsInplaceUpdateOid(Oid relid)
static bool chareqfast(Datum a, Datum b)
HeapTuple SearchCatCache2(CatCache *cache, Datum v1, Datum v2)
static bool int4eqfast(Datum a, Datum b)
HeapTuple SearchCatCache3(CatCache *cache, Datum v1, Datum v2, Datum v3)
void ReleaseCatCacheList(CatCList *list)
static bool equalTuple(HeapTuple a, HeapTuple b)
static void CatalogCacheInitializeCache(CatCache *cache)
static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, int nkeys, uint32 hashValue, Index hashIndex, Datum v1, Datum v2, Datum v3, Datum v4)
static bool int2eqfast(Datum a, Datum b)
static void ReleaseCatCacheWithOwner(HeapTuple tuple, ResourceOwner resowner)
static uint32 int4hashfast(Datum datum)
void InitCatCachePhase2(CatCache *cache, bool touch_index)
void ResetCatalogCaches(void)
static void ResOwnerReleaseCatCache(Datum res)
uint32 GetCatCacheHashValue(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
static char * ResOwnerPrintCatCache(Datum res)
static void RehashCatCache(CatCache *cp)
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
HeapTuple SearchCatCache4(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
static void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, SysScanDesc scandesc, Datum *arguments, uint32 hashValue, Index hashIndex)
static const ResourceOwnerDesc catcache_resowner_desc
static void ResOwnerReleaseCatCacheList(Datum res)
static void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
void PrepareToInvalidateCacheTuple(Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid, void *), void *context)
#define CatalogCacheInitializeCache_DEBUG1
static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *srckeys, Datum *dstkeys)
static HeapTuple SearchCatCacheInternal(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
CatCache * InitCatCache(int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
CatCList * SearchCatCacheList(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3)
static char * ResOwnerPrintCatCacheList(Datum res)
static void ReleaseCatCacheListWithOwner(CatCList *list, ResourceOwner resowner)
static CatCacheHeader * CacheHdr
static uint32 namehashfast(Datum datum)
void CreateCacheMemoryContext(void)
static void ResetCatalogCache(CatCache *cache)
static const ResourceOwnerDesc catlistref_resowner_desc
static bool IndexScanOK(CatCache *cache)
static void GetCCHashEqFuncs(Oid keytype, CCHashFN *hashfunc, RegProcedure *eqfunc, CCFastEqualFN *fasteqfunc)
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
static bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, const Datum *cachekeys, const Datum *searchkeys)
void CatCacheInvalidate(CatCache *cache, uint32 hashValue)
static void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
static bool nameeqfast(Datum a, Datum b)
static uint32 charhashfast(Datum datum)
static void RehashCatCacheLists(CatCache *cp)
HeapTuple SearchCatCache1(CatCache *cache, Datum v1)
#define InitCatCache_DEBUG2
static uint32 oidvectorhashfast(Datum datum)
static void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
static bool texteqfast(Datum a, Datum b)
static bool oidvectoreqfast(Datum a, Datum b)
void CatalogCacheFlushCatalog(Oid catId)
static uint32 int2hashfast(Datum datum)
#define CatalogCacheInitializeCache_DEBUG2
static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
#define HASH_INDEX(h, sz)
static uint32 texthashfast(Datum datum)
void ReleaseCatCache(HeapTuple tuple)
HeapTuple SearchCatCache(CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
uint32(* CCHashFN)(Datum datum)
bool(* CCFastEqualFN)(Datum a, Datum b)
Datum datumCopy(Datum value, bool typByVal, int typLen)
static void PGresult * res
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1)
#define DirectFunctionCall2(func, arg1, arg2)
#define DirectFunctionCall1(func, arg1)
void systable_endscan(SysScanDesc sysscan)
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
static uint32 murmurhash32(uint32 data)
static Datum hash_any(const unsigned char *k, int keylen)
Datum hashoidvector(PG_FUNCTION_ARGS)
Datum hashtext(PG_FUNCTION_ARGS)
HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
HeapTuple heap_copytuple(HeapTuple tuple)
void heap_freetuple(HeapTuple htup)
HeapTupleData * HeapTuple
HeapTupleHeaderData * HeapTupleHeader
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define HeapTupleHasExternal(tuple)
static Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define dlist_foreach(iter, lhead)
static void dlist_delete(dlist_node *node)
static void slist_init(slist_head *head)
static void dlist_push_head(dlist_head *head, dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static void slist_push_head(slist_head *head, slist_node *node)
#define slist_container(type, membername, ptr)
static void dlist_move_head(dlist_head *head, dlist_node *node)
#define slist_foreach(iter, lhead)
#define dlist_container(type, membername, ptr)
void index_close(Relation relation, LOCKMODE lockmode)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
void on_proc_exit(pg_on_exit_callback function, Datum arg)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
List * lappend(List *list, void *datum)
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
void LockRelationOid(Oid relid, LOCKMODE lockmode)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
void * MemoryContextAllocZero(MemoryContext context, Size size)
void * palloc_aligned(Size size, Size alignto, int flags)
MemoryContext CacheMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define IsBootstrapProcessingMode()
void namestrcpy(Name name, const char *str)
Datum oidvectoreq(PG_FUNCTION_ARGS)
FormData_pg_attribute * Form_pg_attribute
static uint32 pg_rotate_left32(uint32 word, int n)
#define PG_CACHE_LINE_SIZE
static int list_length(const List *l)
uint32 pg_prng_uint32(pg_prng_state *state)
pg_prng_state pg_global_prng_state
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Name DatumGetName(Datum X)
static char * DatumGetCString(Datum X)
static Datum NameGetDatum(const NameData *X)
static Pointer DatumGetPointer(Datum X)
static char DatumGetChar(Datum X)
static int16 DatumGetInt16(Datum X)
static int32 DatumGetInt32(Datum X)
char * psprintf(const char *fmt,...)
MemoryContextSwitchTo(old_ctx)
static int before(chr x, chr y)
#define RelationGetForm(relation)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationIsValid(relation)
bool criticalRelcachesBuilt
bool criticalSharedRelcachesBuilt
ResourceOwner CurrentResourceOwner
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerEnlarge(ResourceOwner owner)
#define RELEASE_PRIO_CATCACHE_LIST_REFS
@ RESOURCE_RELEASE_AFTER_LOCKS
#define RELEASE_PRIO_CATCACHE_REFS
#define BTEqualStrategyNumber
StrategyNumber sk_strategy
CCHashFN cc_hashfunc[CATCACHE_MAXKEYS]
int cc_keyno[CATCACHE_MAXKEYS]
CCFastEqualFN cc_fastequal[CATCACHE_MAXKEYS]
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Datum keys[CATCACHE_MAXKEYS]
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Datum keys[CATCACHE_MAXKEYS]
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc)
struct TupleDescData * TupleDesc
#define TupleDescAttr(tupdesc, i)
Datum texteq(PG_FUNCTION_ARGS)
bool IsTransactionState(void)