init
This commit is contained in:
197
include/utils/catcache.h
Executable file
197
include/utils/catcache.h
Executable file
@@ -0,0 +1,197 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* catcache.h
|
||||
* Low-level catalog cache definitions.
|
||||
*
|
||||
* NOTE: every catalog cache must have a corresponding unique index on
|
||||
* the system table that it caches --- ie, the index must match the keys
|
||||
* used to do lookups in this cache. All cache fetches are done with
|
||||
* indexscans (under normal conditions). The index should be unique to
|
||||
* guarantee that there can only be one matching row for a key combination.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/utils/catcache.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef CATCACHE_H
|
||||
#define CATCACHE_H
|
||||
|
||||
#include "access/htup.h"
|
||||
#include "access/skey.h"
|
||||
#include "lib/dllist.h"
|
||||
#include "utils/relcache.h"
|
||||
|
||||
/*
|
||||
* struct catctup: individual tuple in the cache.
|
||||
* struct catclist: list of tuples matching a partial key.
|
||||
* struct catcache: information for managing a cache.
|
||||
* struct catcacheheader: information for managing all the caches.
|
||||
*/
|
||||
|
||||
#define CATCACHE_MAXKEYS 4
|
||||
|
||||
typedef struct catcache {
|
||||
int id; /* cache identifier --- see syscache.h */
|
||||
struct catcache *cc_next; /* link to next catcache */
|
||||
const char *cc_relname; /* name of relation the tuples come from */
|
||||
Oid cc_reloid; /* OID of relation the tuples come from */
|
||||
Oid cc_indexoid; /* OID of index matching cache keys */
|
||||
bool cc_relisshared; /* is relation shared across databases? */
|
||||
TupleDesc cc_tupdesc; /* tuple descriptor (copied from reldesc) */
|
||||
int cc_ntup; /* # of tuples currently in this cache */
|
||||
int cc_nbuckets; /* # of hash buckets in this cache */
|
||||
int cc_nkeys; /* # of keys (1..CATCACHE_MAXKEYS) */
|
||||
int cc_key[CATCACHE_MAXKEYS]; /* AttrNumber of each key */
|
||||
PGFunction cc_hashfunc[CATCACHE_MAXKEYS]; /* hash function for each key */
|
||||
ScanKeyData cc_skey[CATCACHE_MAXKEYS]; /* precomputed key info for
|
||||
* heap scans */
|
||||
bool cc_isname[CATCACHE_MAXKEYS]; /* flag "name" key columns */
|
||||
Dllist cc_lists; /* list of CatCList structs */
|
||||
#ifdef CATCACHE_STATS
|
||||
long cc_searches; /* total # searches against this cache */
|
||||
long cc_hits; /* # of matches against existing entry */
|
||||
long cc_neg_hits; /* # of matches against negative entry */
|
||||
long cc_newloads; /* # of successful loads of new entry */
|
||||
|
||||
/*
|
||||
* cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of failed
|
||||
* searches, each of which will result in loading a negative entry
|
||||
*/
|
||||
long cc_invals; /* # of entries invalidated from cache */
|
||||
long cc_lsearches; /* total # list-searches */
|
||||
long cc_lhits; /* # of matches against existing lists */
|
||||
#endif
|
||||
Dllist cc_bucket[1]; /* hash buckets --- VARIABLE LENGTH ARRAY */
|
||||
} CatCache; /* VARIABLE LENGTH STRUCT */
|
||||
|
||||
typedef struct catctup {
|
||||
int ct_magic; /* for identifying CatCTup entries */
|
||||
#define CT_MAGIC 0x57261502
|
||||
CatCache *my_cache; /* link to owning catcache */
|
||||
|
||||
/*
|
||||
* Each tuple in a cache is a member of a Dllist that stores the elements
|
||||
* of its hash bucket. We keep each Dllist in LRU order to speed repeated
|
||||
* lookups.
|
||||
*/
|
||||
Dlelem cache_elem; /* list member of per-bucket list */
|
||||
|
||||
/*
|
||||
* The tuple may also be a member of at most one CatCList. (If a single
|
||||
* catcache is list-searched with varying numbers of keys, we may have to
|
||||
* make multiple entries for the same tuple because of this restriction.
|
||||
* Currently, that's not expected to be common, so we accept the potential
|
||||
* inefficiency.)
|
||||
*/
|
||||
struct catclist *c_list; /* containing CatCList, or NULL if none */
|
||||
|
||||
/*
|
||||
* A tuple marked "dead" must not be returned by subsequent searches.
|
||||
* However, it won't be physically deleted from the cache until its
|
||||
* refcount goes to zero. (If it's a member of a CatCList, the list's
|
||||
* refcount must go to zero, too; also, remember to mark the list dead at
|
||||
* the same time the tuple is marked.)
|
||||
*
|
||||
* A negative cache entry is an assertion that there is no tuple matching
|
||||
* a particular key. This is just as useful as a normal entry so far as
|
||||
* avoiding catalog searches is concerned. Management of positive and
|
||||
* negative entries is identical.
|
||||
*/
|
||||
int refcount; /* number of active references */
|
||||
bool dead; /* dead but not yet removed? */
|
||||
bool negative; /* negative cache entry? */
|
||||
uint32 hash_value; /* hash value for this tuple's keys */
|
||||
HeapTupleData tuple; /* tuple management header */
|
||||
} CatCTup;
|
||||
|
||||
typedef struct catclist {
|
||||
int cl_magic; /* for identifying CatCList entries */
|
||||
#define CL_MAGIC 0x52765103
|
||||
CatCache *my_cache; /* link to owning catcache */
|
||||
|
||||
/*
|
||||
* A CatCList describes the result of a partial search, ie, a search using
|
||||
* only the first K key columns of an N-key cache. We form the keys used
|
||||
* into a tuple (with other attributes NULL) to represent the stored key
|
||||
* set. The CatCList object contains links to cache entries for all the
|
||||
* table rows satisfying the partial key. (Note: none of these will be
|
||||
* negative cache entries.)
|
||||
*
|
||||
* A CatCList is only a member of a per-cache list; we do not currently
|
||||
* divide them into hash buckets.
|
||||
*
|
||||
* A list marked "dead" must not be returned by subsequent searches.
|
||||
* However, it won't be physically deleted from the cache until its
|
||||
* refcount goes to zero. (A list should be marked dead if any of its
|
||||
* member entries are dead.)
|
||||
*
|
||||
* If "ordered" is true then the member tuples appear in the order of the
|
||||
* cache's underlying index. This will be true in normal operation, but
|
||||
* might not be true during bootstrap or recovery operations. (namespace.c
|
||||
* is able to save some cycles when it is true.)
|
||||
*/
|
||||
Dlelem cache_elem; /* list member of per-catcache list */
|
||||
int refcount; /* number of active references */
|
||||
bool dead; /* dead but not yet removed? */
|
||||
bool ordered; /* members listed in index order? */
|
||||
short nkeys; /* number of lookup keys specified */
|
||||
uint32 hash_value; /* hash value for lookup keys */
|
||||
HeapTupleData tuple; /* header for tuple holding keys */
|
||||
int n_members; /* number of member tuples */
|
||||
CatCTup *members[1]; /* members --- VARIABLE LENGTH ARRAY */
|
||||
} CatCList; /* VARIABLE LENGTH STRUCT */
|
||||
|
||||
typedef struct catcacheheader {
|
||||
CatCache *ch_caches; /* head of list of CatCache structs */
|
||||
int ch_ntup; /* # of tuples in all caches */
|
||||
} CatCacheHeader;
|
||||
|
||||
/* this extern duplicates utils/memutils.h... */
|
||||
extern PGDLLIMPORT __thread MemoryContext CacheMemoryContext;
|
||||
|
||||
extern void CreateCacheMemoryContext(void);
|
||||
|
||||
extern void AtEOXact_CatCache(bool isCommit);
|
||||
|
||||
extern CatCache *InitCatCache(int id, Oid reloid, Oid indexoid,
|
||||
int nkeys, const int *key,
|
||||
int nbuckets);
|
||||
|
||||
extern void InitCatCachePhase2(CatCache *cache, bool touch_index);
|
||||
|
||||
extern HeapTuple SearchCatCache(CatCache *cache,
|
||||
Datum v1, Datum v2,
|
||||
Datum v3, Datum v4);
|
||||
|
||||
extern void ReleaseCatCache(HeapTuple tuple);
|
||||
|
||||
extern uint32 GetCatCacheHashValue(CatCache *cache,
|
||||
Datum v1, Datum v2,
|
||||
Datum v3, Datum v4);
|
||||
|
||||
extern CatCList *SearchCatCacheList(CatCache *cache, int nkeys,
|
||||
Datum v1, Datum v2,
|
||||
Datum v3, Datum v4);
|
||||
|
||||
extern void ReleaseCatCacheList(CatCList *list);
|
||||
|
||||
extern void ResetCatalogCaches(void);
|
||||
|
||||
extern void CatalogCacheFlushCatalog(Oid catId);
|
||||
|
||||
extern void CatalogCacheIdInvalidate(int cacheId, uint32 hashValue);
|
||||
|
||||
extern void PrepareToInvalidateCacheTuple(Relation relation,
|
||||
HeapTuple tuple,
|
||||
HeapTuple newtuple,
|
||||
void (*function)(int, uint32, Oid));
|
||||
|
||||
extern void PrintCatCacheLeakWarning(HeapTuple tuple);
|
||||
|
||||
extern void PrintCatCacheListLeakWarning(CatCList *list);
|
||||
|
||||
#endif /* CATCACHE_H */
|
||||
152
include/utils/memutils.h
Executable file
152
include/utils/memutils.h
Executable file
@@ -0,0 +1,152 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* memutils.h
|
||||
* This file contains declarations for memory allocation utility
|
||||
* functions. These are functions that are not quite widely used
|
||||
* enough to justify going in utils/palloc.h, but are still part
|
||||
* of the API of the memory management subsystem.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/utils/memutils.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef MEMUTILS_H
|
||||
#define MEMUTILS_H
|
||||
|
||||
#include "nodes/memnodes.h"
|
||||
#include <pthread.h>
|
||||
|
||||
/*
|
||||
* MaxAllocSize
|
||||
* Quasi-arbitrary limit on size of allocations.
|
||||
*
|
||||
* Note:
|
||||
* There is no guarantee that allocations smaller than MaxAllocSize
|
||||
* will succeed. Allocation requests larger than MaxAllocSize will
|
||||
* be summarily denied.
|
||||
*
|
||||
* XXX This is deliberately chosen to correspond to the limiting size
|
||||
* of varlena objects under TOAST. See VARSIZE_4B() and related macros
|
||||
* in postgres.h. Many datatypes assume that any allocatable size can
|
||||
* be represented in a varlena header.
|
||||
*
|
||||
* XXX Also, various places in aset.c assume they can compute twice an
|
||||
* allocation's size without overflow, so beware of raising this.
|
||||
*/
|
||||
#define MaxAllocSize ((Size)0x3fffffff) /* 1 gigabyte - 1 */
|
||||
|
||||
#define AllocSizeIsValid(size) ((Size)(size) <= MaxAllocSize)
|
||||
|
||||
/*
|
||||
* All chunks allocated by any memory context manager are required to be
|
||||
* preceded by a StandardChunkHeader at a spacing of STANDARDCHUNKHEADERSIZE.
|
||||
* A currently-allocated chunk must contain a backpointer to its owning
|
||||
* context as well as the allocated size of the chunk. The backpointer is
|
||||
* used by pfree() and repalloc() to find the context to call. The allocated
|
||||
* size is not absolutely essential, but it's expected to be needed by any
|
||||
* reasonable implementation.
|
||||
*/
|
||||
typedef struct StandardChunkHeader {
|
||||
MemoryContext context; /* owning context */
|
||||
Size size; /* size of data space allocated in chunk */
|
||||
#ifdef MEMORY_CONTEXT_CHECKING
|
||||
/* when debugging memory usage, also store actual requested size */
|
||||
Size requested_size;
|
||||
#endif
|
||||
} StandardChunkHeader;
|
||||
|
||||
#define STANDARDCHUNKHEADERSIZE MAXALIGN(sizeof(StandardChunkHeader))
|
||||
|
||||
/*
|
||||
* Standard top-level memory contexts.
|
||||
*
|
||||
* Only TopMemoryContext and ErrorContext are initialized by
|
||||
* MemoryContextInit() itself.
|
||||
*/
|
||||
extern PGDLLIMPORT __thread MemoryContext TopMemoryContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext ErrorContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext PostmasterContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext CacheMemoryContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext MessageContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext TopTransactionContext;
|
||||
extern PGDLLIMPORT __thread MemoryContext CurTransactionContext;
|
||||
|
||||
/* This is a transient link to the active portal's memory context: */
|
||||
extern PGDLLIMPORT __thread MemoryContext PortalContext;
|
||||
|
||||
/*
|
||||
* Memory-context-type-independent functions in mcxt.c
|
||||
*/
|
||||
extern void MemoryContextInit(void);
|
||||
|
||||
extern void MemoryContextReset(MemoryContext context);
|
||||
|
||||
extern void MemoryContextDelete(MemoryContext context);
|
||||
|
||||
extern void MemoryContextResetChildren(MemoryContext context);
|
||||
|
||||
extern void MemoryContextDeleteChildren(MemoryContext context);
|
||||
|
||||
extern void MemoryContextResetAndDeleteChildren(MemoryContext context);
|
||||
|
||||
extern void MemoryContextSetParent(MemoryContext context,
|
||||
MemoryContext new_parent);
|
||||
|
||||
extern Size GetMemoryChunkSpace(void *pointer);
|
||||
|
||||
extern MemoryContext GetMemoryChunkContext(void *pointer);
|
||||
|
||||
extern MemoryContext MemoryContextGetParent(MemoryContext context);
|
||||
|
||||
extern bool MemoryContextIsEmpty(MemoryContext context);
|
||||
|
||||
extern void MemoryContextStats(MemoryContext context);
|
||||
|
||||
#ifdef MEMORY_CONTEXT_CHECKING
|
||||
extern void MemoryContextCheck(MemoryContext context);
|
||||
#endif
|
||||
|
||||
extern bool MemoryContextContains(MemoryContext context, void *pointer);
|
||||
|
||||
/*
|
||||
* This routine handles the context-type-independent part of memory
|
||||
* context creation. It's intended to be called from context-type-
|
||||
* specific creation routines, and noplace else.
|
||||
*/
|
||||
extern MemoryContext MemoryContextCreate(NodeTag tag, Size size,
|
||||
MemoryContextMethods *methods,
|
||||
MemoryContext parent,
|
||||
const char *name);
|
||||
|
||||
/*
|
||||
* Memory-context-type-specific functions
|
||||
*/
|
||||
|
||||
/* aset.c */
|
||||
extern MemoryContext AllocSetContextCreate(MemoryContext parent,
|
||||
const char *name,
|
||||
Size minContextSize,
|
||||
Size initBlockSize,
|
||||
Size maxBlockSize);
|
||||
|
||||
/*
|
||||
* Recommended default alloc parameters, suitable for "ordinary" contexts
|
||||
* that might hold quite a lot of data.
|
||||
*/
|
||||
#define ALLOCSET_DEFAULT_MINSIZE 0
|
||||
#define ALLOCSET_DEFAULT_INITSIZE (8 * 1024)
|
||||
#define ALLOCSET_DEFAULT_MAXSIZE (8 * 1024 * 1024)
|
||||
|
||||
/*
|
||||
* Recommended alloc parameters for "small" contexts that are not expected
|
||||
* to contain much data (for example, a context to contain a query plan).
|
||||
*/
|
||||
#define ALLOCSET_SMALL_MINSIZE 0
|
||||
#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
|
||||
#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
|
||||
|
||||
#endif /* MEMUTILS_H */
|
||||
112
include/utils/palloc.h
Executable file
112
include/utils/palloc.h
Executable file
@@ -0,0 +1,112 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* palloc.h
|
||||
* POSTGRES memory allocator definitions.
|
||||
*
|
||||
* This file contains the basic memory allocation interface that is
|
||||
* needed by almost every backend module. It is included directly by
|
||||
* postgres.h, so the definitions here are automatically available
|
||||
* everywhere. Keep it lean!
|
||||
*
|
||||
* Memory allocation occurs within "contexts". Every chunk obtained from
|
||||
* palloc()/MemoryContextAlloc() is allocated within a specific context.
|
||||
* The entire contents of a context can be freed easily and quickly by
|
||||
* resetting or deleting the context --- this is both faster and less
|
||||
* prone to memory-leakage bugs than releasing chunks individually.
|
||||
* We organize contexts into context trees to allow fine-grain control
|
||||
* over chunk lifetime while preserving the certainty that we will free
|
||||
* everything that should be freed. See utils/mmgr/README for more info.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* src/include/utils/palloc.h
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef PALLOC_H
|
||||
#define PALLOC_H
|
||||
|
||||
/*
|
||||
* Type MemoryContextData is declared in nodes/memnodes.h. Most users
|
||||
* of memory allocation should just treat it as an abstract type, so we
|
||||
* do not provide the struct contents here.
|
||||
*/
|
||||
typedef struct MemoryContextData *MemoryContext;
|
||||
|
||||
/*
|
||||
* CurrentMemoryContext is the default allocation context for palloc().
|
||||
* We declare it here so that palloc() can be a macro. Avoid accessing it
|
||||
* directly! Instead, use MemoryContextSwitchTo() to change the setting.
|
||||
*/
|
||||
extern PGDLLIMPORT __thread MemoryContext CurrentMemoryContext;
|
||||
|
||||
/*
|
||||
* Fundamental memory-allocation operations (more are in utils/memutils.h)
|
||||
*/
|
||||
extern void *MemoryContextAlloc(MemoryContext context, Size size);
|
||||
|
||||
extern void *MemoryContextAllocZero(MemoryContext context, Size size);
|
||||
|
||||
extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
|
||||
|
||||
#define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz))
|
||||
|
||||
#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz))
|
||||
|
||||
/*
|
||||
* The result of palloc() is always word-aligned, so we can skip testing
|
||||
* alignment of the pointer when deciding which MemSet variant to use.
|
||||
* Note that this variant does not offer any advantage, and should not be
|
||||
* used, unless its "sz" argument is a compile-time constant; therefore, the
|
||||
* issue that it evaluates the argument multiple times isn't a problem in
|
||||
* practice.
|
||||
*/
|
||||
#define palloc0fast(sz) \
|
||||
(MemSetTest(0, sz) ? MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : MemoryContextAllocZero(CurrentMemoryContext, sz))
|
||||
|
||||
extern void pfree(void *pointer);
|
||||
|
||||
extern void *repalloc(void *pointer, Size size);
|
||||
|
||||
/*
|
||||
* MemoryContextSwitchTo can't be a macro in standard C compilers.
|
||||
* But we can make it an inline function if the compiler supports it.
|
||||
*
|
||||
* This file has to be includable by some non-backend code such as
|
||||
* pg_resetxlog, so don't expose the CurrentMemoryContext reference
|
||||
* if FRONTEND is defined.
|
||||
*/
|
||||
#if defined(USE_INLINE) && !defined(FRONTEND)
|
||||
|
||||
static inline MemoryContext
|
||||
MemoryContextSwitchTo(MemoryContext context) {
|
||||
MemoryContext old = CurrentMemoryContext;
|
||||
|
||||
CurrentMemoryContext = context;
|
||||
return old;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern MemoryContext MemoryContextSwitchTo(MemoryContext context);
|
||||
#endif /* USE_INLINE && !FRONTEND */
|
||||
|
||||
/*
|
||||
* These are like standard strdup() except the copied string is
|
||||
* allocated in a context, not with malloc().
|
||||
*/
|
||||
extern char *MemoryContextStrdup(MemoryContext context, const char *string);
|
||||
|
||||
#define pstrdup(str) MemoryContextStrdup(CurrentMemoryContext, (str))
|
||||
|
||||
extern char *pnstrdup(const char *in, Size len);
|
||||
|
||||
#if defined(WIN32) || defined(__CYGWIN__)
|
||||
extern void *pgport_palloc(Size sz);
|
||||
extern char *pgport_pstrdup(const char *str);
|
||||
extern void pgport_pfree(void *pointer);
|
||||
#endif
|
||||
|
||||
#endif /* PALLOC_H */
|
||||
Reference in New Issue
Block a user