text: /*-------------------------------------------------------------------------
   *
   * 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-2014, 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"
  
  
  /*
   * MaxAllocSize, MaxAllocHugeSize
   *		Quasi-arbitrary limits on size of allocations.
   *
   * Note:
   *		There is no guarantee that smaller allocations will succeed, but
   *		larger requests will be summarily denied.
   *
   * palloc() enforces MaxAllocSize, 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.  This limit also permits a caller to use
   * an "int" variable for an index into or length of an allocation.  Callers
   * careful to avoid these hazards can access the higher limit with
   * MemoryContextAllocHuge().  Both limits permit code to assume that it may
   * compute twice an allocation's size without overflow.
   */
  #define MaxAllocSize	((Size) 0x3fffffff)		/* 1 gigabyte - 1 */
  
  #define AllocSizeIsValid(size)	((Size) (size) <= MaxAllocSize)
  
  #define MaxAllocHugeSize	(SIZE_MAX / 2)
  
  #define AllocHugeSizeIsValid(size)	((Size) (size) <= MaxAllocHugeSize)
  
  /*
   * 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 MemoryContext TopMemoryContext;
  extern PGDLLIMPORT MemoryContext ErrorContext;
  extern PGDLLIMPORT MemoryContext PostmasterContext;
  extern PGDLLIMPORT MemoryContext CacheMemoryContext;
  extern PGDLLIMPORT MemoryContext MessageContext;
  extern PGDLLIMPORT MemoryContext TopTransactionContext;
  extern PGDLLIMPORT MemoryContext CurTransactionContext;
  
  /* This is a transient link to the active portal's memory context: */
  extern PGDLLIMPORT 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)
  #define ALLOCSET_DEFAULT_SIZES \
  	ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
  
  /*
   * Recommended alloc parameters for "small" contexts that are never 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)
  #define ALLOCSET_SMALL_SIZES \
  	ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
  
  /*
   * Recommended alloc parameters for contexts that should start out small,
   * but might sometimes grow big.
   */
  #define ALLOCSET_START_SMALL_SIZES \
  	ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
  
  
  /*
   * Threshold above which a request in an AllocSet context is certain to be
   * allocated separately (and thereby have constant allocation overhead).
   * Few callers should be interested in this, but tuplesort/tuplestore need
   * to know it.
   */
  #define ALLOCSET_SEPARATE_THRESHOLD  8192
  
  #endif   /* MEMUTILS_H */
  