PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
catcache.h File Reference
#include "access/htup.h"
#include "access/skey.h"
#include "lib/ilist.h"
#include "utils/relcache.h"
Include dependency graph for catcache.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  catcache
 
struct  catctup
 
struct  catclist
 
struct  catcacheheader
 

Macros

#define CATCACHE_MAXKEYS   4
 
#define CT_MAGIC   0x57261502
 
#define CL_MAGIC   0x52765103
 

Typedefs

typedef struct catcache CatCache
 
typedef struct catctup CatCTup
 
typedef struct catclist CatCList
 
typedef struct catcacheheader CatCacheHeader
 

Functions

void CreateCacheMemoryContext (void)
 
CatCacheInitCatCache (int id, Oid reloid, Oid indexoid, int nkeys, const int *key, int nbuckets)
 
void InitCatCachePhase2 (CatCache *cache, bool touch_index)
 
HeapTuple SearchCatCache (CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
 
void ReleaseCatCache (HeapTuple tuple)
 
uint32 GetCatCacheHashValue (CatCache *cache, Datum v1, Datum v2, Datum v3, Datum v4)
 
CatCListSearchCatCacheList (CatCache *cache, int nkeys, Datum v1, Datum v2, Datum v3, Datum v4)
 
void ReleaseCatCacheList (CatCList *list)
 
void ResetCatalogCaches (void)
 
void CatalogCacheFlushCatalog (Oid catId)
 
void CatCacheInvalidate (CatCache *cache, uint32 hashValue)
 
void PrepareToInvalidateCacheTuple (Relation relation, HeapTuple tuple, HeapTuple newtuple, void(*function)(int, uint32, Oid))
 
void PrintCatCacheLeakWarning (HeapTuple tuple)
 
void PrintCatCacheListLeakWarning (CatCList *list)
 

Variables

PGDLLIMPORT MemoryContext CacheMemoryContext
 

Macro Definition Documentation

#define CATCACHE_MAXKEYS   4
#define CL_MAGIC   0x52765103

Definition at line 123 of file catcache.h.

Referenced by ReleaseCatCacheList(), and SearchCatCacheList().

#define CT_MAGIC   0x57261502

Definition at line 81 of file catcache.h.

Referenced by CatalogCacheCreateEntry(), PrintCatCacheLeakWarning(), and ReleaseCatCache().

Typedef Documentation

Function Documentation

void CatalogCacheFlushCatalog ( Oid  catId)

Definition at line 610 of file catcache.c.

References CACHE1_elog, CACHE2_elog, CallSyscacheCallbacks(), catcache::cc_reloid, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, catcache::id, ResetCatalogCache(), slist_container, and slist_foreach.

Referenced by LocalExecuteInvalidationMessage().

611 {
612  slist_iter iter;
613 
614  CACHE2_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
615 
617  {
618  CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
619 
620  /* Does this cache store tuples of the target catalog? */
621  if (cache->cc_reloid == catId)
622  {
623  /* Yes, so flush all its contents */
624  ResetCatalogCache(cache);
625 
626  /* Tell inval.c to call syscache callbacks for this cache */
627  CallSyscacheCallbacks(cache->id, 0);
628  }
629  }
630 
631  CACHE1_elog(DEBUG2, "end of CatalogCacheFlushCatalog call");
632 }
static void ResetCatalogCache(CatCache *cache)
Definition: catcache.c:533
static CatCacheHeader * CacheHdr
Definition: catcache.c:73
slist_node * cur
Definition: ilist.h:226
int id
Definition: catcache.h:39
Oid cc_reloid
Definition: catcache.h:42
#define DEBUG2
Definition: elog.h:24
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
void CallSyscacheCallbacks(int cacheid, uint32 hashvalue)
Definition: inval.c:1450
#define CACHE1_elog(a, b)
Definition: catcache.c:64
slist_head ch_caches
Definition: catcache.h:161
#define slist_foreach(iter, lhead)
Definition: ilist.h:700
#define CACHE2_elog(a, b, c)
Definition: catcache.c:65
void CatCacheInvalidate ( CatCache cache,
uint32  hashValue 
)

Definition at line 443 of file catcache.c.

References Assert, catctup::c_list, CACHE1_elog, CatCacheRemoveCList(), CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_lists, catcache::cc_nbuckets, dlist_mutable_iter::cur, catctup::dead, catclist::dead, DEBUG2, dlist_container, dlist_foreach_modify, HASH_INDEX, catctup::hash_value, catctup::refcount, and catclist::refcount.

Referenced by SysCacheInvalidate().

444 {
445  Index hashIndex;
446  dlist_mutable_iter iter;
447 
448  CACHE1_elog(DEBUG2, "CatCacheInvalidate: called");
449 
450  /*
451  * We don't bother to check whether the cache has finished initialization
452  * yet; if not, there will be no entries in it so no problem.
453  */
454 
455  /*
456  * Invalidate *all* CatCLists in this cache; it's too hard to tell which
457  * searches might still be correct, so just zap 'em all.
458  */
459  dlist_foreach_modify(iter, &cache->cc_lists)
460  {
461  CatCList *cl = dlist_container(CatCList, cache_elem, iter.cur);
462 
463  if (cl->refcount > 0)
464  cl->dead = true;
465  else
466  CatCacheRemoveCList(cache, cl);
467  }
468 
469  /*
470  * inspect the proper hash bucket for tuple matches
471  */
472  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
473  dlist_foreach_modify(iter, &cache->cc_bucket[hashIndex])
474  {
475  CatCTup *ct = dlist_container(CatCTup, cache_elem, iter.cur);
476 
477  if (hashValue == ct->hash_value)
478  {
479  if (ct->refcount > 0 ||
480  (ct->c_list && ct->c_list->refcount > 0))
481  {
482  ct->dead = true;
483  /* list, if any, was marked dead above */
484  Assert(ct->c_list == NULL || ct->c_list->dead);
485  }
486  else
487  CatCacheRemoveCTup(cache, ct);
488  CACHE1_elog(DEBUG2, "CatCacheInvalidate: invalidated");
489 #ifdef CATCACHE_STATS
490  cache->cc_invals++;
491 #endif
492  /* could be multiple matches, so keep looking! */
493  }
494  }
495 }
dlist_node * cur
Definition: ilist.h:180
uint32 hash_value
Definition: catcache.h:115
#define dlist_foreach_modify(iter, lhead)
Definition: ilist.h:524
#define HASH_INDEX(h, sz)
Definition: catcache.c:49
dlist_head * cc_bucket
Definition: catcache.h:55
bool dead
Definition: catcache.h:149
dlist_head cc_lists
Definition: catcache.h:54
struct catclist * c_list
Definition: catcache.h:98
#define dlist_container(type, membername, ptr)
Definition: ilist.h:477
#define DEBUG2
Definition: elog.h:24
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Definition: catcache.c:391
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition: catcache.c:354
unsigned int Index
Definition: c.h:359
#define CACHE1_elog(a, b)
Definition: catcache.c:64
#define Assert(condition)
Definition: c.h:664
int cc_nbuckets
Definition: catcache.h:47
int refcount
Definition: catcache.h:112
int refcount
Definition: catcache.h:148
bool dead
Definition: catcache.h:113
void CreateCacheMemoryContext ( void  )

Definition at line 511 of file catcache.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), CacheMemoryContext, and TopMemoryContext.

