Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

SSL gin_private.h

  Sprache: C
 

/*--------------------------------------------------------------------------
 * gin_private.h
 *   header file for postgres inverted index access method implementation.
 *
 * Copyright (c) 2006-2025, PostgreSQL Global Development Group
 *
 * src/include/access/gin_private.h
 *--------------------------------------------------------------------------
 */

#ifndef GIN_PRIVATE_H
#define GIN_PRIVATE_H

#include "access/amapi.h"
#include "access/gin.h"
#include "access/ginblock.h"
#include "access/itup.h"
#include "common/int.h"
#include "catalog/pg_am_d.h"
#include "fmgr.h"
#include "lib/rbtree.h"
#include "storage/bufmgr.h"

/*
 * Storage type for GIN's reloptions
 */

typedef struct GinOptions
{
 int32  vl_len_;  /* varlena header (do not touch directly!) */
 bool  useFastUpdate; /* use fast updates? */
 int   pendingListCleanupSize; /* maximum size of pending list */
} GinOptions;

#define GIN_DEFAULT_USE_FASTUPDATE true
#define GinGetUseFastUpdate(relation) \
 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
     relation->rd_rel->relam == GIN_AM_OID), \
  (relation)->rd_options ? \
  ((GinOptions *) (relation)->rd_options)->useFastUpdate : GIN_DEFAULT_USE_FASTUPDATE)
#define GinGetPendingListCleanupSize(relation) \
 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
     relation->rd_rel->relam == GIN_AM_OID), \
  (relation)->rd_options && \
  ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize != -1 ? \
  ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize : \
  gin_pending_list_limit)


/* Macros for buffer lock/unlock operations */
#define GIN_UNLOCK BUFFER_LOCK_UNLOCK
#define GIN_SHARE BUFFER_LOCK_SHARE
#define GIN_EXCLUSIVE  BUFFER_LOCK_EXCLUSIVE


/*
 * GinState: working data structure describing the index being worked on
 */

typedef struct GinState
{
 Relation index;
 bool  oneCol;   /* true if single-column index */

 /*
  * origTupdesc is the nominal tuple descriptor of the index, ie, the i'th
  * attribute shows the key type (not the input data type!) of the i'th
  * index column.  In a single-column index this describes the actual leaf
  * index tuples.  In a multi-column index, the actual leaf tuples contain
  * a smallint column number followed by a key datum of the appropriate
  * type for that column.  We set up tupdesc[i] to describe the actual
  * rowtype of the index tuples for the i'th column, ie, (int2, keytype).
  * Note that in any case, leaf tuples contain more data than is known to
  * the TupleDesc; see access/gin/README for details.
 */

 TupleDesc origTupdesc;
 TupleDesc tupdesc[INDEX_MAX_KEYS];

 /*
  * Per-index-column opclass support functions
 */

 FmgrInfo compareFn[INDEX_MAX_KEYS];
 FmgrInfo extractValueFn[INDEX_MAX_KEYS];
 FmgrInfo extractQueryFn[INDEX_MAX_KEYS];
 FmgrInfo consistentFn[INDEX_MAX_KEYS];
 FmgrInfo triConsistentFn[INDEX_MAX_KEYS];
 FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */
 /* canPartialMatch[i] is true if comparePartialFn[i] is valid */
 bool  canPartialMatch[INDEX_MAX_KEYS];
 /* Collations to pass to the support functions */
 Oid   supportCollation[INDEX_MAX_KEYS];
} GinState;


/* ginutil.c */
extern bytea *ginoptions(Datum reloptions, bool validate);
extern void initGinState(GinState *state, Relation index);
extern Buffer GinNewBuffer(Relation index);
extern void GinInitBuffer(Buffer b, uint32 f);
extern void GinInitPage(Page page, uint32 f, Size pageSize);
extern void GinInitMetabuffer(Buffer b);
extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
         Datum a, GinNullCategory categorya,
         Datum b, GinNullCategory categoryb);
extern int ginCompareAttEntries(GinState *ginstate,
         OffsetNumber attnuma, Datum a, GinNullCategory categorya,
         OffsetNumber attnumb, Datum b, GinNullCategory categoryb);
extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
        Datum value, bool isNull,
        int32 *nentries, GinNullCategory **categories);

extern OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple);
extern Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple,
         GinNullCategory *category);
extern char *ginbuildphasename(int64 phasenum);

