1 /*------------------------------------------------------------------------- 2 * 3 * bloom.h 4 * Header for bloom index. 5 * 6 * Copyright (c) 2016-2020, PostgreSQL Global Development Group 7 * 8 * IDENTIFICATION 9 * contrib/bloom/bloom.h 10 * 11 *------------------------------------------------------------------------- 12 */ 13 #ifndef _BLOOM_H_ 14 #define _BLOOM_H_ 15 16 #include "access/amapi.h" 17 #include "access/generic_xlog.h" 18 #include "access/itup.h" 19 #include "access/xlog.h" 20 #include "fmgr.h" 21 #include "nodes/pathnodes.h" 22 23 /* Support procedures numbers */ 24 #define BLOOM_HASH_PROC 1 25 #define BLOOM_OPTIONS_PROC 2 26 #define BLOOM_NPROC 2 27 28 /* Scan strategies */ 29 #define BLOOM_EQUAL_STRATEGY 1 30 #define BLOOM_NSTRATEGIES 1 31 32 /* Opaque for bloom pages */ 33 typedef struct BloomPageOpaqueData 34 { 35 OffsetNumber maxoff; /* number of index tuples on page */ 36 uint16 flags; /* see bit definitions below */ 37 uint16 unused; /* placeholder to force maxaligning of size of 38 * BloomPageOpaqueData and to place 39 * bloom_page_id exactly at the end of page */ 40 uint16 bloom_page_id; /* for identification of BLOOM indexes */ 41 } BloomPageOpaqueData; 42 43 typedef BloomPageOpaqueData *BloomPageOpaque; 44 45 /* Bloom page flags */ 46 #define BLOOM_META (1<<0) 47 #define BLOOM_DELETED (2<<0) 48 49 /* 50 * The page ID is for the convenience of pg_filedump and similar utilities, 51 * which otherwise would have a hard time telling pages of different index 52 * types apart. It should be the last 2 bytes on the page. This is more or 53 * less "free" due to alignment considerations. 54 * 55 * See comments above GinPageOpaqueData. 56 */ 57 #define BLOOM_PAGE_ID 0xFF83 58 59 /* Macros for accessing bloom page structures */ 60 #define BloomPageGetOpaque(page) ((BloomPageOpaque) PageGetSpecialPointer(page)) 61 #define BloomPageGetMaxOffset(page) (BloomPageGetOpaque(page)->maxoff) 62 #define BloomPageIsMeta(page) \ 63 ((BloomPageGetOpaque(page)->flags & BLOOM_META) != 0) 64 #define BloomPageIsDeleted(page) \ 65 ((BloomPageGetOpaque(page)->flags & BLOOM_DELETED) != 0) 66 #define BloomPageSetDeleted(page) \ 67 (BloomPageGetOpaque(page)->flags |= BLOOM_DELETED) 68 #define BloomPageSetNonDeleted(page) \ 69 (BloomPageGetOpaque(page)->flags &= ~BLOOM_DELETED) 70 #define BloomPageGetData(page) ((BloomTuple *)PageGetContents(page)) 71 #define BloomPageGetTuple(state, page, offset) \ 72 ((BloomTuple *)(PageGetContents(page) \ 73 + (state)->sizeOfBloomTuple * ((offset) - 1))) 74 #define BloomPageGetNextTuple(state, tuple) \ 75 ((BloomTuple *)((Pointer)(tuple) + (state)->sizeOfBloomTuple)) 76 77 /* Preserved page numbers */ 78 #define BLOOM_METAPAGE_BLKNO (0) 79 #define BLOOM_HEAD_BLKNO (1) /* first data page */ 80 81 /* 82 * We store Bloom signatures as arrays of uint16 words. 83 */ 84 typedef uint16 BloomSignatureWord; 85 86 #define SIGNWORDBITS ((int) (BITS_PER_BYTE * sizeof(BloomSignatureWord))) 87 88 /* 89 * Default and maximum Bloom signature length in bits. 90 */ 91 #define DEFAULT_BLOOM_LENGTH (5 * SIGNWORDBITS) 92 #define MAX_BLOOM_LENGTH (256 * SIGNWORDBITS) 93 94 /* 95 * Default and maximum signature bits generated per index key. 96 */ 97 #define DEFAULT_BLOOM_BITS 2 98 #define MAX_BLOOM_BITS (MAX_BLOOM_LENGTH - 1) 99 100 /* Bloom index options */ 101 typedef struct BloomOptions 102 { 103 int32 vl_len_; /* varlena header (do not touch directly!) */ 104 int bloomLength; /* length of signature in words (not bits!) */ 105 int bitSize[INDEX_MAX_KEYS]; /* # of bits generated for each 106 * index key */ 107 } BloomOptions; 108 109 /* 110 * FreeBlockNumberArray - array of block numbers sized so that metadata fill 111 * all space in metapage. 112 */ 113 typedef BlockNumber FreeBlockNumberArray[ 114 MAXALIGN_DOWN( 115 BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) 116 - MAXALIGN(sizeof(uint16) * 2 + sizeof(uint32) + sizeof(BloomOptions)) 117 ) / sizeof(BlockNumber) 118 ]; 119 120 /* Metadata of bloom index */ 121 typedef struct BloomMetaPageData 122 { 123 uint32 magickNumber; 124 uint16 nStart; 125 uint16 nEnd; 126 BloomOptions opts; 127 FreeBlockNumberArray notFullPage; 128 } BloomMetaPageData; 129 130 /* Magic number to distinguish bloom pages among anothers */ 131 #define BLOOM_MAGICK_NUMBER (0xDBAC0DED) 132 133 /* Number of blocks numbers fit in BloomMetaPageData */ 134 #define BloomMetaBlockN (sizeof(FreeBlockNumberArray) / sizeof(BlockNumber)) 135 136 #define BloomPageGetMeta(page) ((BloomMetaPageData *) PageGetContents(page)) 137 138 typedef struct BloomState 139 { 140 FmgrInfo hashFn[INDEX_MAX_KEYS]; 141 Oid collations[INDEX_MAX_KEYS]; 142 BloomOptions opts; /* copy of options on index's metapage */ 143 int32 nColumns; 144 145 /* 146 * sizeOfBloomTuple is index-specific, and it depends on reloptions, so 147 * precompute it 148 */ 149 Size sizeOfBloomTuple; 150 } BloomState; 151 152 #define BloomPageGetFreeSpace(state, page) \ 153 (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \ 154 - BloomPageGetMaxOffset(page) * (state)->sizeOfBloomTuple \ 155 - MAXALIGN(sizeof(BloomPageOpaqueData))) 156 157 /* 158 * Tuples are very different from all other relations 159 */ 160 typedef struct BloomTuple 161 { 162 ItemPointerData heapPtr; 163 BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]; 164 } BloomTuple; 165 166 #define BLOOMTUPLEHDRSZ offsetof(BloomTuple, sign) 167 168 /* Opaque data structure for bloom index scan */ 169 typedef struct BloomScanOpaqueData 170 { 171 BloomSignatureWord *sign; /* Scan signature */ 172 BloomState state; 173 } BloomScanOpaqueData; 174 175 typedef BloomScanOpaqueData *BloomScanOpaque; 176 177 /* blutils.c */ 178 extern void _PG_init(void); 179 extern void initBloomState(BloomState *state, Relation index); 180 extern void BloomFillMetapage(Relation index, Page metaPage); 181 extern void BloomInitMetapage(Relation index); 182 extern void BloomInitPage(Page page, uint16 flags); 183 extern Buffer BloomNewBuffer(Relation index); 184 extern void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno); 185 extern BloomTuple *BloomFormTuple(BloomState *state, ItemPointer iptr, Datum *values, bool *isnull); 186 extern bool BloomPageAddItem(BloomState *state, Page page, BloomTuple *tuple); 187 188 /* blvalidate.c */ 189 extern bool blvalidate(Oid opclassoid); 190 191 /* index access method interface functions */ 192 extern bool blinsert(Relation index, Datum *values, bool *isnull, 193 ItemPointer ht_ctid, Relation heapRel, 194 IndexUniqueCheck checkUnique, 195 struct IndexInfo *indexInfo); 196 extern IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys); 197 extern int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); 198 extern void blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, 199 ScanKey orderbys, int norderbys); 200 extern void blendscan(IndexScanDesc scan); 201 extern IndexBuildResult *blbuild(Relation heap, Relation index, 202 struct IndexInfo *indexInfo); 203 extern void blbuildempty(Relation index); 204 extern IndexBulkDeleteResult *blbulkdelete(IndexVacuumInfo *info, 205 IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, 206 void *callback_state); 207 extern IndexBulkDeleteResult *blvacuumcleanup(IndexVacuumInfo *info, 208 IndexBulkDeleteResult *stats); 209 extern bytea *bloptions(Datum reloptions, bool validate); 210 extern void blcostestimate(PlannerInfo *root, IndexPath *path, 211 double loop_count, Cost *indexStartupCost, 212 Cost *indexTotalCost, Selectivity *indexSelectivity, 213 double *indexCorrelation, double *indexPages); 214 215 #endif 216