Referenced by assign_record_type_typmod(), BuildEventTriggerCache(), init_ts_config_cache(), InitCatCache(), InitializeAttoptCache(), InitializeRelfilenodeMap(), InitializeTableSpaceCache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), LookupOpclassInfo(), RelationBuildLocalRelation(), and RelationCacheInitialize().

512 {
513  /*
514  * Purely for paranoia, check that context doesn't exist; caller probably
515  * did so already.
516  */
517  if (!CacheMemoryContext)
519  "CacheMemoryContext",
521 }
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
MemoryContext TopMemoryContext
Definition: mcxt.c:43
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
uint32 GetCatCacheHashValue ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1285 of file catcache.c.

References CatalogCacheComputeHashValue(), CatalogCacheInitializeCache(), CATCACHE_MAXKEYS, catcache::cc_nkeys, catcache::cc_skey, catcache::cc_tupdesc, and ScanKeyData::sk_argument.

Referenced by GetSysCacheHashValue().

1290 {
1291  ScanKeyData cur_skey[CATCACHE_MAXKEYS];
1292 
1293  /*
1294  * one-time startup overhead for each cache
1295  */
1296  if (cache->cc_tupdesc == NULL)
1298 
1299  /*
1300  * initialize the search key information
1301  */
1302  memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
1303  cur_skey[0].sk_argument = v1;
1304  cur_skey[1].sk_argument = v2;
1305  cur_skey[2].sk_argument = v3;
1306  cur_skey[3].sk_argument = v4;
1307 
1308  /*
1309  * calculate the hash value
1310  */
1311  return CatalogCacheComputeHashValue(cache, cache->cc_nkeys, cur_skey);
1312 }
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:812
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, ScanKey cur_skey)
Definition: catcache.c:174
#define CATCACHE_MAXKEYS
Definition: catcache.h:35
int cc_nkeys
Definition: catcache.h:48
TupleDesc cc_tupdesc
Definition: catcache.h:45
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Definition: catcache.h:51
Datum sk_argument
Definition: skey.h:72
CatCache* InitCatCache ( int  id,
Oid  reloid,
Oid  indexoid,
int  nkeys,
const int *  key,
int  nbuckets 
)

Definition at line 654 of file catcache.c.

References Assert, CacheMemoryContext, catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_key, catcache::cc_nbuckets, catcache::cc_next, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_relisshared, catcache::cc_relname, catcache::cc_reloid, catcache::cc_tupdesc, catcacheheader::ch_caches, catcacheheader::ch_ntup, CreateCacheMemoryContext(), i, catcache::id, InitCatCache_DEBUG2, MemoryContextSwitchTo(), on_proc_exit(), palloc(), palloc0(), slist_init(), and slist_push_head().

Referenced by InitCatalogCache().

660 {
661  CatCache *cp;
662  MemoryContext oldcxt;
663  int i;
664 
665  /*
666  * nbuckets is the initial number of hash buckets to use in this catcache.
667  * It will be enlarged later if it becomes too full.
668  *
669  * nbuckets must be a power of two. We check this via Assert rather than
670  * a full runtime check because the values will be coming from constant
671  * tables.
672  *
673  * If you're confused by the power-of-two check, see comments in
674  * bitmapset.c for an explanation.
675  */
676  Assert(nbuckets > 0 && (nbuckets & -nbuckets) == nbuckets);
677 
678  /*
679  * first switch to the cache context so our allocations do not vanish at
680  * the end of a transaction
681  */
682  if (!CacheMemoryContext)
684 
686 
687  /*
688  * if first time through, initialize the cache group header
689  */
690  if (CacheHdr == NULL)
691  {
694  CacheHdr->ch_ntup = 0;
695 #ifdef CATCACHE_STATS
696  /* set up to dump stats at backend exit */
697  on_proc_exit(CatCachePrintStats, 0);
698 #endif
699  }
700 
701  /*
702  * allocate a new cache structure
703  *
704  * Note: we rely on zeroing to initialize all the dlist headers correctly
705  */
706  cp = (CatCache *) palloc0(sizeof(CatCache));
707  cp->cc_bucket = palloc0(nbuckets * sizeof(dlist_head));
708 
709  /*
710  * initialize the cache's relation information for the relation
711  * corresponding to this cache, and initialize some of the new cache's
712  * other internal fields. But don't open the relation yet.
713  */
714  cp->id = id;
715  cp->cc_relname = "(not known yet)";
716  cp->cc_reloid = reloid;
717  cp->cc_indexoid = indexoid;
718  cp->cc_relisshared = false; /* temporary */
719  cp->cc_tupdesc = (TupleDesc) NULL;
720  cp->cc_ntup = 0;
721  cp->cc_nbuckets = nbuckets;
722  cp->cc_nkeys = nkeys;
723  for (i = 0; i < nkeys; ++i)
724  cp->cc_key[i] = key[i];
725 
726  /*
727  * new cache is initialized as far as we can go for now. print some
728  * debugging information, if appropriate.
729  */
731 
732  /*
733  * add completed cache to top of group header's list
734  */
736 
737  /*
738  * back to the old context before we return...
739  */
740  MemoryContextSwitchTo(oldcxt);
741 
742  return cp;
743 }
static CatCacheHeader * CacheHdr
Definition: catcache.c:73
void on_proc_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:292
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
dlist_head * cc_bucket
Definition: catcache.h:55
static void slist_push_head(slist_head *head, slist_node *node)
Definition: ilist.h:574
slist_node cc_next
Definition: catcache.h:40
int id
Definition: catcache.h:39
bool cc_relisshared
Definition: catcache.h:44
Oid cc_indexoid
Definition: catcache.h:43
static void slist_init(slist_head *head)
Definition: ilist.h:554
Oid cc_reloid
Definition: catcache.h:42
int cc_key[CATCACHE_MAXKEYS]
Definition: catcache.h:49
int cc_nkeys
Definition: catcache.h:48
TupleDesc cc_tupdesc
Definition: catcache.h:45
int cc_ntup
Definition: catcache.h:46
void * palloc0(Size size)
Definition: mcxt.c:877
struct tupleDesc * TupleDesc
slist_head ch_caches
Definition: catcache.h:161
#define InitCatCache_DEBUG2
Definition: catcache.c:650
#define Assert(condition)
Definition: c.h:664
int cc_nbuckets
Definition: catcache.h:47
void CreateCacheMemoryContext(void)
Definition: catcache.c:511
const char * cc_relname
Definition: catcache.h:41
void * palloc(Size size)
Definition: mcxt.c:848
int i
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
void InitCatCachePhase2 ( CatCache cache,
bool  touch_index 
)