/* gininsert.c */
extern IndexBuildResult *ginbuild(Relation heap, Relation index,
          struct IndexInfo *indexInfo);
extern void ginbuildempty(Relation index);
extern bool gininsert(Relation index, Datum *values, bool *isnull,
       ItemPointer ht_ctid, Relation heapRel,
       IndexUniqueCheck checkUnique,
       bool indexUnchanged,
       struct IndexInfo *indexInfo);
extern void ginEntryInsert(GinState *ginstate,
         OffsetNumber attnum, Datum key, GinNullCategory category,
         ItemPointerData *items, uint32 nitem,
         GinStatsData *buildStats);

/* ginbtree.c */

typedef struct GinBtreeStack
{
 BlockNumber blkno;
 Buffer  buffer;
 OffsetNumber off;
 ItemPointerData iptr;
 /* predictNumber contains predicted number of pages on current level */
 uint32  predictNumber;
 struct GinBtreeStack *parent;
} GinBtreeStack;

typedef struct GinBtreeData *GinBtree;

/* Return codes for GinBtreeData.beginPlaceToPage method */
typedef enum
{
 GPTP_NO_WORK,
 GPTP_INSERT,
 GPTP_SPLIT,
} GinPlaceToPageRC;

typedef struct GinBtreeData
{
 /* search methods */
 BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
 BlockNumber (*getLeftMostChild) (GinBtree, Page);
 bool  (*isMoveRight) (GinBtree, Page);
 bool  (*findItem) (GinBtree, GinBtreeStack *);

 /* insert methods */
 OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
 GinPlaceToPageRC (*beginPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *);
 void  (*execPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void *);
 void    *(*prepareDownlink) (GinBtree, Buffer);
 void  (*fillRoot) (GinBtree, Page, BlockNumber, Page, BlockNumber, Page);

 bool  isData;

 Relation index;
 BlockNumber rootBlkno;
 GinState   *ginstate;  /* not valid in a data scan */
 bool  fullScan;
 bool  isBuild;

 /* Search key for Entry tree */
 OffsetNumber entryAttnum;
 Datum  entryKey;
 GinNullCategory entryCategory;

 /* Search key for data tree (posting tree) */
 ItemPointerData itemptr;
} GinBtreeData;

/* This represents a tuple to be inserted to entry tree. */
typedef struct
{
 IndexTuple entry;   /* tuple to insert */
 bool  isDelete;  /* delete old tuple at same offset? */
} GinBtreeEntryInsertData;

/*
 * This represents an itempointer, or many itempointers, to be inserted to
 * a data (posting tree) leaf page
 */

typedef struct
{
 ItemPointerData *items;
 uint32  nitem;
 uint32  curitem;
} GinBtreeDataLeafInsertData;

/*
 * For internal data (posting tree) pages, the insertion payload is a
 * PostingItem
 */


extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode,
           bool rootConflictCheck);
extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
extern void freeGinBtreeStack(GinBtreeStack *stack);
extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
         void *insertdata, GinStatsData *buildStats);

/* ginentrypage.c */
extern IndexTuple GinFormTuple(GinState *ginstate,
          OffsetNumber attnum, Datum key, GinNullCategory category,
          Pointer data, Size dataSize, int nipd, bool errorTooBig);
extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
        Datum key, GinNullCategory category,
        GinState *ginstate);
extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
        IndexTuple itup, int *nitems);

/* gindatapage.c */
extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
extern BlockNumber createPostingTree(Relation index,
          ItemPointerData *items, uint32 nitems,
          GinStatsData *buildStats, Buffer entrybuffer);
extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
          ItemPointerData *items, uint32 nitem,
          GinStatsData *buildStats);
extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno);
extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);

/*
 * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers
 * and ginVacuumPostingTreeLeaf and as an opaque struct, so we need a forward
 * declaration for it.
 */

typedef struct GinVacuumState GinVacuumState;

extern void ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer,
          GinVacuumState *gvs);

/* ginscan.c */

/*
 * GinScanKeyData describes a single GIN index qualifier expression.
 *
 * From each qual expression, we extract one or more specific index search
 * conditions, which are represented by GinScanEntryData.  It's quite
 * possible for identical search conditions to be requested by more than
 * one qual expression, in which case we merge such conditions to have just
 * one unique GinScanEntry --- this is particularly important for efficiency
 * when dealing with full-index-scan entries.  So there can be multiple
 * GinScanKeyData.scanEntry pointers to the same GinScanEntryData.
 *
 * In each GinScanKeyData, nentries is the true number of entries, while
 * nuserentries is the number that extractQueryFn returned (which is what
 * we report to consistentFn).  The "user" entries must come first.
 */

