gooderp18绿色标准版
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

477 lines
16KB

  1. /*--------------------------------------------------------------------------
  2. * gin_private.h
  3. * header file for postgres inverted index access method implementation.
  4. *
  5. * Copyright (c) 2006-2019, PostgreSQL Global Development Group
  6. *
  7. * src/include/access/gin_private.h
  8. *--------------------------------------------------------------------------
  9. */
  10. #ifndef GIN_PRIVATE_H
  11. #define GIN_PRIVATE_H
  12. #include "access/amapi.h"
  13. #include "access/gin.h"
  14. #include "access/ginblock.h"
  15. #include "access/itup.h"
  16. #include "fmgr.h"
  17. #include "storage/bufmgr.h"
  18. #include "lib/rbtree.h"
  19. /*
  20. * Storage type for GIN's reloptions
  21. */
  22. typedef struct GinOptions
  23. {
  24. int32 vl_len_; /* varlena header (do not touch directly!) */
  25. bool useFastUpdate; /* use fast updates? */
  26. int pendingListCleanupSize; /* maximum size of pending list */
  27. } GinOptions;
  28. #define GIN_DEFAULT_USE_FASTUPDATE true
  29. #define GinGetUseFastUpdate(relation) \
  30. ((relation)->rd_options ? \
  31. ((GinOptions *) (relation)->rd_options)->useFastUpdate : GIN_DEFAULT_USE_FASTUPDATE)
  32. #define GinGetPendingListCleanupSize(relation) \
  33. ((relation)->rd_options && \
  34. ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize != -1 ? \
  35. ((GinOptions *) (relation)->rd_options)->pendingListCleanupSize : \
  36. gin_pending_list_limit)
  37. /* Macros for buffer lock/unlock operations */
  38. #define GIN_UNLOCK BUFFER_LOCK_UNLOCK
  39. #define GIN_SHARE BUFFER_LOCK_SHARE
  40. #define GIN_EXCLUSIVE BUFFER_LOCK_EXCLUSIVE
  41. /*
  42. * GinState: working data structure describing the index being worked on
  43. */
  44. typedef struct GinState
  45. {
  46. Relation index;
  47. bool oneCol; /* true if single-column index */
  48. /*
  49. * origTupDesc is the nominal tuple descriptor of the index, ie, the i'th
  50. * attribute shows the key type (not the input data type!) of the i'th
  51. * index column. In a single-column index this describes the actual leaf
  52. * index tuples. In a multi-column index, the actual leaf tuples contain
  53. * a smallint column number followed by a key datum of the appropriate
  54. * type for that column. We set up tupdesc[i] to describe the actual
  55. * rowtype of the index tuples for the i'th column, ie, (int2, keytype).
  56. * Note that in any case, leaf tuples contain more data than is known to
  57. * the TupleDesc; see access/gin/README for details.
  58. */
  59. TupleDesc origTupdesc;
  60. TupleDesc tupdesc[INDEX_MAX_KEYS];
  61. /*
  62. * Per-index-column opclass support functions
  63. */
  64. FmgrInfo compareFn[INDEX_MAX_KEYS];
  65. FmgrInfo extractValueFn[INDEX_MAX_KEYS];
  66. FmgrInfo extractQueryFn[INDEX_MAX_KEYS];
  67. FmgrInfo consistentFn[INDEX_MAX_KEYS];
  68. FmgrInfo triConsistentFn[INDEX_MAX_KEYS];
  69. FmgrInfo comparePartialFn[INDEX_MAX_KEYS]; /* optional method */
  70. /* canPartialMatch[i] is true if comparePartialFn[i] is valid */
  71. bool canPartialMatch[INDEX_MAX_KEYS];
  72. /* Collations to pass to the support functions */
  73. Oid supportCollation[INDEX_MAX_KEYS];
  74. } GinState;
  75. /* ginutil.c */
  76. extern bytea *ginoptions(Datum reloptions, bool validate);
  77. extern void initGinState(GinState *state, Relation index);
  78. extern Buffer GinNewBuffer(Relation index);
  79. extern void GinInitBuffer(Buffer b, uint32 f);
  80. extern void GinInitPage(Page page, uint32 f, Size pageSize);
  81. extern void GinInitMetabuffer(Buffer b);
  82. extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum,
  83. Datum a, GinNullCategory categorya,
  84. Datum b, GinNullCategory categoryb);
  85. extern int ginCompareAttEntries(GinState *ginstate,
  86. OffsetNumber attnuma, Datum a, GinNullCategory categorya,
  87. OffsetNumber attnumb, Datum b, GinNullCategory categoryb);
  88. extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum,
  89. Datum value, bool isNull,
  90. int32 *nentries, GinNullCategory **categories);
  91. extern OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple);
  92. extern Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple,
  93. GinNullCategory *category);
  94. /* gininsert.c */
  95. extern IndexBuildResult *ginbuild(Relation heap, Relation index,
  96. struct IndexInfo *indexInfo);
  97. extern void ginbuildempty(Relation index);
  98. extern bool gininsert(Relation index, Datum *values, bool *isnull,
  99. ItemPointer ht_ctid, Relation heapRel,
  100. IndexUniqueCheck checkUnique,
  101. struct IndexInfo *indexInfo);
  102. extern void ginEntryInsert(GinState *ginstate,
  103. OffsetNumber attnum, Datum key, GinNullCategory category,
  104. ItemPointerData *items, uint32 nitem,
  105. GinStatsData *buildStats);
  106. /* ginbtree.c */
  107. typedef struct GinBtreeStack
  108. {
  109. BlockNumber blkno;
  110. Buffer buffer;
  111. OffsetNumber off;
  112. ItemPointerData iptr;
  113. /* predictNumber contains predicted number of pages on current level */
  114. uint32 predictNumber;
  115. struct GinBtreeStack *parent;
  116. } GinBtreeStack;
  117. typedef struct GinBtreeData *GinBtree;
  118. /* Return codes for GinBtreeData.beginPlaceToPage method */
  119. typedef enum
  120. {
  121. GPTP_NO_WORK,
  122. GPTP_INSERT,
  123. GPTP_SPLIT
  124. } GinPlaceToPageRC;
  125. typedef struct GinBtreeData
  126. {
  127. /* search methods */
  128. BlockNumber (*findChildPage) (GinBtree, GinBtreeStack *);
  129. BlockNumber (*getLeftMostChild) (GinBtree, Page);
  130. bool (*isMoveRight) (GinBtree, Page);
  131. bool (*findItem) (GinBtree, GinBtreeStack *);
  132. /* insert methods */
  133. OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
  134. GinPlaceToPageRC (*beginPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void **, Page *, Page *);
  135. void (*execPlaceToPage) (GinBtree, Buffer, GinBtreeStack *, void *, BlockNumber, void *);
  136. void *(*prepareDownlink) (GinBtree, Buffer);
  137. void (*fillRoot) (GinBtree, Page, BlockNumber, Page, BlockNumber, Page);
  138. bool isData;
  139. Relation index;
  140. BlockNumber rootBlkno;
  141. GinState *ginstate; /* not valid in a data scan */
  142. bool fullScan;
  143. bool isBuild;
  144. /* Search key for Entry tree */
  145. OffsetNumber entryAttnum;
  146. Datum entryKey;
  147. GinNullCategory entryCategory;
  148. /* Search key for data tree (posting tree) */
  149. ItemPointerData itemptr;
  150. } GinBtreeData;
  151. /* This represents a tuple to be inserted to entry tree. */
  152. typedef struct
  153. {
  154. IndexTuple entry; /* tuple to insert */
  155. bool isDelete; /* delete old tuple at same offset? */
  156. } GinBtreeEntryInsertData;
  157. /*
  158. * This represents an itempointer, or many itempointers, to be inserted to
  159. * a data (posting tree) leaf page
  160. */
  161. typedef struct
  162. {
  163. ItemPointerData *items;
  164. uint32 nitem;
  165. uint32 curitem;
  166. } GinBtreeDataLeafInsertData;
  167. /*
  168. * For internal data (posting tree) pages, the insertion payload is a
  169. * PostingItem
  170. */
  171. extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode,
  172. bool rootConflictCheck, Snapshot snapshot);
  173. extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode);
  174. extern void freeGinBtreeStack(GinBtreeStack *stack);
  175. extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack,
  176. void *insertdata, GinStatsData *buildStats);
  177. /* ginentrypage.c */
  178. extern IndexTuple GinFormTuple(GinState *ginstate,
  179. OffsetNumber attnum, Datum key, GinNullCategory category,
  180. Pointer data, Size dataSize, int nipd, bool errorTooBig);
  181. extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
  182. Datum key, GinNullCategory category,
  183. GinState *ginstate);
  184. extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
  185. extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum,
  186. IndexTuple itup, int *nitems);
  187. /* gindatapage.c */
  188. extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast);
  189. extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm);
  190. extern BlockNumber createPostingTree(Relation index,
  191. ItemPointerData *items, uint32 nitems,
  192. GinStatsData *buildStats, Buffer entrybuffer);
  193. extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
  194. extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
  195. extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno,
  196. ItemPointerData *items, uint32 nitem,
  197. GinStatsData *buildStats);
  198. extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, Snapshot snapshot);
  199. extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage);
  200. /*
  201. * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers
  202. * and ginVacuumPostingTreeLeaf and as an opaque struct, so we need a forward
  203. * declaration for it.
  204. */
  205. typedef struct GinVacuumState GinVacuumState;
  206. extern void ginVacuumPostingTreeLeaf(Relation rel, Buffer buf, GinVacuumState *gvs);
  207. /* ginscan.c */
  208. /*
  209. * GinScanKeyData describes a single GIN index qualifier expression.
  210. *
  211. * From each qual expression, we extract one or more specific index search
  212. * conditions, which are represented by GinScanEntryData. It's quite
  213. * possible for identical search conditions to be requested by more than
  214. * one qual expression, in which case we merge such conditions to have just
  215. * one unique GinScanEntry --- this is particularly important for efficiency
  216. * when dealing with full-index-scan entries. So there can be multiple
  217. * GinScanKeyData.scanEntry pointers to the same GinScanEntryData.
  218. *
  219. * In each GinScanKeyData, nentries is the true number of entries, while
  220. * nuserentries is the number that extractQueryFn returned (which is what
  221. * we report to consistentFn). The "user" entries must come first.
  222. */
  223. typedef struct GinScanKeyData *GinScanKey;
  224. typedef struct GinScanEntryData *GinScanEntry;
  225. typedef struct GinScanKeyData
  226. {
  227. /* Real number of entries in scanEntry[] (always > 0) */
  228. uint32 nentries;
  229. /* Number of entries that extractQueryFn and consistentFn know about */
  230. uint32 nuserentries;
  231. /* array of GinScanEntry pointers, one per extracted search condition */
  232. GinScanEntry *scanEntry;
  233. /*
  234. * At least one of the entries in requiredEntries must be present for a
  235. * tuple to match the overall qual.
  236. *
  237. * additionalEntries contains entries that are needed by the consistent
  238. * function to decide if an item matches, but are not sufficient to
  239. * satisfy the qual without entries from requiredEntries.
  240. */
  241. GinScanEntry *requiredEntries;
  242. int nrequired;
  243. GinScanEntry *additionalEntries;
  244. int nadditional;
  245. /* array of check flags, reported to consistentFn */
  246. GinTernaryValue *entryRes;
  247. bool (*boolConsistentFn) (GinScanKey key);
  248. GinTernaryValue (*triConsistentFn) (GinScanKey key);
  249. FmgrInfo *consistentFmgrInfo;
  250. FmgrInfo *triConsistentFmgrInfo;
  251. Oid collation;
  252. /* other data needed for calling consistentFn */
  253. Datum query;
  254. /* NB: these three arrays have only nuserentries elements! */
  255. Datum *queryValues;
  256. GinNullCategory *queryCategories;
  257. Pointer *extra_data;
  258. StrategyNumber strategy;
  259. int32 searchMode;
  260. OffsetNumber attnum;
  261. /*
  262. * Match status data. curItem is the TID most recently tested (could be a
  263. * lossy-page pointer). curItemMatches is true if it passes the
  264. * consistentFn test; if so, recheckCurItem is the recheck flag.
  265. * isFinished means that all the input entry streams are finished, so this
  266. * key cannot succeed for any later TIDs.
  267. */
  268. ItemPointerData curItem;
  269. bool curItemMatches;
  270. bool recheckCurItem;
  271. bool isFinished;
  272. } GinScanKeyData;
  273. typedef struct GinScanEntryData
  274. {
  275. /* query key and other information from extractQueryFn */
  276. Datum queryKey;
  277. GinNullCategory queryCategory;
  278. bool isPartialMatch;
  279. Pointer extra_data;
  280. StrategyNumber strategy;
  281. int32 searchMode;
  282. OffsetNumber attnum;
  283. /* Current page in posting tree */
  284. Buffer buffer;
  285. /* current ItemPointer to heap */
  286. ItemPointerData curItem;
  287. /* for a partial-match or full-scan query, we accumulate all TIDs here */
  288. TIDBitmap *matchBitmap;
  289. TBMIterator *matchIterator;
  290. TBMIterateResult *matchResult;
  291. /* used for Posting list and one page in Posting tree */
  292. ItemPointerData *list;
  293. int nlist;
  294. OffsetNumber offset;
  295. bool isFinished;
  296. bool reduceResult;
  297. uint32 predictNumberResult;
  298. GinBtreeData btree;
  299. } GinScanEntryData;
  300. typedef struct GinScanOpaqueData
  301. {
  302. MemoryContext tempCtx;
  303. GinState ginstate;
  304. GinScanKey keys; /* one per scan qualifier expr */
  305. uint32 nkeys;
  306. GinScanEntry *entries; /* one per index search condition */
  307. uint32 totalentries;
  308. uint32 allocentries; /* allocated length of entries[] */
  309. MemoryContext keyCtx; /* used to hold key and entry data */
  310. bool isVoidRes; /* true if query is unsatisfiable */
  311. } GinScanOpaqueData;
  312. typedef GinScanOpaqueData *GinScanOpaque;
  313. extern IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys);
  314. extern void ginendscan(IndexScanDesc scan);
  315. extern void ginrescan(IndexScanDesc scan, ScanKey key, int nscankeys,
  316. ScanKey orderbys, int norderbys);
  317. extern void ginNewScanKey(IndexScanDesc scan);
  318. extern void ginFreeScanKeys(GinScanOpaque so);
  319. /* ginget.c */
  320. extern int64 gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
  321. /* ginlogic.c */
  322. extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key);
  323. /* ginvacuum.c */
  324. extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info,
  325. IndexBulkDeleteResult *stats,
  326. IndexBulkDeleteCallback callback,
  327. void *callback_state);
  328. extern IndexBulkDeleteResult *ginvacuumcleanup(IndexVacuumInfo *info,
  329. IndexBulkDeleteResult *stats);
  330. extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs,
  331. ItemPointerData *items, int nitem, int *nremaining);
  332. /* ginvalidate.c */
  333. extern bool ginvalidate(Oid opclassoid);
  334. /* ginbulk.c */
  335. typedef struct GinEntryAccumulator
  336. {
  337. RBTNode rbtnode;
  338. Datum key;
  339. GinNullCategory category;
  340. OffsetNumber attnum;
  341. bool shouldSort;
  342. ItemPointerData *list;
  343. uint32 maxcount; /* allocated size of list[] */
  344. uint32 count; /* current number of list[] entries */
  345. } GinEntryAccumulator;
  346. typedef struct
  347. {
  348. GinState *ginstate;
  349. Size allocatedMemory;
  350. GinEntryAccumulator *entryallocator;
  351. uint32 eas_used;
  352. RBTree *tree;
  353. RBTreeIterator tree_walk;
  354. } BuildAccumulator;
  355. extern void ginInitBA(BuildAccumulator *accum);
  356. extern void ginInsertBAEntries(BuildAccumulator *accum,
  357. ItemPointer heapptr, OffsetNumber attnum,
  358. Datum *entries, GinNullCategory *categories,
  359. int32 nentries);
  360. extern void ginBeginBAScan(BuildAccumulator *accum);
  361. extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum,
  362. OffsetNumber *attnum, Datum *key, GinNullCategory *category,
  363. uint32 *n);
  364. /* ginfast.c */
  365. typedef struct GinTupleCollector
  366. {
  367. IndexTuple *tuples;
  368. uint32 ntuples;
  369. uint32 lentuples;
  370. uint32 sumsize;
  371. } GinTupleCollector;
  372. extern void ginHeapTupleFastInsert(GinState *ginstate,
  373. GinTupleCollector *collector);
  374. extern void ginHeapTupleFastCollect(GinState *ginstate,
  375. GinTupleCollector *collector,
  376. OffsetNumber attnum, Datum value, bool isNull,
  377. ItemPointer ht_ctid);
  378. extern void ginInsertCleanup(GinState *ginstate, bool full_clean,
  379. bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats);
  380. /* ginpostinglist.c */
  381. extern GinPostingList *ginCompressPostingList(const ItemPointer ptrs, int nptrs,
  382. int maxsize, int *nwritten);
  383. extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int totalsize, TIDBitmap *tbm);
  384. extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *ptr, int len, int *ndecoded);
  385. extern ItemPointer ginPostingListDecode(GinPostingList *ptr, int *ndecoded);
  386. extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na,
  387. ItemPointerData *b, uint32 nb,
  388. int *nmerged);
  389. /*
  390. * Merging the results of several gin scans compares item pointers a lot,
  391. * so we want this to be inlined.
  392. */
  393. static inline int
  394. ginCompareItemPointers(ItemPointer a, ItemPointer b)
  395. {
  396. uint64 ia = (uint64) GinItemPointerGetBlockNumber(a) << 32 | GinItemPointerGetOffsetNumber(a);
  397. uint64 ib = (uint64) GinItemPointerGetBlockNumber(b) << 32 | GinItemPointerGetOffsetNumber(b);
  398. if (ia == ib)
  399. return 0;
  400. else if (ia > ib)
  401. return 1;
  402. else
  403. return -1;
  404. }
  405. extern int ginTraverseLock(Buffer buffer, bool searchMode);
  406. #endif /* GIN_PRIVATE_H */
上海开阖软件有限公司 沪ICP备12045867号-1