Definition at line 924 of file catcache.c.

References AccessShareLock, AMNAME, AMOID, Assert, CatalogCacheInitializeCache(), catcache::cc_indexoid, catcache::cc_reloid, catcache::cc_tupdesc, catcache::id, index_close(), index_open(), LockRelationOid(), RelationData::rd_index, and UnlockRelationOid().

Referenced by InitCatalogCachePhase2(), and SysCacheGetAttr().

925 {
926  if (cache->cc_tupdesc == NULL)
928 
929  if (touch_index &&
930  cache->id != AMOID &&
931  cache->id != AMNAME)
932  {
933  Relation idesc;
934 
935  /*
936  * We must lock the underlying catalog before opening the index to
937  * avoid deadlock, since index_open could possibly result in reading
938  * this same catalog, and if anyone else is exclusive-locking this
939  * catalog and index they'll be doing it in that order.
940  */
942  idesc = index_open(cache->cc_indexoid, AccessShareLock);
943 
944  /*
945  * While we've got the index open, let's check that it's unique (and
946  * not just deferrable-unique, thank you very much). This is just to
947  * catch thinkos in definitions of new catcaches, so we don't worry
948  * about the pg_am indexes not getting tested.
949  */
950  Assert(idesc->rd_index->indisunique &&
951  idesc->rd_index->indimmediate);
952 
955  }
956 }
Definition: syscache.h:36
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:182
#define AccessShareLock
Definition: lockdefs.h:36
int id
Definition: catcache.h:39
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:812
Oid cc_indexoid
Definition: catcache.h:43
Form_pg_index rd_index
Definition: rel.h:159
Oid cc_reloid
Definition: catcache.h:42
TupleDesc cc_tupdesc
Definition: catcache.h:45
#define Assert(condition)
Definition: c.h:664
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:105
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
void PrepareToInvalidateCacheTuple ( Relation  relation,
HeapTuple  tuple,
HeapTuple  newtuple,
void(*)(int, uint32, Oid function 
)

Definition at line 1782 of file catcache.c.

References Assert, CACHE1_elog, CatalogCacheComputeTupleHashValue(), CatalogCacheInitializeCache(), catcache::cc_relisshared, catcache::cc_reloid, catcache::cc_tupdesc, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, HeapTupleIsValid, catcache::id, MyDatabaseId, PointerIsValid, RelationGetRelid, RelationIsValid, slist_container, and slist_foreach.

Referenced by CacheInvalidateHeapTuple().

1786 {
1787  slist_iter iter;
1788  Oid reloid;
1789 
1790  CACHE1_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called");
1791 
1792  /*
1793  * sanity checks
1794  */
1795  Assert(RelationIsValid(relation));
1796  Assert(HeapTupleIsValid(tuple));
1797  Assert(PointerIsValid(function));
1798  Assert(CacheHdr != NULL);
1799 
1800  reloid = RelationGetRelid(relation);
1801 
1802  /* ----------------
1803  * for each cache
1804  * if the cache contains tuples from the specified relation
1805  * compute the tuple's hash value(s) in this cache,
1806  * and call the passed function to register the information.
1807  * ----------------
1808  */
1809 
1811  {
1812  CatCache *ccp = slist_container(CatCache, cc_next, iter.cur);
1813  uint32 hashvalue;
1814  Oid dbid;
1815 
1816  if (ccp->cc_reloid != reloid)
1817  continue;
1818 
1819  /* Just in case cache hasn't finished initialization yet... */
1820  if (ccp->cc_tupdesc == NULL)
1822 
1823  hashvalue = CatalogCacheComputeTupleHashValue(ccp, tuple);
1824  dbid = ccp->cc_relisshared ? (Oid) 0 : MyDatabaseId;
1825 
1826  (*function) (ccp->id, hashvalue, dbid);
1827 
1828  if (newtuple)
1829  {
1830  uint32 newhashvalue;
1831 
1832  newhashvalue = CatalogCacheComputeTupleHashValue(ccp, newtuple);
1833 
1834  if (newhashvalue != hashvalue)
1835  (*function) (ccp->id, newhashvalue, dbid);
1836  }
1837  }
1838 }
static CatCacheHeader * CacheHdr
Definition: catcache.c:73
slist_node * cur
Definition: ilist.h:226
int id
Definition: catcache.h:39
unsigned int Oid
Definition: postgres_ext.h:31
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:812
bool cc_relisshared
Definition: catcache.h:44
Oid cc_reloid
Definition: catcache.h:42
#define RelationIsValid(relation)
Definition: rel.h:389
TupleDesc cc_tupdesc
Definition: catcache.h:45
#define DEBUG2
Definition: elog.h:24
unsigned int uint32
Definition: c.h:258
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
Oid MyDatabaseId
Definition: globals.c:77
#define CACHE1_elog(a, b)
Definition: catcache.c:64
slist_head ch_caches
Definition: catcache.h:161
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
Definition: catcache.c:227
#define slist_foreach(iter, lhead)
Definition: ilist.h:700
#define PointerIsValid(pointer)
Definition: c.h:520
#define RelationGetRelid(relation)
Definition: rel.h:416
void PrintCatCacheLeakWarning ( HeapTuple  tuple)

Definition at line 1846 of file catcache.c.

References Assert, catcache::cc_relname, catctup::ct_magic, CT_MAGIC, elog, catcache::id, ItemPointerGetBlockNumber, ItemPointerGetOffsetNumber, catctup::my_cache, offsetof, catctup::refcount, HeapTupleData::t_self, and WARNING.

Referenced by ResourceOwnerReleaseInternal().

1847 {
1848  CatCTup *ct = (CatCTup *) (((char *) tuple) -
1849  offsetof(CatCTup, tuple));
1850 
1851  /* Safety check to ensure we were handed a cache entry */
1852  Assert(ct->ct_magic == CT_MAGIC);
1853 
1854  elog(WARNING, "cache reference leak: cache %s (%d), tuple %u/%u has count %d",
1855  ct->my_cache->cc_relname, ct->my_cache->id,
1856  ItemPointerGetBlockNumber(&(tuple->t_self)),
1858  ct->refcount);
1859 }
CatCache * my_cache
Definition: catcache.h:82
#define CT_MAGIC
Definition: catcache.h:81
int id
Definition: catcache.h:39
ItemPointerData t_self
Definition: htup.h:65
#define WARNING
Definition: elog.h:40
#define Assert(condition)
Definition: c.h:664
int refcount
Definition: catcache.h:112
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:95
const char * cc_relname
Definition: catcache.h:41
#define elog
Definition: elog.h:219
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:76
#define offsetof(type, field)
Definition: c.h:549
int ct_magic
Definition: catcache.h:80
void PrintCatCacheListLeakWarning ( CatCList list)

Definition at line 1862 of file catcache.c.

References catcache::cc_relname, elog, catcache::id, catclist::my_cache, catclist::refcount, and WARNING.

Referenced by ResourceOwnerReleaseInternal().

1863 {
1864  elog(WARNING, "cache reference leak: cache %s (%d), list %p has count %d",
1865  list->my_cache->cc_relname, list->my_cache->id,
1866  list, list->refcount);
1867 }
int id
Definition: catcache.h:39
#define WARNING
Definition: elog.h:40
CatCache * my_cache
Definition: catcache.h:124
const char * cc_relname
Definition: catcache.h:41
#define elog
Definition: elog.h:219
int refcount
Definition: catcache.h:148
void ReleaseCatCache ( HeapTuple  tuple)

Definition at line 1253 of file catcache.c.

References Assert, catctup::c_list, CatCacheRemoveCTup(), catctup::ct_magic, CT_MAGIC, CurrentResourceOwner, catctup::dead, catctup::my_cache, offsetof, catctup::refcount, catclist::refcount, ResourceOwnerForgetCatCacheRef(), and catctup::tuple.

Referenced by ReleaseSysCache(), and ResourceOwnerReleaseInternal().

1254 {
1255  CatCTup *ct = (CatCTup *) (((char *) tuple) -
1256  offsetof(CatCTup, tuple));
1257 
1258  /* Safety checks to ensure we were handed a cache entry */
1259  Assert(ct->ct_magic == CT_MAGIC);
1260  Assert(ct->refcount > 0);
1261 
1262  ct->refcount--;
1264 
1265  if (
1266 #ifndef CATCACHE_FORCE_RELEASE
1267  ct->dead &&
1268 #endif
1269  ct->refcount == 0 &&
1270  (ct->c_list == NULL || ct->c_list->refcount == 0))
1271  CatCacheRemoveCTup(ct->my_cache, ct);
1272 }
CatCache * my_cache
Definition: catcache.h:82
#define CT_MAGIC
Definition: catcache.h:81
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition: resowner.c:958
struct catclist * c_list
Definition: catcache.h:98
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition: catcache.c:354
#define Assert(condition)
Definition: c.h:664
int refcount
Definition: catcache.h:112
HeapTupleData tuple
Definition: catcache.h:116
int refcount
Definition: catcache.h:148
#define offsetof(type, field)
Definition: c.h:549
int ct_magic
Definition: catcache.h:80
bool dead
Definition: catcache.h:113
void ReleaseCatCacheList ( CatCList list)

Definition at line 1601 of file catcache.c.

References Assert, CatCacheRemoveCList(), catclist::cl_magic, CL_MAGIC, CurrentResourceOwner, catclist::dead, catclist::my_cache, catclist::refcount, and ResourceOwnerForgetCatCacheListRef().

Referenced by AddEnumLabel(), blvalidate(), brinvalidate(), btvalidate(), ginvalidate(), gistvalidate(), hashvalidate(), opfamily_can_sort_type(), RenameEnumLabel(), ResourceOwnerReleaseInternal(), sepgsql_relation_drop(), and spgvalidate().

1602 {
1603  /* Safety checks to ensure we were handed a cache entry */
1604  Assert(list->cl_magic == CL_MAGIC);
1605  Assert(list->refcount > 0);
1606  list->refcount--;
1608 
1609  if (
1610 #ifndef CATCACHE_FORCE_RELEASE
1611  list->dead &&
1612 #endif
1613  list->refcount == 0)
1614  CatCacheRemoveCList(list->my_cache, list);
1615 }
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
int cl_magic
Definition: catcache.h:122
bool dead
Definition: catcache.h:149
static void CatCacheRemoveCList(CatCache *cache, CatCList *cl)
Definition: catcache.c:391
#define CL_MAGIC
Definition: catcache.h:123
CatCache * my_cache
Definition: catcache.h:124
void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition: resowner.c:993
#define Assert(condition)
Definition: c.h:664
int refcount
Definition: catcache.h:148
void ResetCatalogCaches ( void  )

Definition at line 580 of file catcache.c.

References CACHE1_elog, catcacheheader::ch_caches, slist_iter::cur, DEBUG2, ResetCatalogCache(), slist_container, and slist_foreach.

Referenced by InvalidateSystemCaches().

581 {
582  slist_iter iter;
583 
584  CACHE1_elog(DEBUG2, "ResetCatalogCaches called");
585 
587  {
588  CatCache *cache = slist_container(CatCache, cc_next, iter.cur);
589 
590  ResetCatalogCache(cache);
591  }
592 
593  CACHE1_elog(DEBUG2, "end of ResetCatalogCaches call");
594 }
static void ResetCatalogCache(CatCache *cache)
Definition: catcache.c:533
static CatCacheHeader * CacheHdr
Definition: catcache.c:73
slist_node * cur
Definition: ilist.h:226
#define DEBUG2
Definition: elog.h:24
#define slist_container(type, membername, ptr)
Definition: ilist.h:674
#define CACHE1_elog(a, b)
Definition: catcache.c:64
slist_head ch_caches
Definition: catcache.h:161
#define slist_foreach(iter, lhead)
Definition: ilist.h:700
HeapTuple SearchCatCache ( CatCache cache,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1039 of file catcache.c.

References AccessShareLock, Assert, build_dummy_tuple(), CACHE3_elog, CACHE4_elog, catctup::cache_elem, CatalogCacheComputeHashValue(), CatalogCacheCreateEntry(), CatalogCacheInitializeCache(), CATCACHE_MAXKEYS, catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_nbuckets, catcache::cc_nkeys, catcache::cc_ntup, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcache::cc_tupdesc, catcacheheader::ch_ntup, dlist_iter::cur, CurrentResourceOwner, catctup::dead, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), HASH_INDEX, catctup::hash_value, heap_close, heap_freetuple(), heap_open(), HeapKeyTest, HeapTupleIsValid, IndexScanOK(), IsBootstrapProcessingMode, IsTransactionState(), catctup::negative, catctup::refcount, ResourceOwnerEnlargeCatCacheRefs(), ResourceOwnerRememberCatCacheRef(), ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), and catctup::tuple.