typedef struct GinScanKeyData *GinScanKey;

typedef struct GinScanEntryData *GinScanEntry;

typedef struct GinScanKeyData
{
 /* Real number of entries in scanEntry[] (always > 0) */
 uint32  nentries;
 /* Number of entries that extractQueryFn and consistentFn know about */
 uint32  nuserentries;

 /* array of GinScanEntry pointers, one per extracted search condition */
 GinScanEntry *scanEntry;

 /*
  * At least one of the entries in requiredEntries must be present for a
  * tuple to match the overall qual.
  *
  * additionalEntries contains entries that are needed by the consistent
  * function to decide if an item matches, but are not sufficient to
  * satisfy the qual without entries from requiredEntries.
 */

 GinScanEntry *requiredEntries;
 int   nrequired;
 GinScanEntry *additionalEntries;
 int   nadditional;

 /* array of check flags, reported to consistentFn */
 GinTernaryValue *entryRes;
 bool  (*boolConsistentFn) (GinScanKey key);
 GinTernaryValue (*triConsistentFn) (GinScanKey key);
 FmgrInfo   *consistentFmgrInfo;
 FmgrInfo   *triConsistentFmgrInfo;
 Oid   collation;

 /* other data needed for calling consistentFn */
 Datum  query;
 /* NB: these three arrays have only nuserentries elements! */
 Datum    *queryValues;
 GinNullCategory *queryCategories;
 Pointer    *extra_data;
 StrategyNumber strategy;
 int32  searchMode;
 OffsetNumber attnum;

 /*
  * An excludeOnly scan key is not able to enumerate all matching tuples.
  * That is, to be semantically correct on its own, it would need to have a
  * GIN_CAT_EMPTY_QUERY scanEntry, but it doesn't.  Such a key can still be
  * used to filter tuples returned by other scan keys, so we will get the
  * right answers as long as there's at least one non-excludeOnly scan key
  * for each index attribute considered by the search.  For efficiency
  * reasons we don't want to have unnecessary GIN_CAT_EMPTY_QUERY entries,
  * so we will convert an excludeOnly scan key to non-excludeOnly (by
  * adding a GIN_CAT_EMPTY_QUERY scanEntry) only if there are no other
  * non-excludeOnly scan keys.
 */

 bool  excludeOnly;

 /*
  * Match status data.  curItem is the TID most recently tested (could be a
  * lossy-page pointer).  curItemMatches is true if it passes the
  * consistentFn test; if so, recheckCurItem is the recheck flag.
  * isFinished means that all the input entry streams are finished, so this
  * key cannot succeed for any later TIDs.
 */

 ItemPointerData curItem;
 bool  curItemMatches;
 bool  recheckCurItem;
 bool  isFinished;
}   GinScanKeyData;

typedef struct GinScanEntryData
{
 /* query key and other information from extractQueryFn */
 Datum  queryKey;
 GinNullCategory queryCategory;
 bool  isPartialMatch;
 Pointer  extra_data;
 StrategyNumber strategy;
 int32  searchMode;
 OffsetNumber attnum;

 /* Current page in posting tree */
 Buffer  buffer;

 /* current ItemPointer to heap */
 ItemPointerData curItem;

 /* for a partial-match or full-scan query, we accumulate all TIDs here */
 TIDBitmap  *matchBitmap;
 TBMPrivateIterator *matchIterator;

 /*
  * If blockno is InvalidBlockNumber, all of the other fields in the
  * matchResult are meaningless.
 */

 TBMIterateResult matchResult;
 OffsetNumber matchOffsets[TBM_MAX_TUPLES_PER_PAGE];
 int   matchNtuples;

 /* used for Posting list and one page in Posting tree */
 ItemPointerData *list;
 int   nlist;
 OffsetNumber offset;

 bool  isFinished;
 bool  reduceResult;
 uint32  predictNumberResult;
 GinBtreeData btree;
}   GinScanEntryData;

