diff options
Diffstat (limited to 'src/backend/utils/cache/catcache.c')
-rw-r--r-- | src/backend/utils/cache/catcache.c | 118 |
1 files changed, 49 insertions, 69 deletions
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index e5e22a7ab31..f96a3956053 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.58 2000/01/26 05:57:17 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.59 2000/01/31 04:35:51 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -35,9 +35,6 @@ static long comphash(long l, char *v); /* ---------------- * variables, macros and other stuff - * - * note CCSIZE allocates 51 buckets .. one was already allocated in - * the catcache structure. * ---------------- */ @@ -64,17 +61,20 @@ GlobalMemory CacheCxt; /* context in which caches are allocated */ /* ---------------- - * EQPROC is used in CatalogCacheInitializeCache - * XXX this should be replaced by catalog lookups soon + * EQPROC is used in CatalogCacheInitializeCache to find the equality + * functions for system types that are used as cache key fields. + * + * XXX this should be replaced by catalog lookups, + * but that seems to pose considerable risk of circularity... * ---------------- */ -static long eqproc[] = { - F_BOOLEQ, 0l, F_CHAREQ, F_NAMEEQ, 0l, - F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, 0l, F_TEXTEQ, - F_OIDEQ, 0l, 0l, 0l, F_OIDVECTOREQ +static const Oid eqproc[] = { + F_BOOLEQ, InvalidOid, F_CHAREQ, F_NAMEEQ, InvalidOid, + F_INT2EQ, F_KEYFIRSTEQ, F_INT4EQ, F_OIDEQ, F_TEXTEQ, + F_OIDEQ, InvalidOid, InvalidOid, InvalidOid, F_OIDVECTOREQ }; -#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-16] +#define EQPROC(SYSTEMTYPEOID) eqproc[(SYSTEMTYPEOID)-BOOLOID] /* ---------------------------------------------------------------- * internal support functions @@ -169,12 +169,13 @@ CatalogCacheInitializeCache(struct catcache * cache, } /* ---------------- - * initialize the cache's relation id + * initialize the cache's relation id and tuple descriptor * ---------------- */ Assert(RelationIsValid(relation)); cache->relationId = RelationGetRelid(relation); - tupdesc = cache->cc_tupdesc = RelationGetDescr(relation); + tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation)); + cache->cc_tupdesc = tupdesc; CACHE3_elog(DEBUG, "CatalogCacheInitializeCache: relid %u, %d keys", cache->relationId, cache->cc_nkeys); @@ -254,22 +255,6 @@ CatalogCacheInitializeCache(struct catcache * cache, MemoryContextSwitchTo(oldcxt); } -/* -------------------------------- - * CatalogCacheSetId - * - * XXX temporary function - * -------------------------------- - */ -#ifdef NOT_USED -void -CatalogCacheSetId(CatCache *cacheInOutP, int id) -{ - Assert(id == InvalidCatalogCacheId || id >= 0); - cacheInOutP->id = id; -} - -#endif - /* ---------------- * comphash * Compute a hash value, somehow. @@ -369,10 +354,12 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, Relation relation, HeapTuple tuple) { - bool isNull = '\0'; + bool isNull = false; + /* XXX is this really needed? */ if (cacheInOutP->relationId == InvalidOid) CatalogCacheInitializeCache(cacheInOutP, relation); + switch (cacheInOutP->cc_nkeys) { case 4: @@ -417,8 +404,7 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, break; default: elog(FATAL, "CCComputeTupleHashIndex: %d cc_nkeys", - cacheInOutP->cc_nkeys - ); + cacheInOutP->cc_nkeys); break; } @@ -427,6 +413,8 @@ CatalogCacheComputeTupleHashIndex(struct catcache * cacheInOutP, /* -------------------------------- * CatCacheRemoveCTup + * + * NB: assumes caller has switched to CacheCxt * -------------------------------- */ static void @@ -436,19 +424,24 @@ CatCacheRemoveCTup(CatCache *cache, Dlelem *elt) CatCTup *other_ct; Dlelem *other_elt; - if (elt) - ct = (CatCTup *) DLE_VAL(elt); - else + if (!elt) /* probably-useless safety check */ return; + /* We need to zap both linked-list elements as well as the tuple */ + + ct = (CatCTup *) DLE_VAL(elt); other_elt = ct->ct_node; other_ct = (CatCTup *) DLE_VAL(other_elt); + + heap_freetuple(ct->ct_tup); + DLRemove(other_elt); DLFreeElem(other_elt); - free(other_ct); + pfree(other_ct); DLRemove(elt); DLFreeElem(elt); - free(ct); + pfree(ct); + --cache->cc_ntup; } @@ -529,7 +522,6 @@ CatalogCacheIdInvalidate(int cacheId, /* XXX */ * ---------------- */ MemoryContextSwitchTo(oldcxt); - /* sendpm('I', "Invalidated tuple"); */ } /* ---------------------------------------------------------------- @@ -615,34 +607,26 @@ ResetSystemCache() * * A special case occurs when relId is itself one of the cacheable system * tables --- although those'll never be dropped, they can get flushed from - * the relcache (VACUUM causes this, for example). In that case we need to - * force the next SearchSysCache() call to reinitialize the cache itself, - * because we have info (such as cc_tupdesc) that is pointing at the about- - * to-be-deleted relcache entry. + * the relcache (VACUUM causes this, for example). In that case we need + * to flush all cache entries from that table. The brute-force method + * currently used takes care of that quite handily. (At one point we + * also tried to force re-execution of CatalogCacheInitializeCache for + * the cache(s) on that table. This is a bad idea since it leads to all + * kinds of trouble if a cache flush occurs while loading cache entries. + * We now avoid the need to do it by copying cc_tupdesc out of the relcache, + * rather than relying on the relcache to keep a tupdesc for us. Of course + * this assumes the tupdesc of a cachable system table will not change...) * -------------------------------- */ void SystemCacheRelationFlushed(Oid relId) { - struct catcache *cache; - /* * XXX Ideally we'd search the caches and just zap entries that actually - * refer to the indicated relation. For now, we take the brute-force - * approach: just flush the caches entirely. + * refer to or come from the indicated relation. For now, we take the + * brute-force approach: just flush the caches entirely. */ ResetSystemCache(); - - /* - * If relcache is dropping a system relation's cache entry, mark the - * associated cache structures invalid, so we can rebuild them from - * scratch (not just repopulate them) next time they are used. - */ - for (cache = Caches; PointerIsValid(cache); cache = cache->cc_next) - { - if (cache->relationId == relId) - cache->relationId = InvalidOid; - } } /* -------------------------------- @@ -715,11 +699,11 @@ InitSysCache(char *relname, { /* * We can only do this optimization because the number of hash - * buckets never changes. Without it, we call malloc() too much. + * buckets never changes. Without it, we call palloc() too much. * We could move this to dllist.c, but the way we do this is not - * dynamic/portabl, so why allow other routines to use it. + * dynamic/portable, so why allow other routines to use it. */ - Dllist *cache_begin = malloc((NCCBUCK + 1) * sizeof(Dllist)); + Dllist *cache_begin = palloc((NCCBUCK + 1) * sizeof(Dllist)); for (i = 0; i <= NCCBUCK; ++i) { @@ -927,7 +911,7 @@ SearchSysCache(struct catcache * cache, MemoryContext oldcxt; /* ---------------- - * sanity checks + * one-time startup overhead * ---------------- */ if (cache->relationId == InvalidOid) @@ -946,7 +930,7 @@ SearchSysCache(struct catcache * cache, * resolve self referencing informtion */ if ((ntp = SearchSelfReferences(cache))) - return heap_copytuple(ntp); + return ntp; /* ---------------- * find the hash bucket in which to look for the tuple @@ -995,10 +979,8 @@ SearchSysCache(struct catcache * cache, DLMoveToFront(elt); #ifdef CACHEDEBUG - relation = heap_open(cache->relationId, NoLock); CACHE3_elog(DEBUG, "SearchSysCache(%s): found in bucket %d", - RelationGetRelationName(relation), hash); - heap_close(relation, NoLock); + cache->cc_relname, hash); #endif /* CACHEDEBUG */ return ct->ct_tup; @@ -1020,9 +1002,7 @@ SearchSysCache(struct catcache * cache, */ if (cache->busy) - { elog(ERROR, "SearchSysCache: recursive use of cache %d", cache->id); - } cache->busy = true; /* ---------------- @@ -1140,10 +1120,10 @@ SearchSysCache(struct catcache * cache, * it easier to remove something from both the cache bucket and * the lru list at the same time */ - nct = (CatCTup *) malloc(sizeof(CatCTup)); + nct = (CatCTup *) palloc(sizeof(CatCTup)); nct->ct_tup = ntp; elt = DLNewElem(nct); - nct2 = (CatCTup *) malloc(sizeof(CatCTup)); + nct2 = (CatCTup *) palloc(sizeof(CatCTup)); nct2->ct_tup = ntp; lru_elt = DLNewElem(nct2); nct2->ct_node = elt; |