Referenced by SearchSysCache().

1044 {
1045  ScanKeyData cur_skey[CATCACHE_MAXKEYS];
1046  uint32 hashValue;
1047  Index hashIndex;
1048  dlist_iter iter;
1049  dlist_head *bucket;
1050  CatCTup *ct;
1051  Relation relation;
1052  SysScanDesc scandesc;
1053  HeapTuple ntp;
1054 
1055  /* Make sure we're in an xact, even if this ends up being a cache hit */
1057 
1058  /*
1059  * one-time startup overhead for each cache
1060  */
1061  if (cache->cc_tupdesc == NULL)
1063 
1064 #ifdef CATCACHE_STATS
1065  cache->cc_searches++;
1066 #endif
1067 
1068  /*
1069  * initialize the search key information
1070  */
1071  memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
1072  cur_skey[0].sk_argument = v1;
1073  cur_skey[1].sk_argument = v2;
1074  cur_skey[2].sk_argument = v3;
1075  cur_skey[3].sk_argument = v4;
1076 
1077  /*
1078  * find the hash bucket in which to look for the tuple
1079  */
1080  hashValue = CatalogCacheComputeHashValue(cache, cache->cc_nkeys, cur_skey);
1081  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1082 
1083  /*
1084  * scan the hash bucket until we find a match or exhaust our tuples
1085  *
1086  * Note: it's okay to use dlist_foreach here, even though we modify the
1087  * dlist within the loop, because we don't continue the loop afterwards.
1088  */
1089  bucket = &cache->cc_bucket[hashIndex];
1090  dlist_foreach(iter, bucket)
1091  {
1092  bool res;
1093 
1094  ct = dlist_container(CatCTup, cache_elem, iter.cur);
1095 
1096  if (ct->dead)
1097  continue; /* ignore dead entries */
1098 
1099  if (ct->hash_value != hashValue)
1100  continue; /* quickly skip entry if wrong hash val */
1101 
1102  /*
1103  * see if the cached tuple matches our key.
1104  */
1105  HeapKeyTest(&ct->tuple,
1106  cache->cc_tupdesc,
1107  cache->cc_nkeys,
1108  cur_skey,
1109  res);
1110  if (!res)
1111  continue;
1112 
1113  /*
1114  * We found a match in the cache. Move it to the front of the list
1115  * for its hashbucket, in order to speed subsequent searches. (The
1116  * most frequently accessed elements in any hashbucket will tend to be
1117  * near the front of the hashbucket's list.)
1118  */
1119  dlist_move_head(bucket, &ct->cache_elem);
1120 
1121  /*
1122  * If it's a positive entry, bump its refcount and return it. If it's
1123  * negative, we can report failure to the caller.
1124  */
1125  if (!ct->negative)
1126  {
1128  ct->refcount++;
1130 
1131  CACHE3_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d",
1132  cache->cc_relname, hashIndex);
1133 
1134 #ifdef CATCACHE_STATS
1135  cache->cc_hits++;
1136 #endif
1137 
1138  return &ct->tuple;
1139  }
1140  else
1141  {
1142  CACHE3_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d",
1143  cache->cc_relname, hashIndex);
1144 
1145 #ifdef CATCACHE_STATS
1146  cache->cc_neg_hits++;
1147 #endif
1148 
1149  return NULL;
1150  }
1151  }
1152 
1153  /*
1154  * Tuple was not found in cache, so we have to try to retrieve it directly
1155  * from the relation. If found, we will add it to the cache; if not
1156  * found, we will add a negative cache entry instead.
1157  *
1158  * NOTE: it is possible for recursive cache lookups to occur while reading
1159  * the relation --- for example, due to shared-cache-inval messages being
1160  * processed during heap_open(). This is OK. It's even possible for one
1161  * of those lookups to find and enter the very same tuple we are trying to
1162  * fetch here. If that happens, we will enter a second copy of the tuple
1163  * into the cache. The first copy will never be referenced again, and
1164  * will eventually age out of the cache, so there's no functional problem.
1165  * This case is rare enough that it's not worth expending extra cycles to
1166  * detect.
1167  */
1168  relation = heap_open(cache->cc_reloid, AccessShareLock);
1169 
1170  scandesc = systable_beginscan(relation,
1171  cache->cc_indexoid,
1172  IndexScanOK(cache, cur_skey),
1173  NULL,
1174  cache->cc_nkeys,
1175  cur_skey);
1176 
1177  ct = NULL;
1178 
1179  while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
1180  {
1181  ct = CatalogCacheCreateEntry(cache, ntp,
1182  hashValue, hashIndex,
1183  false);
1184  /* immediately set the refcount to 1 */
1186  ct->refcount++;
1188  break; /* assume only one match */
1189  }
1190 
1191  systable_endscan(scandesc);
1192 
1193  heap_close(relation, AccessShareLock);
1194 
1195  /*
1196  * If tuple was not found, we need to build a negative cache entry
1197  * containing a fake tuple. The fake tuple has the correct key columns,
1198  * but nulls everywhere else.
1199  *
1200  * In bootstrap mode, we don't build negative entries, because the cache
1201  * invalidation mechanism isn't alive and can't clear them if the tuple
1202  * gets created later. (Bootstrap doesn't do UPDATEs, so it doesn't need
1203  * cache inval for that.)
1204  */
1205  if (ct == NULL)
1206  {
1208  return NULL;
1209 
1210  ntp = build_dummy_tuple(cache, cache->cc_nkeys, cur_skey);
1211  ct = CatalogCacheCreateEntry(cache, ntp,
1212  hashValue, hashIndex,
1213  true);
1214  heap_freetuple(ntp);
1215 
1216  CACHE4_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1217  cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1218  CACHE3_elog(DEBUG2, "SearchCatCache(%s): put neg entry in bucket %d",
1219  cache->cc_relname, hashIndex);
1220 
1221  /*
1222  * We are not returning the negative entry to the caller, so leave its
1223  * refcount zero.
1224  */
1225 
1226  return NULL;
1227  }
1228 
1229  CACHE4_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples",
1230  cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup);
1231  CACHE3_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d",
1232  cache->cc_relname, hashIndex);
1233 
1234 #ifdef CATCACHE_STATS
1235  cache->cc_newloads++;
1236 #endif
1237 
1238  return &ct->tuple;
1239 }
void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
Definition: resowner.c:949
uint32 hash_value
Definition: catcache.h:115
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define CACHE3_elog(a, b, c, d)
Definition: catcache.c:66
static CatCacheHeader * CacheHdr
Definition: catcache.c:73
#define HASH_INDEX(h, sz)
Definition: catcache.c:49
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, uint32 hashValue, Index hashIndex, bool negative)
Definition: catcache.c:1624
#define dlist_foreach(iter, lhead)
Definition: ilist.h:507
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
dlist_head * cc_bucket
Definition: catcache.h:55
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:812
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
Oid cc_indexoid
Definition: catcache.h:43
#define dlist_container(type, membername, ptr)
Definition: ilist.h:477
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, ScanKey cur_skey)
Definition: catcache.c:174
#define CATCACHE_MAXKEYS
Definition: catcache.h:35
Oid cc_reloid
Definition: catcache.h:42
int cc_nkeys
Definition: catcache.h:48
TupleDesc cc_tupdesc
Definition: catcache.h:45
int cc_ntup
Definition: catcache.h:46
#define DEBUG2
Definition: elog.h:24
unsigned int uint32
Definition: c.h:258
#define CACHE4_elog(a, b, c, d, e)
Definition: catcache.c:67
static bool IndexScanOK(CatCache *cache, ScanKey cur_skey)
Definition: catcache.c:975
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
dlist_node * cur
Definition: ilist.h:161
unsigned int Index
Definition: c.h:359
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
static HeapTuple build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
Definition: catcache.c:1690
int cc_nbuckets
Definition: catcache.h:47
int refcount
Definition: catcache.h:112
bool IsTransactionState(void)
Definition: xact.c:351
const char * cc_relname
Definition: catcache.h:41
static void dlist_move_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:385
dlist_node cache_elem
Definition: catcache.h:89
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:368
bool negative
Definition: catcache.h:114
HeapTupleData tuple
Definition: catcache.h:116
#define HeapKeyTest(tuple, tupdesc, nkeys, keys, result)
Definition: valid.h:22
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Definition: catcache.h:51
Datum sk_argument
Definition: skey.h:72
void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner)
Definition: resowner.c:938
bool dead
Definition: catcache.h:113
CatCList* SearchCatCacheList ( CatCache cache,
int  nkeys,
Datum  v1,
Datum  v2,
Datum  v3,
Datum  v4 
)