typedef struct GinScanOpaqueData
{
 MemoryContext tempCtx;
 GinState ginstate;

 GinScanKey keys;   /* one per scan qualifier expr */
 uint32  nkeys;

 GinScanEntry *entries;  /* one per index search condition */
 uint32  totalentries;
 uint32  allocentries; /* allocated length of entries[] */

 MemoryContext keyCtx;  /* used to hold key and entry data */

 bool  isVoidRes;  /* true if query is unsatisfiable */
} GinScanOpaqueData;

typedef GinScanOpaqueData *GinScanOpaque;

extern IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys);
extern void ginendscan(IndexScanDesc scan);
extern void ginrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
       ScanKey orderbys, int norderbys);
extern void ginNewScanKey(IndexScanDesc scan);
extern void ginFreeScanKeys(GinScanOpaque so);

/* ginget.c */
extern int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm);

/* ginlogic.c */
extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key);

/* ginvacuum.c */
extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info,
           IndexBulkDeleteResult *stats,
           IndexBulkDeleteCallback callback,
           void *callback_state);
extern IndexBulkDeleteResult *ginvacuumcleanup(IndexVacuumInfo *info,
              IndexBulkDeleteResult *stats);
extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs,
           ItemPointerData *items, int nitem, int *nremaining);

/* ginvalidate.c */
extern bool ginvalidate(Oid opclassoid);
extern void ginadjustmembers(Oid opfamilyoid,
        Oid opclassoid,
        List *operators,
        List *functions);

/* ginbulk.c */
typedef struct GinEntryAccumulator
{
 RBTNode  rbtnode;
 Datum  key;
 GinNullCategory category;
 OffsetNumber attnum;
 bool  shouldSort;
 ItemPointerData *list;
 uint32  maxcount;  /* allocated size of list[] */
 uint32  count;   /* current number of list[] entries */
} GinEntryAccumulator;

typedef struct
{
 GinState   *ginstate;
 Size  allocatedMemory;
 GinEntryAccumulator *entryallocator;
 uint32  eas_used;
 RBTree    *tree;
 RBTreeIterator tree_walk;
} BuildAccumulator;

extern void ginInitBA(BuildAccumulator *accum);
extern void ginInsertBAEntries(BuildAccumulator *accum,
          ItemPointer heapptr, OffsetNumber attnum,
          Datum *entries, GinNullCategory *categories,
          int32 nentries);
extern void ginBeginBAScan(BuildAccumulator *accum);
extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum,
           OffsetNumber *attnum, Datum *key, GinNullCategory *category,
           uint32 *n);

/* ginfast.c */

typedef struct GinTupleCollector
{
 IndexTuple *tuples;
 uint32  ntuples;
 uint32  lentuples;
 uint32  sumsize;
} GinTupleCollector;

extern void ginHeapTupleFastInsert(GinState *ginstate,
           GinTupleCollector *collector);
extern void ginHeapTupleFastCollect(GinState *ginstate,
         GinTupleCollector *collector,
         OffsetNumber attnum, Datum value, bool isNull,
         ItemPointer ht_ctid);
extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
        bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);

/* ginpostinglist.c */

extern GinPostingList *ginCompressPostingList(const ItemPointer ipd, int nipd,
             int maxsize, int *nwritten);
extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int len, TIDBitmap *tbm);

extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *segment, int len,
               int *ndecoded_out);
extern ItemPointer ginPostingListDecode(GinPostingList *plist, int *ndecoded_out);
extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na,
          ItemPointerData *b, uint32 nb,
          int *nmerged);

/*
 * Merging the results of several gin scans compares item pointers a lot,
 * so we want this to be inlined.
 */

static inline int
ginCompareItemPointers(ItemPointer a, ItemPointer b)
{
 uint64  ia = (uint64) GinItemPointerGetBlockNumber(a) << 32 | GinItemPointerGetOffsetNumber(a);
 uint64  ib = (uint64) GinItemPointerGetBlockNumber(b) << 32 | GinItemPointerGetOffsetNumber(b);

 return pg_cmp_u64(ia, ib);
}

extern int ginTraverseLock(Buffer buffer, bool searchMode);

#endif       /* GIN_PRIVATE_H */

Messung V0.5 in Prozent
C=78 H=98 G=88

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.15Angebot  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-08) ¤

*Eine klare Vorstellung vom Zielzustand






Versionsinformation zu Columbo

Bemerkung:

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Anfrage:

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

letze Version des Elbe Quellennavigators


Jenseits des Üblichen ....
    

Besucher

Besucher

Statistik
#Sources=141584
#Domains=752002