/* get the value stored in the first element */ void* DLGetTailVal(Dllist* l) { Dlelem* e = DLGetTail(l); return (e ? e->dle_val : 0); }
/* * CatalogCacheCreateEntry * Create a new CatCTup entry, copying the given HeapTuple and other * supplied data into it. The new entry is given refcount 1. */ static CatCTup * CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, uint32 hashValue, Index hashIndex, bool negative) { CatCTup *ct; MemoryContext oldcxt; /* * Allocate CatCTup header in cache memory, and copy the tuple there * too. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); ct = (CatCTup *) palloc(sizeof(CatCTup)); heap_copytuple_with_tuple(ntp, &ct->tuple); MemoryContextSwitchTo(oldcxt); /* * Finish initializing the CatCTup header, and add it to the cache's * linked lists and counts. */ ct->ct_magic = CT_MAGIC; ct->my_cache = cache; DLInitElem(&ct->lrulist_elem, (void *) ct); DLInitElem(&ct->cache_elem, (void *) ct); ct->c_list = NULL; ct->refcount = 1; /* count this first reference */ ct->dead = false; ct->negative = negative; ct->hash_value = hashValue; DLAddHead(&CacheHdr->ch_lrulist, &ct->lrulist_elem); DLAddHead(&cache->cc_bucket[hashIndex], &ct->cache_elem); cache->cc_ntup++; CacheHdr->ch_ntup++; /* * If we've exceeded the desired size of the caches, try to throw away * the least recently used entry. NB: the newly-built entry cannot * get thrown away here, because it has positive refcount. */ if (CacheHdr->ch_ntup > CacheHdr->ch_maxtup) { Dlelem *elt, *prevelt; for (elt = DLGetTail(&CacheHdr->ch_lrulist); elt; elt = prevelt) { CatCTup *oldct = (CatCTup *) DLE_VAL(elt); prevelt = DLGetPred(elt); if (oldct->refcount == 0) { CACHE2_elog(DEBUG2, "CatCacheCreateEntry(%s): Overflow, LRU removal", cache->cc_relname); #ifdef CATCACHE_STATS oldct->my_cache->cc_discards++; #endif CatCacheRemoveCTup(oldct->my_cache, oldct); if (CacheHdr->ch_ntup <= CacheHdr->ch_maxtup) break; } } } return ct; }