Definition at line 1325 of file catcache.c.

References AccessShareLock, Assert, build_dummy_tuple(), catctup::c_list, CACHE2_elog, CACHE3_elog, catclist::cache_elem, CacheMemoryContext, CatalogCacheComputeHashValue(), CatalogCacheComputeTupleHashValue(), CatalogCacheCreateEntry(), CatalogCacheInitializeCache(), CATCACHE_MAXKEYS, CatCacheRemoveCTup(), catcache::cc_bucket, catcache::cc_indexoid, catcache::cc_lists, catcache::cc_nbuckets, catcache::cc_relname, catcache::cc_reloid, catcache::cc_skey, catcache::cc_tupdesc, catclist::cl_magic, CL_MAGIC, dlist_iter::cur, CurrentResourceOwner, catctup::dead, catclist::dead, DEBUG2, dlist_container, dlist_foreach, dlist_move_head(), dlist_push_head(), HASH_INDEX, catctup::hash_value, catclist::hash_value, heap_close, heap_copytuple_with_tuple(), heap_freetuple(), heap_open(), HeapKeyTest, HeapTupleIsValid, i, IndexScanOK(), SysScanDescData::irel, ItemPointerEquals(), lappend(), lfirst, list_length(), catclist::members, MemoryContextSwitchTo(), catclist::my_cache, catclist::n_members, catctup::negative, NIL, catclist::nkeys, offsetof, catclist::ordered, palloc(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, catctup::refcount, catclist::refcount, ResourceOwnerEnlargeCatCacheListRefs(), ResourceOwnerRememberCatCacheListRef(), ScanKeyData::sk_argument, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, catctup::tuple, and catclist::tuple.

Referenced by SearchSysCacheList().

1331 {
1332  ScanKeyData cur_skey[CATCACHE_MAXKEYS];
1333  uint32 lHashValue;
1334  dlist_iter iter;
1335  CatCList *cl;
1336  CatCTup *ct;
1337  List *volatile ctlist;
1338  ListCell *ctlist_item;
1339  int nmembers;
1340  bool ordered;
1341  HeapTuple ntp;
1342  MemoryContext oldcxt;
1343  int i;
1344 
1345  /*
1346  * one-time startup overhead for each cache
1347  */
1348  if (cache->cc_tupdesc == NULL)
1350 
1351  Assert(nkeys > 0 && nkeys < cache->cc_nkeys);
1352 
1353 #ifdef CATCACHE_STATS
1354  cache->cc_lsearches++;
1355 #endif
1356 
1357  /*
1358  * initialize the search key information
1359  */
1360  memcpy(cur_skey, cache->cc_skey, sizeof(cur_skey));
1361  cur_skey[0].sk_argument = v1;
1362  cur_skey[1].sk_argument = v2;
1363  cur_skey[2].sk_argument = v3;
1364  cur_skey[3].sk_argument = v4;
1365 
1366  /*
1367  * compute a hash value of the given keys for faster search. We don't
1368  * presently divide the CatCList items into buckets, but this still lets
1369  * us skip non-matching items quickly most of the time.
1370  */
1371  lHashValue = CatalogCacheComputeHashValue(cache, nkeys, cur_skey);
1372 
1373  /*
1374  * scan the items until we find a match or exhaust our list
1375  *
1376  * Note: it's okay to use dlist_foreach here, even though we modify the
1377  * dlist within the loop, because we don't continue the loop afterwards.
1378  */
1379  dlist_foreach(iter, &cache->cc_lists)
1380  {
1381  bool res;
1382 
1383  cl = dlist_container(CatCList, cache_elem, iter.cur);
1384 
1385  if (cl->dead)
1386  continue; /* ignore dead entries */
1387 
1388  if (cl->hash_value != lHashValue)
1389  continue; /* quickly skip entry if wrong hash val */
1390 
1391  /*
1392  * see if the cached list matches our key.
1393  */
1394  if (cl->nkeys != nkeys)
1395  continue;
1396  HeapKeyTest(&cl->tuple,
1397  cache->cc_tupdesc,
1398  nkeys,
1399  cur_skey,
1400  res);
1401  if (!res)
1402  continue;
1403 
1404  /*
1405  * We found a matching list. Move the list to the front of the
1406  * cache's list-of-lists, to speed subsequent searches. (We do not
1407  * move the members to the fronts of their hashbucket lists, however,
1408  * since there's no point in that unless they are searched for
1409  * individually.)
1410  */
1411  dlist_move_head(&cache->cc_lists, &cl->cache_elem);
1412 
1413  /* Bump the list's refcount and return it */
1415  cl->refcount++;
1417 
1418  CACHE2_elog(DEBUG2, "SearchCatCacheList(%s): found list",
1419  cache->cc_relname);
1420 
1421 #ifdef CATCACHE_STATS
1422  cache->cc_lhits++;
1423 #endif
1424 
1425  return cl;
1426  }
1427 
1428  /*
1429  * List was not found in cache, so we have to build it by reading the
1430  * relation. For each matching tuple found in the relation, use an
1431  * existing cache entry if possible, else build a new one.
1432  *
1433  * We have to bump the member refcounts temporarily to ensure they won't
1434  * get dropped from the cache while loading other members. We use a PG_TRY
1435  * block to ensure we can undo those refcounts if we get an error before
1436  * we finish constructing the CatCList.
1437  */
1439 
1440  ctlist = NIL;
1441 
1442  PG_TRY();
1443  {
1444  Relation relation;
1445  SysScanDesc scandesc;
1446 
1447  relation = heap_open(cache->cc_reloid, AccessShareLock);
1448 
1449  scandesc = systable_beginscan(relation,
1450  cache->cc_indexoid,
1451  IndexScanOK(cache, cur_skey),
1452  NULL,
1453  nkeys,
1454  cur_skey);
1455 
1456  /* The list will be ordered iff we are doing an index scan */
1457  ordered = (scandesc->irel != NULL);
1458 
1459  while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
1460  {
1461  uint32 hashValue;
1462  Index hashIndex;
1463  bool found = false;
1464  dlist_head *bucket;
1465 
1466  /*
1467  * See if there's an entry for this tuple already.
1468  */
1469  ct = NULL;
1470  hashValue = CatalogCacheComputeTupleHashValue(cache, ntp);
1471  hashIndex = HASH_INDEX(hashValue, cache->cc_nbuckets);
1472 
1473  bucket = &cache->cc_bucket[hashIndex];
1474  dlist_foreach(iter, bucket)
1475  {
1476  ct = dlist_container(CatCTup, cache_elem, iter.cur);
1477 
1478  if (ct->dead || ct->negative)
1479  continue; /* ignore dead and negative entries */
1480 
1481  if (ct->hash_value != hashValue)
1482  continue; /* quickly skip entry if wrong hash val */
1483 
1484  if (!ItemPointerEquals(&(ct->tuple.t_self), &(ntp->t_self)))
1485  continue; /* not same tuple */
1486 
1487  /*
1488  * Found a match, but can't use it if it belongs to another
1489  * list already
1490  */
1491  if (ct->c_list)
1492  continue;
1493 
1494  found = true;
1495  break; /* A-OK */
1496  }
1497 
1498  if (!found)
1499  {
1500  /* We didn't find a usable entry, so make a new one */
1501  ct = CatalogCacheCreateEntry(cache, ntp,
1502  hashValue, hashIndex,
1503  false);
1504  }
1505 
1506  /* Careful here: add entry to ctlist, then bump its refcount */
1507  /* This way leaves state correct if lappend runs out of memory */
1508  ctlist = lappend(ctlist, ct);
1509  ct->refcount++;
1510  }
1511 
1512  systable_endscan(scandesc);
1513 
1514  heap_close(relation, AccessShareLock);
1515 
1516  /*
1517  * Now we can build the CatCList entry. First we need a dummy tuple
1518  * containing the key values...
1519  */
1520  ntp = build_dummy_tuple(cache, nkeys, cur_skey);
1522  nmembers = list_length(ctlist);
1523  cl = (CatCList *)
1524  palloc(offsetof(CatCList, members) + nmembers * sizeof(CatCTup *));
1525  heap_copytuple_with_tuple(ntp, &cl->tuple);
1526  MemoryContextSwitchTo(oldcxt);
1527  heap_freetuple(ntp);
1528 
1529  /*
1530  * We are now past the last thing that could trigger an elog before we
1531  * have finished building the CatCList and remembering it in the
1532  * resource owner. So it's OK to fall out of the PG_TRY, and indeed
1533  * we'd better do so before we start marking the members as belonging
1534  * to the list.
1535  */
1536 
1537  }
1538  PG_CATCH();
1539  {
1540  foreach(ctlist_item, ctlist)
1541  {
1542  ct = (CatCTup *) lfirst(ctlist_item);
1543  Assert(ct->c_list == NULL);
1544  Assert(ct->refcount > 0);
1545  ct->refcount--;
1546  if (
1547 #ifndef CATCACHE_FORCE_RELEASE
1548  ct->dead &&
1549 #endif
1550  ct->refcount == 0 &&
1551  (ct->c_list == NULL || ct->c_list->refcount == 0))
1552  CatCacheRemoveCTup(cache, ct);
1553  }
1554 
1555  PG_RE_THROW();
1556  }
1557  PG_END_TRY();
1558 
1559  cl->cl_magic = CL_MAGIC;
1560  cl->my_cache = cache;
1561  cl->refcount = 0; /* for the moment */
1562  cl->dead = false;
1563  cl->ordered = ordered;
1564  cl->nkeys = nkeys;
1565  cl->hash_value = lHashValue;
1566  cl->n_members = nmembers;
1567 
1568  i = 0;
1569  foreach(ctlist_item, ctlist)
1570  {
1571  cl->members[i++] = ct = (CatCTup *) lfirst(ctlist_item);
1572  Assert(ct->c_list == NULL);
1573  ct->c_list = cl;
1574  /* release the temporary refcount on the member */
1575  Assert(ct->refcount > 0);
1576  ct->refcount--;
1577  /* mark list dead if any members already dead */
1578  if (ct->dead)
1579  cl->dead = true;
1580  }
1581  Assert(i == nmembers);
1582 
1583  dlist_push_head(&cache->cc_lists, &cl->cache_elem);
1584 
1585  /* Finally, bump the list's refcount and return it */
1586  cl->refcount++;
1588 
1589  CACHE3_elog(DEBUG2, "SearchCatCacheList(%s): made list of %d members",
1590  cache->cc_relname, nmembers);
1591 
1592  return cl;
1593 }
#define NIL
Definition: pg_list.h:69
Relation irel
Definition: relscan.h:156
int n_members
Definition: catcache.h:154
uint32 hash_value
Definition: catcache.h:152
uint32 hash_value
Definition: catcache.h:115
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define CACHE3_elog(a, b, c, d)
Definition: catcache.c:66
#define HASH_INDEX(h, sz)
Definition: catcache.c:49
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:300
static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, uint32 hashValue, Index hashIndex, bool negative)
Definition: catcache.c:1624
#define dlist_foreach(iter, lhead)
Definition: ilist.h:507
ResourceOwner CurrentResourceOwner
Definition: resowner.c:138
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
dlist_head * cc_bucket
Definition: catcache.h:55
#define AccessShareLock
Definition: lockdefs.h:36
void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner)
Definition: resowner.c:973
int cl_magic
Definition: catcache.h:122
bool dead
Definition: catcache.h:149
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
dlist_head cc_lists
Definition: catcache.h:54
static void CatalogCacheInitializeCache(CatCache *cache)
Definition: catcache.c:812
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
short nkeys
Definition: catcache.h:151
struct catclist * c_list
Definition: catcache.h:98
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:155
Oid cc_indexoid
Definition: catcache.h:43
#define dlist_container(type, membername, ptr)
Definition: ilist.h:477
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, ScanKey cur_skey)
Definition: catcache.c:174
#define CATCACHE_MAXKEYS
Definition: catcache.h:35
Oid cc_reloid
Definition: catcache.h:42
ItemPointerData t_self
Definition: htup.h:65
TupleDesc cc_tupdesc
Definition: catcache.h:45
#define DEBUG2
Definition: elog.h:24
unsigned int uint32
Definition: c.h:258
List * lappend(List *list, void *datum)
Definition: list.c:128
dlist_node cache_elem
Definition: catcache.h:147
#define CL_MAGIC
Definition: catcache.h:123
static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct)
Definition: catcache.c:354
static bool IndexScanOK(CatCache *cache, ScanKey cur_skey)
Definition: catcache.c:975
void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest)
Definition: heaptuple.c:637
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
CatCache * my_cache
Definition: catcache.h:124
dlist_node * cur
Definition: ilist.h:161
unsigned int Index
Definition: c.h:359
#define PG_CATCH()
Definition: elog.h:293
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:664
#define lfirst(lc)
Definition: pg_list.h:106
static HeapTuple build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
Definition: catcache.c:1690
int cc_nbuckets
Definition: catcache.h:47
HeapTupleData tuple
Definition: catcache.h:153
static int list_length(const List *l)
Definition: pg_list.h:89
int refcount
Definition: catcache.h:112
const char * cc_relname
Definition: catcache.h:41
#define PG_RE_THROW()
Definition: elog.h:314
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
Definition: catcache.c:227
static void dlist_move_head(dlist_head *head, dlist_node *node)
Definition: ilist.h:385
bool negative
Definition: catcache.h:114
bool ordered
Definition: catcache.h:150
void * palloc(Size size)
Definition: mcxt.c:848
int i
HeapTupleData tuple
Definition: catcache.h:116
#define CACHE2_elog(a, b, c)
Definition: catcache.c:65
#define HeapKeyTest(tuple, tupdesc, nkeys, keys, result)
Definition: valid.h:22
int refcount
Definition: catcache.h:148
#define PG_TRY()
Definition: elog.h:284
ScanKeyData cc_skey[CATCACHE_MAXKEYS]
Definition: catcache.h:51
Definition: pg_list.h:45
Datum sk_argument
Definition: skey.h:72
#define PG_END_TRY()
Definition: elog.h:300
#define offsetof(type, field)
Definition: c.h:549
bool dead
Definition: catcache.h:113
MemoryContext CacheMemoryContext
Definition: mcxt.c:46
void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
Definition: resowner.c:984

Variable Documentation

PGDLLIMPORT MemoryContext CacheMemoryContext

Definition at line 46 of file mcxt.c.