PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bloom.h File Reference
#include "access/amapi.h"
#include "access/generic_xlog.h"
#include "access/itup.h"
#include "access/xlog.h"
#include "fmgr.h"
#include "nodes/pathnodes.h"
Include dependency graph for bloom.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  BloomPageOpaqueData
 
struct  BloomOptions
 
struct  BloomMetaPageData
 
struct  BloomState
 
struct  BloomTuple
 
struct  BloomScanOpaqueData
 

Macros

#define BLOOM_HASH_PROC   1
 
#define BLOOM_OPTIONS_PROC   2
 
#define BLOOM_NPROC   2
 
#define BLOOM_EQUAL_STRATEGY   1
 
#define BLOOM_NSTRATEGIES   1
 
#define BLOOM_META   (1<<0)
 
#define BLOOM_DELETED   (2<<0)
 
#define BLOOM_PAGE_ID   0xFF83
 
#define BloomPageGetOpaque(page)   ((BloomPageOpaque) PageGetSpecialPointer(page))
 
#define BloomPageGetMaxOffset(page)   (BloomPageGetOpaque(page)->maxoff)
 
#define BloomPageIsMeta(page)    ((BloomPageGetOpaque(page)->flags & BLOOM_META) != 0)
 
#define BloomPageIsDeleted(page)    ((BloomPageGetOpaque(page)->flags & BLOOM_DELETED) != 0)
 
#define BloomPageSetDeleted(page)    (BloomPageGetOpaque(page)->flags |= BLOOM_DELETED)
 
#define BloomPageSetNonDeleted(page)    (BloomPageGetOpaque(page)->flags &= ~BLOOM_DELETED)
 
#define BloomPageGetData(page)   ((BloomTuple *)PageGetContents(page))
 
#define BloomPageGetTuple(state, page, offset)
 
#define BloomPageGetNextTuple(state, tuple)    ((BloomTuple *)((Pointer)(tuple) + (state)->sizeOfBloomTuple))
 
#define BLOOM_METAPAGE_BLKNO   (0)
 
#define BLOOM_HEAD_BLKNO   (1) /* first data page */
 
#define SIGNWORDBITS   ((int) (BITS_PER_BYTE * sizeof(BloomSignatureWord)))
 
#define DEFAULT_BLOOM_LENGTH   (5 * SIGNWORDBITS)
 
#define MAX_BLOOM_LENGTH   (256 * SIGNWORDBITS)
 
#define DEFAULT_BLOOM_BITS   2
 
#define MAX_BLOOM_BITS   (MAX_BLOOM_LENGTH - 1)
 
#define BLOOM_MAGICK_NUMBER   (0xDBAC0DED)
 
#define BloomMetaBlockN   (sizeof(FreeBlockNumberArray) / sizeof(BlockNumber))
 
#define BloomPageGetMeta(page)   ((BloomMetaPageData *) PageGetContents(page))
 
#define BloomPageGetFreeSpace(state, page)
 
#define BLOOMTUPLEHDRSZ   offsetof(BloomTuple, sign)
 

Typedefs

typedef struct BloomPageOpaqueData BloomPageOpaqueData
 
typedef BloomPageOpaqueDataBloomPageOpaque
 
typedef uint16 BloomSignatureWord
 
typedef struct BloomOptions BloomOptions
 
typedef BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) - MAXALIGN(sizeof(uint16) *2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]
 
typedef struct BloomMetaPageData BloomMetaPageData
 
typedef struct BloomState BloomState
 
typedef struct BloomTuple BloomTuple
 
typedef struct BloomScanOpaqueData BloomScanOpaqueData
 
typedef BloomScanOpaqueDataBloomScanOpaque
 

Functions

void initBloomState (BloomState *state, Relation index)
 
void BloomFillMetapage (Relation index, Page metaPage)
 
void BloomInitMetapage (Relation index, ForkNumber forknum)
 
void BloomInitPage (Page page, uint16 flags)
 
Buffer BloomNewBuffer (Relation index)
 
void signValue (BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
 
BloomTupleBloomFormTuple (BloomState *state, ItemPointer iptr, Datum *values, bool *isnull)
 
bool BloomPageAddItem (BloomState *state, Page page, BloomTuple *tuple)
 
bool blvalidate (Oid opclassoid)
 
bool blinsert (Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo)
 
IndexScanDesc blbeginscan (Relation r, int nkeys, int norderbys)
 
int64 blgetbitmap (IndexScanDesc scan, TIDBitmap *tbm)
 
void blrescan (IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
 
void blendscan (IndexScanDesc scan)
 
IndexBuildResultblbuild (Relation heap, Relation index, struct IndexInfo *indexInfo)
 
void blbuildempty (Relation index)
 
IndexBulkDeleteResultblbulkdelete (IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
 
IndexBulkDeleteResultblvacuumcleanup (IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
 
byteabloptions (Datum reloptions, bool validate)
 
void blcostestimate (PlannerInfo *root, IndexPath *path, double loop_count, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages)
 

Macro Definition Documentation

◆ BLOOM_DELETED

#define BLOOM_DELETED   (2<<0)

Definition at line 47 of file bloom.h.

◆ BLOOM_EQUAL_STRATEGY

#define BLOOM_EQUAL_STRATEGY   1

Definition at line 29 of file bloom.h.

◆ BLOOM_HASH_PROC

#define BLOOM_HASH_PROC   1

Definition at line 24 of file bloom.h.

◆ BLOOM_HEAD_BLKNO

#define BLOOM_HEAD_BLKNO   (1) /* first data page */

Definition at line 79 of file bloom.h.

◆ BLOOM_MAGICK_NUMBER

#define BLOOM_MAGICK_NUMBER   (0xDBAC0DED)

Definition at line 128 of file bloom.h.

◆ BLOOM_META

#define BLOOM_META   (1<<0)

Definition at line 46 of file bloom.h.

◆ BLOOM_METAPAGE_BLKNO

#define BLOOM_METAPAGE_BLKNO   (0)

Definition at line 78 of file bloom.h.

◆ BLOOM_NPROC

#define BLOOM_NPROC   2

Definition at line 26 of file bloom.h.

◆ BLOOM_NSTRATEGIES

#define BLOOM_NSTRATEGIES   1

Definition at line 30 of file bloom.h.

◆ BLOOM_OPTIONS_PROC

#define BLOOM_OPTIONS_PROC   2

Definition at line 25 of file bloom.h.

◆ BLOOM_PAGE_ID

#define BLOOM_PAGE_ID   0xFF83

Definition at line 57 of file bloom.h.

◆ BloomMetaBlockN

#define BloomMetaBlockN   (sizeof(FreeBlockNumberArray) / sizeof(BlockNumber))

Definition at line 131 of file bloom.h.

◆ BloomPageGetData

#define BloomPageGetData (   page)    ((BloomTuple *)PageGetContents(page))

Definition at line 70 of file bloom.h.

◆ BloomPageGetFreeSpace

#define BloomPageGetFreeSpace (   state,
  page 
)
Value:
- BloomPageGetMaxOffset(page) * (state)->sizeOfBloomTuple \
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:61
#define SizeOfPageHeaderData
Definition: bufpage.h:217
#define MAXALIGN(LEN)
Definition: c.h:782
Definition: regguts.h:323

Definition at line 149 of file bloom.h.

◆ BloomPageGetMaxOffset

#define BloomPageGetMaxOffset (   page)    (BloomPageGetOpaque(page)->maxoff)

Definition at line 61 of file bloom.h.

◆ BloomPageGetMeta

#define BloomPageGetMeta (   page)    ((BloomMetaPageData *) PageGetContents(page))

Definition at line 133 of file bloom.h.

◆ BloomPageGetNextTuple

#define BloomPageGetNextTuple (   state,
  tuple 
)     ((BloomTuple *)((Pointer)(tuple) + (state)->sizeOfBloomTuple))

Definition at line 74 of file bloom.h.

◆ BloomPageGetOpaque

#define BloomPageGetOpaque (   page)    ((BloomPageOpaque) PageGetSpecialPointer(page))

Definition at line 60 of file bloom.h.

◆ BloomPageGetTuple

#define BloomPageGetTuple (   state,
  page,
  offset 
)
Value:
+ (state)->sizeOfBloomTuple * ((offset) - 1)))
static char * PageGetContents(Page page)
Definition: bufpage.h:258

Definition at line 71 of file bloom.h.

◆ BloomPageIsDeleted

#define BloomPageIsDeleted (   page)     ((BloomPageGetOpaque(page)->flags & BLOOM_DELETED) != 0)

Definition at line 64 of file bloom.h.

◆ BloomPageIsMeta

#define BloomPageIsMeta (   page)     ((BloomPageGetOpaque(page)->flags & BLOOM_META) != 0)

Definition at line 62 of file bloom.h.

◆ BloomPageSetDeleted

#define BloomPageSetDeleted (   page)     (BloomPageGetOpaque(page)->flags |= BLOOM_DELETED)

Definition at line 66 of file bloom.h.

◆ BloomPageSetNonDeleted

#define BloomPageSetNonDeleted (   page)     (BloomPageGetOpaque(page)->flags &= ~BLOOM_DELETED)

Definition at line 68 of file bloom.h.

◆ BLOOMTUPLEHDRSZ

#define BLOOMTUPLEHDRSZ   offsetof(BloomTuple, sign)

Definition at line 163 of file bloom.h.

◆ DEFAULT_BLOOM_BITS

#define DEFAULT_BLOOM_BITS   2

Definition at line 97 of file bloom.h.

◆ DEFAULT_BLOOM_LENGTH

#define DEFAULT_BLOOM_LENGTH   (5 * SIGNWORDBITS)

Definition at line 91 of file bloom.h.

◆ MAX_BLOOM_BITS

#define MAX_BLOOM_BITS   (MAX_BLOOM_LENGTH - 1)

Definition at line 98 of file bloom.h.

◆ MAX_BLOOM_LENGTH

#define MAX_BLOOM_LENGTH   (256 * SIGNWORDBITS)

Definition at line 92 of file bloom.h.

◆ SIGNWORDBITS

#define SIGNWORDBITS   ((int) (BITS_PER_BYTE * sizeof(BloomSignatureWord)))

Definition at line 86 of file bloom.h.

Typedef Documentation

◆ BloomMetaPageData

◆ BloomOptions

typedef struct BloomOptions BloomOptions

◆ BloomPageOpaque

Definition at line 43 of file bloom.h.

◆ BloomPageOpaqueData

◆ BloomScanOpaque

Definition at line 172 of file bloom.h.

◆ BloomScanOpaqueData

◆ BloomSignatureWord

Definition at line 84 of file bloom.h.

◆ BloomState

typedef struct BloomState BloomState

◆ BloomTuple

typedef struct BloomTuple BloomTuple

◆ FreeBlockNumberArray

typedef BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) - MAXALIGN(sizeof(uint16) *2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]

Definition at line 113 of file bloom.h.

Function Documentation

◆ blbeginscan()

IndexScanDesc blbeginscan ( Relation  r,
int  nkeys,
int  norderbys 
)

Definition at line 25 of file blscan.c.

26{
27 IndexScanDesc scan;
29
30 scan = RelationGetIndexScan(r, nkeys, norderbys);
31
34 so->sign = NULL;
35
36 scan->opaque = so;
37
38 return scan;
39}
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:166
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:172
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:80
void * palloc(Size size)
Definition: mcxt.c:1943
BloomSignatureWord * sign
Definition: bloom.h:168
BloomState state
Definition: bloom.h:169
Relation indexRelation
Definition: relscan.h:137

References IndexScanDescData::indexRelation, initBloomState(), IndexScanDescData::opaque, palloc(), RelationGetIndexScan(), BloomScanOpaqueData::sign, and BloomScanOpaqueData::state.

Referenced by blhandler().

◆ blbuild()

IndexBuildResult * blbuild ( Relation  heap,
Relation  index,
struct IndexInfo indexInfo 
)

Definition at line 122 of file blinsert.c.

123{
124 IndexBuildResult *result;
125 double reltuples;
126 BloomBuildState buildstate;
127
129 elog(ERROR, "index \"%s\" already contains data",
131
132 /* Initialize the meta page */
134
135 /* Initialize the bloom build state */
136 memset(&buildstate, 0, sizeof(buildstate));
137 initBloomState(&buildstate.blstate, index);
139 "Bloom build temporary context",
141 initCachedPage(&buildstate);
142
143 /* Do the heap scan */
144 reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
145 bloomBuildCallback, &buildstate,
146 NULL);
147
148 /* Flush last page if needed (it will be, unless heap was empty) */
149 if (buildstate.count > 0)
150 flushCachedPage(index, &buildstate);
151
152 MemoryContextDelete(buildstate.tmpCtx);
153
154 result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
155 result->heap_tuples = reltuples;
156 result->index_tuples = buildstate.indtuples;
157
158 return result;
159}
static void initCachedPage(BloomBuildState *buildstate)
Definition: blinsert.c:65
static void flushCachedPage(Relation index, BloomBuildState *buildstate)
Definition: blinsert.c:48
static void bloomBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition: blinsert.c:75
void BloomInitMetapage(Relation index, ForkNumber forknum)
Definition: blutils.c:451
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:283
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:485
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
#define RelationGetRelationName(relation)
Definition: rel.h:550
@ MAIN_FORKNUM
Definition: relpath.h:58
int64 indtuples
Definition: blinsert.c:37
BloomState blstate
Definition: blinsert.c:36
MemoryContext tmpCtx
Definition: blinsert.c:38
double heap_tuples
Definition: genam.h:55
double index_tuples
Definition: genam.h:56
Definition: type.h:96
static double table_index_build_scan(Relation table_rel, Relation index_rel, struct IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
Definition: tableam.h:1735

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, bloomBuildCallback(), BloomInitMetapage(), BloomBuildState::blstate, BloomBuildState::count, CurrentMemoryContext, elog, ERROR, flushCachedPage(), IndexBuildResult::heap_tuples, IndexBuildResult::index_tuples, BloomBuildState::indtuples, initBloomState(), initCachedPage(), MAIN_FORKNUM, MemoryContextDelete(), palloc(), RelationGetNumberOfBlocks, RelationGetRelationName, table_index_build_scan(), and BloomBuildState::tmpCtx.

Referenced by blhandler().

◆ blbuildempty()

void blbuildempty ( Relation  index)

Definition at line 165 of file blinsert.c.

166{
167 /* Initialize the meta page */
169}
@ INIT_FORKNUM
Definition: relpath.h:61

References BloomInitMetapage(), and INIT_FORKNUM.

Referenced by blhandler().

◆ blbulkdelete()

IndexBulkDeleteResult * blbulkdelete ( IndexVacuumInfo info,
IndexBulkDeleteResult stats,
IndexBulkDeleteCallback  callback,
void *  callback_state 
)

Definition at line 30 of file blvacuum.c.

32{
33 Relation index = info->index;
34 BlockNumber blkno,
35 npages;
36 FreeBlockNumberArray notFullPage;
37 int countPage = 0;
39 Buffer buffer;
40 Page page;
41 BloomMetaPageData *metaData;
42 GenericXLogState *gxlogState;
43
44 if (stats == NULL)
46
48
49 /*
50 * Iterate over the pages. We don't care about concurrently added pages,
51 * they can't contain tuples to delete.
52 */
54 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
55 {
56 BloomTuple *itup,
57 *itupPtr,
58 *itupEnd;
59
60 vacuum_delay_point(false);
61
62 buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
63 RBM_NORMAL, info->strategy);
64
66 gxlogState = GenericXLogStart(index);
67 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
68
69 /* Ignore empty/deleted pages until blvacuumcleanup() */
70 if (PageIsNew(page) || BloomPageIsDeleted(page))
71 {
72 UnlockReleaseBuffer(buffer);
73 GenericXLogAbort(gxlogState);
74 continue;
75 }
76
77 /*
78 * Iterate over the tuples. itup points to current tuple being
79 * scanned, itupPtr points to where to save next non-deleted tuple.
80 */
81 itup = itupPtr = BloomPageGetTuple(&state, page, FirstOffsetNumber);
82 itupEnd = BloomPageGetTuple(&state, page,
84 while (itup < itupEnd)
85 {
86 /* Do we have to delete this tuple? */
87 if (callback(&itup->heapPtr, callback_state))
88 {
89 /* Yes; adjust count of tuples that will be left on page */
90 BloomPageGetOpaque(page)->maxoff--;
91 stats->tuples_removed += 1;
92 }
93 else
94 {
95 /* No; copy it to itupPtr++, but skip copy if not needed */
96 if (itupPtr != itup)
97 memmove((Pointer) itupPtr, (Pointer) itup,
98 state.sizeOfBloomTuple);
99 itupPtr = BloomPageGetNextTuple(&state, itupPtr);
100 }
101
102 itup = BloomPageGetNextTuple(&state, itup);
103 }
104
105 /* Assert that we counted correctly */
106 Assert(itupPtr == BloomPageGetTuple(&state, page,
108
109 /*
110 * Add page to new notFullPage list if we will not mark page as
111 * deleted and there is free space on it
112 */
113 if (BloomPageGetMaxOffset(page) != 0 &&
114 BloomPageGetFreeSpace(&state, page) >= state.sizeOfBloomTuple &&
115 countPage < BloomMetaBlockN)
116 notFullPage[countPage++] = blkno;
117
118 /* Did we delete something? */
119 if (itupPtr != itup)
120 {
121 /* Is it empty page now? */
122 if (BloomPageGetMaxOffset(page) == 0)
124 /* Adjust pd_lower */
125 ((PageHeader) page)->pd_lower = (Pointer) itupPtr - page;
126 /* Finish WAL-logging */
127 GenericXLogFinish(gxlogState);
128 }
129 else
130 {
131 /* Didn't change anything: abort WAL-logging */
132 GenericXLogAbort(gxlogState);
133 }
134 UnlockReleaseBuffer(buffer);
135 }
136
137 /*
138 * Update the metapage's notFullPage list with whatever we found. Our
139 * info could already be out of date at this point, but blinsert() will
140 * cope if so.
141 */
144
145 gxlogState = GenericXLogStart(index);
146 page = GenericXLogRegisterBuffer(gxlogState, buffer, 0);
147
148 metaData = BloomPageGetMeta(page);
149 memcpy(metaData->notFullPage, notFullPage, sizeof(BlockNumber) * countPage);
150 metaData->nStart = 0;
151 metaData->nEnd = countPage;
152
153 GenericXLogFinish(gxlogState);
154 UnlockReleaseBuffer(buffer);
155
156 return stats;
157}
uint32 BlockNumber
Definition: block.h:31
#define BloomPageGetOpaque(page)
Definition: bloom.h:60
#define BloomPageGetFreeSpace(state, page)
Definition: bloom.h:149
#define BloomPageGetMeta(page)
Definition: bloom.h:133
BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) - MAXALIGN(sizeof(uint16) *2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]
Definition: bloom.h:115
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:71
#define BloomPageSetDeleted(page)
Definition: bloom.h:66
#define BloomPageGetNextTuple(state, tuple)
Definition: bloom.h:74
#define BloomPageIsDeleted(page)
Definition: bloom.h:64
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:79
#define BloomMetaBlockN
Definition: bloom.h:131
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:78
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:5390
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5607
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:805
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:758
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:198
@ RBM_NORMAL
Definition: bufmgr.h:46
PageHeaderData * PageHeader
Definition: bufpage.h:174
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
PageData * Page
Definition: bufpage.h:82
char * Pointer
Definition: c.h:493
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:299
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:269
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:337
void GenericXLogAbort(GenericXLogState *state)
Definition: generic_xlog.c:444
Assert(PointerIsAligned(start, uint64))
void * palloc0(Size size)
Definition: mcxt.c:1973
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
#define FirstOffsetNumber
Definition: off.h:27
FreeBlockNumberArray notFullPage
Definition: bloom.h:124
uint16 nEnd
Definition: bloom.h:122
uint16 nStart
Definition: bloom.h:121
ItemPointerData heapPtr
Definition: bloom.h:159
double tuples_removed
Definition: genam.h:103
Relation index
Definition: genam.h:69
BufferAccessStrategy strategy
Definition: genam.h:76
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46
void vacuum_delay_point(bool is_analyze)
Definition: vacuum.c:2404

References Assert(), BLOOM_HEAD_BLKNO, BLOOM_METAPAGE_BLKNO, BloomMetaBlockN, BloomPageGetFreeSpace, BloomPageGetMaxOffset, BloomPageGetMeta, BloomPageGetNextTuple, BloomPageGetOpaque, BloomPageGetTuple, BloomPageIsDeleted, BloomPageSetDeleted, BUFFER_LOCK_EXCLUSIVE, callback(), FirstOffsetNumber, GenericXLogAbort(), GenericXLogFinish(), GenericXLogRegisterBuffer(), GenericXLogStart(), BloomTuple::heapPtr, IndexVacuumInfo::index, initBloomState(), LockBuffer(), MAIN_FORKNUM, BloomMetaPageData::nEnd, BloomMetaPageData::notFullPage, BloomMetaPageData::nStart, OffsetNumberNext, PageIsNew(), palloc0(), RBM_NORMAL, ReadBuffer(), ReadBufferExtended(), RelationGetNumberOfBlocks, IndexVacuumInfo::strategy, IndexBulkDeleteResult::tuples_removed, UnlockReleaseBuffer(), and vacuum_delay_point().

Referenced by blhandler().

◆ blcostestimate()

void blcostestimate ( PlannerInfo root,
IndexPath path,
double  loop_count,
Cost indexStartupCost,
Cost indexTotalCost,
Selectivity indexSelectivity,
double *  indexCorrelation,
double *  indexPages 
)

Definition at line 22 of file blcost.c.

26{
28 GenericCosts costs = {0};
29
30 /* We have to visit all index tuples anyway */
31 costs.numIndexTuples = index->tuples;
32
33 /* Use generic estimate */
34 genericcostestimate(root, path, loop_count, &costs);
35
36 *indexStartupCost = costs.indexStartupCost;
37 *indexTotalCost = costs.indexTotalCost;
38 *indexSelectivity = costs.indexSelectivity;
39 *indexCorrelation = costs.indexCorrelation;
40 *indexPages = costs.numIndexPages;
41}
tree ctl root
Definition: radixtree.h:1857
void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, GenericCosts *costs)
Definition: selfuncs.c:6935
Selectivity indexSelectivity
Definition: selfuncs.h:128
Cost indexStartupCost
Definition: selfuncs.h:126
double indexCorrelation
Definition: selfuncs.h:129
Cost indexTotalCost
Definition: selfuncs.h:127
double numIndexPages
Definition: selfuncs.h:132
double numIndexTuples
Definition: selfuncs.h:133
IndexOptInfo * indexinfo
Definition: pathnodes.h:1847

References genericcostestimate(), GenericCosts::indexCorrelation, IndexPath::indexinfo, GenericCosts::indexSelectivity, GenericCosts::indexStartupCost, GenericCosts::indexTotalCost, GenericCosts::numIndexPages, GenericCosts::numIndexTuples, and root.

Referenced by blhandler().

◆ blendscan()

void blendscan ( IndexScanDesc  scan)

Definition at line 62 of file blscan.c.

63{
65
66 if (so->sign)
67 pfree(so->sign);
68 so->sign = NULL;
69}
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
void pfree(void *pointer)
Definition: mcxt.c:2150

References if(), IndexScanDescData::opaque, pfree(), and BloomScanOpaqueData::sign.

Referenced by blhandler().

◆ blgetbitmap()

int64 blgetbitmap ( IndexScanDesc  scan,
TIDBitmap tbm 
)

Definition at line 75 of file blscan.c.

76{
77 int64 ntids = 0;
79 npages;
80 int i;
83
84 if (so->sign == NULL)
85 {
86 /* New search: have to calculate search signature */
87 ScanKey skey = scan->keyData;
88
90
91 for (i = 0; i < scan->numberOfKeys; i++)
92 {
93 /*
94 * Assume bloom-indexable operators to be strict, so nothing could
95 * be found for NULL key.
96 */
97 if (skey->sk_flags & SK_ISNULL)
98 {
99 pfree(so->sign);
100 so->sign = NULL;
101 return 0;
102 }
103
104 /* Add next value to the signature */
105 signValue(&so->state, so->sign, skey->sk_argument,
106 skey->sk_attno - 1);
107
108 skey++;
109 }
110 }
111
112 /*
113 * We're going to read the whole index. This is why we use appropriate
114 * buffer access strategy.
115 */
119 if (scan->instrument)
120 scan->instrument->nsearches++;
121
122 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
123 {
124 Buffer buffer;
125 Page page;
126
128 blkno, RBM_NORMAL, bas);
129
131 page = BufferGetPage(buffer);
132
133 if (!PageIsNew(page) && !BloomPageIsDeleted(page))
134 {
135 OffsetNumber offset,
136 maxOffset = BloomPageGetMaxOffset(page);
137
138 for (offset = 1; offset <= maxOffset; offset++)
139 {
140 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
141 bool res = true;
142
143 /* Check index signature with scan signature */
144 for (i = 0; i < so->state.opts.bloomLength; i++)
145 {
146 if ((itup->sign[i] & so->sign[i]) != so->sign[i])
147 {
148 res = false;
149 break;
150 }
151 }
152
153 /* Add matching tuples to bitmap */
154 if (res)
155 {
156 tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
157 ntids++;
158 }
159 }
160 }
161
162 UnlockReleaseBuffer(buffer);
164 }
166
167 return ntids;
168}
uint16 BloomSignatureWord
Definition: bloom.h:84
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:265
@ BAS_BULKREAD
Definition: bufmgr.h:37
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:197
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:417
int64_t int64
Definition: c.h:499
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:541
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition: freelist.c:723
int i
Definition: isn.c:77
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
uint16 OffsetNumber
Definition: off.h:24
#define pgstat_count_index_scan(rel)
Definition: pgstat.h:694
#define SK_ISNULL
Definition: skey.h:115
int bloomLength
Definition: bloom.h:104
BloomOptions opts
Definition: bloom.h:139
BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]
Definition: bloom.h:160
struct ScanKeyData * keyData
Definition: relscan.h:141
struct IndexScanInstrumentation * instrument
Definition: relscan.h:159
int sk_flags
Definition: skey.h:66
Datum sk_argument
Definition: skey.h:72
AttrNumber sk_attno
Definition: skey.h:67
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
Definition: tidbitmap.c:366

References BAS_BULKREAD, BLOOM_HEAD_BLKNO, BloomOptions::bloomLength, BloomPageGetMaxOffset, BloomPageGetTuple, BloomPageIsDeleted, BUFFER_LOCK_SHARE, BufferGetPage(), CHECK_FOR_INTERRUPTS, FreeAccessStrategy(), GetAccessStrategy(), BloomTuple::heapPtr, i, if(), IndexScanDescData::indexRelation, IndexScanDescData::instrument, IndexScanDescData::keyData, LockBuffer(), MAIN_FORKNUM, IndexScanInstrumentation::nsearches, IndexScanDescData::numberOfKeys, IndexScanDescData::opaque, BloomState::opts, PageIsNew(), palloc0(), pfree(), pgstat_count_index_scan, RBM_NORMAL, ReadBufferExtended(), RelationGetNumberOfBlocks, BloomTuple::sign, BloomScanOpaqueData::sign, signValue(), ScanKeyData::sk_argument, ScanKeyData::sk_attno, ScanKeyData::sk_flags, SK_ISNULL, BloomScanOpaqueData::state, tbm_add_tuples(), and UnlockReleaseBuffer().

Referenced by blhandler().

◆ blinsert()

bool blinsert ( Relation  index,
Datum values,
bool *  isnull,
ItemPointer  ht_ctid,
Relation  heapRel,
IndexUniqueCheck  checkUnique,
bool  indexUnchanged,
struct IndexInfo indexInfo 
)

Definition at line 175 of file blinsert.c.

180{
181 BloomState blstate;
182 BloomTuple *itup;
183 MemoryContext oldCtx;
184 MemoryContext insertCtx;
185 BloomMetaPageData *metaData;
186 Buffer buffer,
187 metaBuffer;
188 Page page,
189 metaPage;
191 OffsetNumber nStart;
193
195 "Bloom insert temporary context",
197
198 oldCtx = MemoryContextSwitchTo(insertCtx);
199
200 initBloomState(&blstate, index);
201 itup = BloomFormTuple(&blstate, ht_ctid, values, isnull);
202
203 /*
204 * At first, try to insert new tuple to the first page in notFullPage
205 * array. If successful, we don't need to modify the meta page.
206 */
208 LockBuffer(metaBuffer, BUFFER_LOCK_SHARE);
209 metaData = BloomPageGetMeta(BufferGetPage(metaBuffer));
210
211 if (metaData->nEnd > metaData->nStart)
212 {
213 blkno = metaData->notFullPage[metaData->nStart];
214 Assert(blkno != InvalidBlockNumber);
215
216 /* Don't hold metabuffer lock while doing insert */
217 LockBuffer(metaBuffer, BUFFER_LOCK_UNLOCK);
218
219 buffer = ReadBuffer(index, blkno);
221
223 page = GenericXLogRegisterBuffer(state, buffer, 0);
224
225 /*
226 * We might have found a page that was recently deleted by VACUUM. If
227 * so, we can reuse it, but we must reinitialize it.
228 */
229 if (PageIsNew(page) || BloomPageIsDeleted(page))
230 BloomInitPage(page, 0);
231
232 if (BloomPageAddItem(&blstate, page, itup))
233 {
234 /* Success! Apply the change, clean up, and exit */
236 UnlockReleaseBuffer(buffer);
237 ReleaseBuffer(metaBuffer);
238 MemoryContextSwitchTo(oldCtx);
239 MemoryContextDelete(insertCtx);
240 return false;
241 }
242
243 /* Didn't fit, must try other pages */
245 UnlockReleaseBuffer(buffer);
246 }
247 else
248 {
249 /* No entries in notFullPage */
250 LockBuffer(metaBuffer, BUFFER_LOCK_UNLOCK);
251 }
252
253 /*
254 * Try other pages in notFullPage array. We will have to change nStart in
255 * metapage. Thus, grab exclusive lock on metapage.
256 */
258
259 /* nStart might have changed while we didn't have lock */
260 nStart = metaData->nStart;
261
262 /* Skip first page if we already tried it above */
263 if (nStart < metaData->nEnd &&
264 blkno == metaData->notFullPage[nStart])
265 nStart++;
266
267 /*
268 * This loop iterates for each page we try from the notFullPage array, and
269 * will also initialize a GenericXLogState for the fallback case of having
270 * to allocate a new page.
271 */
272 for (;;)
273 {
275
276 /* get modifiable copy of metapage */
277 metaPage = GenericXLogRegisterBuffer(state, metaBuffer, 0);
278 metaData = BloomPageGetMeta(metaPage);
279
280 if (nStart >= metaData->nEnd)
281 break; /* no more entries in notFullPage array */
282
283 blkno = metaData->notFullPage[nStart];
284 Assert(blkno != InvalidBlockNumber);
285
286 buffer = ReadBuffer(index, blkno);
288 page = GenericXLogRegisterBuffer(state, buffer, 0);
289
290 /* Basically same logic as above */
291 if (PageIsNew(page) || BloomPageIsDeleted(page))
292 BloomInitPage(page, 0);
293
294 if (BloomPageAddItem(&blstate, page, itup))
295 {
296 /* Success! Apply the changes, clean up, and exit */
297 metaData->nStart = nStart;
299 UnlockReleaseBuffer(buffer);
300 UnlockReleaseBuffer(metaBuffer);
301 MemoryContextSwitchTo(oldCtx);
302 MemoryContextDelete(insertCtx);
303 return false;
304 }
305
306 /* Didn't fit, must try other pages */
308 UnlockReleaseBuffer(buffer);
309 nStart++;
310 }
311
312 /*
313 * Didn't find place to insert in notFullPage array. Allocate new page.
314 * (XXX is it good to do this while holding ex-lock on the metapage??)
315 */
316 buffer = BloomNewBuffer(index);
317
319 BloomInitPage(page, 0);
320
321 if (!BloomPageAddItem(&blstate, page, itup))
322 {
323 /* We shouldn't be here since we're inserting to an empty page */
324 elog(ERROR, "could not add new bloom tuple to empty page");
325 }
326
327 /* Reset notFullPage array to contain just this new page */
328 metaData->nStart = 0;
329 metaData->nEnd = 1;
330 metaData->notFullPage[0] = BufferGetBlockNumber(buffer);
331
332 /* Apply the changes, clean up, and exit */
334
335 UnlockReleaseBuffer(buffer);
336 UnlockReleaseBuffer(metaBuffer);
337
338 MemoryContextSwitchTo(oldCtx);
339 MemoryContextDelete(insertCtx);
340
341 return false;
342}
#define InvalidBlockNumber
Definition: block.h:33
void BloomInitPage(Page page, uint16 flags)
Definition: blutils.c:404
BloomTuple * BloomFormTuple(BloomState *state, ItemPointer iptr, Datum *values, bool *isnull)
Definition: blutils.c:298
bool BloomPageAddItem(BloomState *state, Page page, BloomTuple *tuple)
Definition: blutils.c:323
Buffer BloomNewBuffer(Relation index)
Definition: blutils.c:358
static Datum values[MAXATTR]
Definition: bootstrap.c:151
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:4231
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:5373
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:196
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), BLOOM_METAPAGE_BLKNO, BloomFormTuple(), BloomInitPage(), BloomNewBuffer(), BloomPageAddItem(), BloomPageGetMeta, BloomPageIsDeleted, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetBlockNumber(), BufferGetPage(), CurrentMemoryContext, elog, ERROR, GENERIC_XLOG_FULL_IMAGE, GenericXLogAbort(), GenericXLogFinish(), GenericXLogRegisterBuffer(), GenericXLogStart(), initBloomState(), InvalidBlockNumber, LockBuffer(), MemoryContextDelete(), MemoryContextSwitchTo(), BloomMetaPageData::nEnd, BloomMetaPageData::notFullPage, BloomMetaPageData::nStart, PageIsNew(), ReadBuffer(), ReleaseBuffer(), UnlockReleaseBuffer(), and values.

Referenced by blhandler().

◆ BloomFillMetapage()

void BloomFillMetapage ( Relation  index,
Page  metaPage 
)

Definition at line 419 of file blutils.c.

420{
422 BloomMetaPageData *metadata;
423
424 /*
425 * Choose the index's options. If reloptions have been assigned, use
426 * those, otherwise create default options.
427 */
428 opts = (BloomOptions *) index->rd_options;
429 if (!opts)
431
432 /*
433 * Initialize contents of meta page, including a copy of the options,
434 * which are now frozen for the life of the index.
435 */
436 BloomInitPage(metaPage, BLOOM_META);
437 metadata = BloomPageGetMeta(metaPage);
438 memset(metadata, 0, sizeof(BloomMetaPageData));
440 metadata->opts = *opts;
441 ((PageHeader) metaPage)->pd_lower += sizeof(BloomMetaPageData);
442
443 /* If this fails, probably FreeBlockNumberArray size calc is wrong: */
444 Assert(((PageHeader) metaPage)->pd_lower <= ((PageHeader) metaPage)->pd_upper);
445}
struct BloomMetaPageData BloomMetaPageData
#define BLOOM_MAGICK_NUMBER
Definition: bloom.h:128
#define BLOOM_META
Definition: bloom.h:46
void BloomInitPage(Page page, uint16 flags)
Definition: blutils.c:404
static BloomOptions * makeDefaultBloomOptions(void)
Definition: blutils.c:84
static AmcheckOptions opts
Definition: pg_amcheck.c:112
BloomOptions opts
Definition: bloom.h:123
uint32 magickNumber
Definition: bloom.h:120

References Assert(), BLOOM_MAGICK_NUMBER, BLOOM_META, BloomInitPage(), BloomPageGetMeta, if(), BloomMetaPageData::magickNumber, makeDefaultBloomOptions(), BloomMetaPageData::opts, and opts.

Referenced by BloomInitMetapage().

◆ BloomFormTuple()

BloomTuple * BloomFormTuple ( BloomState state,
ItemPointer  iptr,
Datum values,
bool *  isnull 
)

Definition at line 298 of file blutils.c.

299{
300 int i;
301 BloomTuple *res = (BloomTuple *) palloc0(state->sizeOfBloomTuple);
302
303 res->heapPtr = *iptr;
304
305 /* Blooming each column */
306 for (i = 0; i < state->nColumns; i++)
307 {
308 /* skip nulls */
309 if (isnull[i])
310 continue;
311
312 signValue(state, res->sign, values[i], i);
313 }
314
315 return res;
316}
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:265

References BloomTuple::heapPtr, i, palloc0(), BloomTuple::sign, signValue(), and values.

Referenced by blinsert(), and bloomBuildCallback().

◆ BloomInitMetapage()

void BloomInitMetapage ( Relation  index,
ForkNumber  forknum 
)

Definition at line 451 of file blutils.c.

452{
453 Buffer metaBuffer;
454 Page metaPage;
456
457 /*
458 * Make a new page; since it is first page it should be associated with
459 * block number 0 (BLOOM_METAPAGE_BLKNO). No need to hold the extension
460 * lock because there cannot be concurrent inserters yet.
461 */
462 metaBuffer = ReadBufferExtended(index, forknum, P_NEW, RBM_NORMAL, NULL);
465
466 /* Initialize contents of meta page */
468 metaPage = GenericXLogRegisterBuffer(state, metaBuffer,
470 BloomFillMetapage(index, metaPage);
472
473 UnlockReleaseBuffer(metaBuffer);
474}
void BloomFillMetapage(Relation index, Page metaPage)
Definition: blutils.c:419
#define P_NEW
Definition: bufmgr.h:191

References Assert(), BLOOM_METAPAGE_BLKNO, BloomFillMetapage(), BUFFER_LOCK_EXCLUSIVE, BufferGetBlockNumber(), GENERIC_XLOG_FULL_IMAGE, GenericXLogFinish(), GenericXLogRegisterBuffer(), GenericXLogStart(), LockBuffer(), P_NEW, RBM_NORMAL, ReadBufferExtended(), and UnlockReleaseBuffer().

Referenced by blbuild(), and blbuildempty().

◆ BloomInitPage()

void BloomInitPage ( Page  page,
uint16  flags 
)

Definition at line 404 of file blutils.c.

405{
406 BloomPageOpaque opaque;
407
408 PageInit(page, BLCKSZ, sizeof(BloomPageOpaqueData));
409
410 opaque = BloomPageGetOpaque(page);
411 opaque->flags = flags;
413}
#define BLOOM_PAGE_ID
Definition: bloom.h:57
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
uint16 flags
Definition: bloom.h:36
uint16 bloom_page_id
Definition: bloom.h:40

References BloomPageOpaqueData::bloom_page_id, BLOOM_PAGE_ID, BloomPageGetOpaque, BloomPageOpaqueData::flags, and PageInit().

Referenced by blinsert(), BloomFillMetapage(), and initCachedPage().

◆ BloomNewBuffer()

Buffer BloomNewBuffer ( Relation  index)

Definition at line 358 of file blutils.c.

359{
360 Buffer buffer;
361
362 /* First, try to get a page from FSM */
363 for (;;)
364 {
366
367 if (blkno == InvalidBlockNumber)
368 break;
369
370 buffer = ReadBuffer(index, blkno);
371
372 /*
373 * We have to guard against the possibility that someone else already
374 * recycled this page; the buffer may be locked if so.
375 */
376 if (ConditionalLockBuffer(buffer))
377 {
378 Page page = BufferGetPage(buffer);
379
380 if (PageIsNew(page))
381 return buffer; /* OK to use, if never initialized */
382
383 if (BloomPageIsDeleted(page))
384 return buffer; /* OK to use */
385
387 }
388
389 /* Can't use it, so release buffer and try again */
390 ReleaseBuffer(buffer);
391 }
392
393 /* Must extend the file */
396
397 return buffer;
398}
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
Definition: bufmgr.c:858
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:5633
@ EB_LOCK_FIRST
Definition: bufmgr.h:87
#define BMR_REL(p_rel)
Definition: bufmgr.h:108
BlockNumber GetFreeIndexPage(Relation rel)
Definition: indexfsm.c:38

References BloomPageIsDeleted, BMR_REL, BUFFER_LOCK_UNLOCK, BufferGetPage(), ConditionalLockBuffer(), EB_LOCK_FIRST, ExtendBufferedRel(), GetFreeIndexPage(), InvalidBlockNumber, LockBuffer(), MAIN_FORKNUM, PageIsNew(), ReadBuffer(), and ReleaseBuffer().

Referenced by blinsert(), and flushCachedPage().

◆ BloomPageAddItem()

bool BloomPageAddItem ( BloomState state,
Page  page,
BloomTuple tuple 
)

Definition at line 323 of file blutils.c.

324{
325 BloomTuple *itup;
326 BloomPageOpaque opaque;
327 Pointer ptr;
328
329 /* We shouldn't be pointed to an invalid page */
330 Assert(!PageIsNew(page) && !BloomPageIsDeleted(page));
331
332 /* Does new tuple fit on the page? */
333 if (BloomPageGetFreeSpace(state, page) < state->sizeOfBloomTuple)
334 return false;
335
336 /* Copy new tuple to the end of page */
337 opaque = BloomPageGetOpaque(page);
338 itup = BloomPageGetTuple(state, page, opaque->maxoff + 1);
339 memcpy((Pointer) itup, (Pointer) tuple, state->sizeOfBloomTuple);
340
341 /* Adjust maxoff and pd_lower */
342 opaque->maxoff++;
343 ptr = (Pointer) BloomPageGetTuple(state, page, opaque->maxoff + 1);
344 ((PageHeader) page)->pd_lower = ptr - page;
345
346 /* Assert we didn't overrun available space */
347 Assert(((PageHeader) page)->pd_lower <= ((PageHeader) page)->pd_upper);
348
349 return true;
350}
OffsetNumber maxoff
Definition: bloom.h:35

References Assert(), BloomPageGetFreeSpace, BloomPageGetOpaque, BloomPageGetTuple, BloomPageIsDeleted, BloomPageOpaqueData::maxoff, and PageIsNew().

Referenced by blinsert(), and bloomBuildCallback().

◆ bloptions()

bytea * bloptions ( Datum  reloptions,
bool  validate 
)

Definition at line 480 of file blutils.c.

481{
482 BloomOptions *rdopts;
483
484 /* Parse the user-given reloptions */
485 rdopts = (BloomOptions *) build_reloptions(reloptions, validate,
487 sizeof(BloomOptions),
490
491 /* Convert signature length from # of bits to # to words, rounding up */
492 if (rdopts)
493 rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
494
495 return (bytea *) rdopts;
496}
static bool validate(Port *port, const char *auth)
Definition: auth-oauth.c:638
#define SIGNWORDBITS
Definition: bloom.h:86
static relopt_kind bl_relopt_kind
Definition: blutils.c:35
static relopt_parse_elt bl_relopt_tab[INDEX_MAX_KEYS+1]
Definition: blutils.c:38
#define lengthof(array)
Definition: c.h:759
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
Definition: reloptions.c:1934
Definition: c.h:658

References bl_relopt_kind, bl_relopt_tab, BloomOptions::bloomLength, build_reloptions(), lengthof, SIGNWORDBITS, and validate().

Referenced by blhandler().

◆ blrescan()

void blrescan ( IndexScanDesc  scan,
ScanKey  scankey,
int  nscankeys,
ScanKey  orderbys,
int  norderbys 
)

Definition at line 45 of file blscan.c.

47{
49
50 if (so->sign)
51 pfree(so->sign);
52 so->sign = NULL;
53
54 if (scankey && scan->numberOfKeys > 0)
55 memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
56}

References if(), IndexScanDescData::keyData, IndexScanDescData::numberOfKeys, IndexScanDescData::opaque, pfree(), and BloomScanOpaqueData::sign.

Referenced by blhandler().

◆ blvacuumcleanup()

IndexBulkDeleteResult * blvacuumcleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 165 of file blvacuum.c.

166{
167 Relation index = info->index;
168 BlockNumber npages,
169 blkno;
170
171 if (info->analyze_only)
172 return stats;
173
174 if (stats == NULL)
176
177 /*
178 * Iterate over the pages: insert deleted pages into FSM and collect
179 * statistics.
180 */
182 stats->num_pages = npages;
183 stats->pages_free = 0;
184 stats->num_index_tuples = 0;
185 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
186 {
187 Buffer buffer;
188 Page page;
189
190 vacuum_delay_point(false);
191
192 buffer = ReadBufferExtended(index, MAIN_FORKNUM, blkno,
193 RBM_NORMAL, info->strategy);
195 page = (Page) BufferGetPage(buffer);
196
197 if (PageIsNew(page) || BloomPageIsDeleted(page))
198 {
200 stats->pages_free++;
201 }
202 else
203 {
205 }
206
207 UnlockReleaseBuffer(buffer);
208 }
209
211
212 return stats;
213}
void IndexFreeSpaceMapVacuum(Relation rel)
Definition: indexfsm.c:71
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
Definition: indexfsm.c:52
BlockNumber pages_free
Definition: genam.h:106
BlockNumber num_pages
Definition: genam.h:100
double num_index_tuples
Definition: genam.h:102
bool analyze_only
Definition: genam.h:71

References IndexVacuumInfo::analyze_only, BLOOM_HEAD_BLKNO, BloomPageGetMaxOffset, BloomPageIsDeleted, BUFFER_LOCK_SHARE, BufferGetPage(), IndexVacuumInfo::index, IndexFreeSpaceMapVacuum(), LockBuffer(), MAIN_FORKNUM, IndexBulkDeleteResult::num_index_tuples, IndexBulkDeleteResult::num_pages, PageIsNew(), IndexBulkDeleteResult::pages_free, palloc0(), RBM_NORMAL, ReadBufferExtended(), RecordFreeIndexPage(), RelationGetNumberOfBlocks, IndexVacuumInfo::strategy, UnlockReleaseBuffer(), and vacuum_delay_point().

Referenced by blhandler().

◆ blvalidate()

bool blvalidate ( Oid  opclassoid)

Definition at line 30 of file blvalidate.c.

31{
32 bool result = true;
33 HeapTuple classtup;
34 Form_pg_opclass classform;
35 Oid opfamilyoid;
36 Oid opcintype;
37 Oid opckeytype;
38 char *opclassname;
39 char *opfamilyname;
40 CatCList *proclist,
41 *oprlist;
42 List *grouplist;
43 OpFamilyOpFuncGroup *opclassgroup;
44 int i;
45 ListCell *lc;
46
47 /* Fetch opclass information */
48 classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassoid));
49 if (!HeapTupleIsValid(classtup))
50 elog(ERROR, "cache lookup failed for operator class %u", opclassoid);
51 classform = (Form_pg_opclass) GETSTRUCT(classtup);
52
53 opfamilyoid = classform->opcfamily;
54 opcintype = classform->opcintype;
55 opckeytype = classform->opckeytype;
56 if (!OidIsValid(opckeytype))
57 opckeytype = opcintype;
58 opclassname = NameStr(classform->opcname);
59
60 /* Fetch opfamily information */
61 opfamilyname = get_opfamily_name(opfamilyoid, false);
62
63 /* Fetch all operators and support functions of the opfamily */
64 oprlist = SearchSysCacheList1(AMOPSTRATEGY, ObjectIdGetDatum(opfamilyoid));
65 proclist = SearchSysCacheList1(AMPROCNUM, ObjectIdGetDatum(opfamilyoid));
66
67 /* Check individual support functions */
68 for (i = 0; i < proclist->n_members; i++)
69 {
70 HeapTuple proctup = &proclist->members[i]->tuple;
71 Form_pg_amproc procform = (Form_pg_amproc) GETSTRUCT(proctup);
72 bool ok;
73
74 /*
75 * All bloom support functions should be registered with matching
76 * left/right types
77 */
78 if (procform->amproclefttype != procform->amprocrighttype)
79 {
81 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
82 errmsg("bloom opfamily %s contains support procedure %s with cross-type registration",
83 opfamilyname,
84 format_procedure(procform->amproc))));
85 result = false;
86 }
87
88 /*
89 * We can't check signatures except within the specific opclass, since
90 * we need to know the associated opckeytype in many cases.
91 */
92 if (procform->amproclefttype != opcintype)
93 continue;
94
95 /* Check procedure numbers and function signatures */
96 switch (procform->amprocnum)
97 {
98 case BLOOM_HASH_PROC:
99 ok = check_amproc_signature(procform->amproc, INT4OID, false,
100 1, 1, opckeytype);
101 break;
103 ok = check_amoptsproc_signature(procform->amproc);
104 break;
105 default:
107 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
108 errmsg("bloom opfamily %s contains function %s with invalid support number %d",
109 opfamilyname,
110 format_procedure(procform->amproc),
111 procform->amprocnum)));
112 result = false;
113 continue; /* don't want additional message */
114 }
115
116 if (!ok)
117 {
119 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
120 errmsg("bloom opfamily %s contains function %s with wrong signature for support number %d",
121 opfamilyname,
122 format_procedure(procform->amproc),
123 procform->amprocnum)));
124 result = false;
125 }
126 }
127
128 /* Check individual operators */
129 for (i = 0; i < oprlist->n_members; i++)
130 {
131 HeapTuple oprtup = &oprlist->members[i]->tuple;
132 Form_pg_amop oprform = (Form_pg_amop) GETSTRUCT(oprtup);
133
134 /* Check it's allowed strategy for bloom */
135 if (oprform->amopstrategy < 1 ||
136 oprform->amopstrategy > BLOOM_NSTRATEGIES)
137 {
139 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
140 errmsg("bloom opfamily %s contains operator %s with invalid strategy number %d",
141 opfamilyname,
142 format_operator(oprform->amopopr),
143 oprform->amopstrategy)));
144 result = false;
145 }
146
147 /* bloom doesn't support ORDER BY operators */
148 if (oprform->amoppurpose != AMOP_SEARCH ||
149 OidIsValid(oprform->amopsortfamily))
150 {
152 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
153 errmsg("bloom opfamily %s contains invalid ORDER BY specification for operator %s",
154 opfamilyname,
155 format_operator(oprform->amopopr))));
156 result = false;
157 }
158
159 /* Check operator signature --- same for all bloom strategies */
160 if (!check_amop_signature(oprform->amopopr, BOOLOID,
161 oprform->amoplefttype,
162 oprform->amoprighttype))
163 {
165 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
166 errmsg("bloom opfamily %s contains operator %s with wrong signature",
167 opfamilyname,
168 format_operator(oprform->amopopr))));
169 result = false;
170 }
171 }
172
173 /* Now check for inconsistent groups of operators/functions */
174 grouplist = identify_opfamily_groups(oprlist, proclist);
175 opclassgroup = NULL;
176 foreach(lc, grouplist)
177 {
179
180 /* Remember the group exactly matching the test opclass */
181 if (thisgroup->lefttype == opcintype &&
182 thisgroup->righttype == opcintype)
183 opclassgroup = thisgroup;
184
185 /*
186 * There is not a lot we can do to check the operator sets, since each
187 * bloom opclass is more or less a law unto itself, and some contain
188 * only operators that are binary-compatible with the opclass datatype
189 * (meaning that empty operator sets can be OK). That case also means
190 * that we shouldn't insist on nonempty function sets except for the
191 * opclass's own group.
192 */
193 }
194
195 /* Check that the originally-named opclass is complete */
196 for (i = 1; i <= BLOOM_NPROC; i++)
197 {
198 if (opclassgroup &&
199 (opclassgroup->functionset & (((uint64) 1) << i)) != 0)
200 continue; /* got it */
201 if (i == BLOOM_OPTIONS_PROC)
202 continue; /* optional method */
204 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
205 errmsg("bloom opclass %s is missing support function %d",
206 opclassname, i)));
207 result = false;
208 }
209
210 ReleaseCatCacheList(proclist);
211 ReleaseCatCacheList(oprlist);
212 ReleaseSysCache(classtup);
213
214 return result;
215}
bool check_amproc_signature(Oid funcid, Oid restype, bool exact, int minargs, int maxargs,...)
Definition: amvalidate.c:152
bool check_amop_signature(Oid opno, Oid restype, Oid lefttype, Oid righttype)
Definition: amvalidate.c:206
List * identify_opfamily_groups(CatCList *oprlist, CatCList *proclist)
Definition: amvalidate.c:43
bool check_amoptsproc_signature(Oid funcid)
Definition: amvalidate.c:192
#define BLOOM_HASH_PROC
Definition: bloom.h:24
#define BLOOM_NPROC
Definition: bloom.h:26
#define BLOOM_NSTRATEGIES
Definition: bloom.h:30
#define BLOOM_OPTIONS_PROC
Definition: bloom.h:25
#define NameStr(name)
Definition: c.h:717
uint64_t uint64
Definition: c.h:503
#define OidIsValid(objectId)
Definition: c.h:746
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:2093
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define INFO
Definition: elog.h:34
#define ereport(elevel,...)
Definition: elog.h:149
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
Definition: htup_details.h:728
char * get_opfamily_name(Oid opfid, bool missing_ok)
Definition: lsyscache.c:1393
FormData_pg_amop * Form_pg_amop
Definition: pg_amop.h:88
FormData_pg_amproc * Form_pg_amproc
Definition: pg_amproc.h:68
#define lfirst(lc)
Definition: pg_list.h:172
FormData_pg_opclass * Form_pg_opclass
Definition: pg_opclass.h:83
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:30
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:299
char * format_operator(Oid operator_oid)
Definition: regproc.c:793
Definition: pg_list.h:54
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:180
int n_members
Definition: catcache.h:178
HeapTupleData tuple
Definition: catcache.h:123
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:127

References BLOOM_HASH_PROC, BLOOM_NPROC, BLOOM_NSTRATEGIES, BLOOM_OPTIONS_PROC, check_amop_signature(), check_amoptsproc_signature(), check_amproc_signature(), elog, ereport, errcode(), errmsg(), ERROR, format_operator(), format_procedure(), OpFamilyOpFuncGroup::functionset, get_opfamily_name(), GETSTRUCT(), HeapTupleIsValid, i, identify_opfamily_groups(), INFO, OpFamilyOpFuncGroup::lefttype, lfirst, catclist::members, catclist::n_members, NameStr, ObjectIdGetDatum(), OidIsValid, ReleaseCatCacheList(), ReleaseSysCache(), OpFamilyOpFuncGroup::righttype, SearchSysCache1(), SearchSysCacheList1, and catctup::tuple.

Referenced by blhandler().

◆ initBloomState()

void initBloomState ( BloomState state,
Relation  index 
)

Definition at line 166 of file blutils.c.

167{
168 int i;
169
170 state->nColumns = index->rd_att->natts;
171
172 /* Initialize hash function for each attribute */
173 for (i = 0; i < index->rd_att->natts; i++)
174 {
175 fmgr_info_copy(&(state->hashFn[i]),
178 state->collations[i] = index->rd_indcollation[i];
179 }
180
181 /* Initialize amcache if needed with options from metapage */
182 if (!index->rd_amcache)
183 {
184 Buffer buffer;
185 Page page;
186 BloomMetaPageData *meta;
188
189 opts = MemoryContextAlloc(index->rd_indexcxt, sizeof(BloomOptions));
190
193
194 page = BufferGetPage(buffer);
195
196 if (!BloomPageIsMeta(page))
197 elog(ERROR, "Relation is not a bloom index");
198 meta = BloomPageGetMeta(BufferGetPage(buffer));
199
201 elog(ERROR, "Relation is not a bloom index");
202
203 *opts = meta->opts;
204
205 UnlockReleaseBuffer(buffer);
206
207 index->rd_amcache = opts;
208 }
209
210 memcpy(&state->opts, index->rd_amcache, sizeof(state->opts));
211 state->sizeOfBloomTuple = BLOOMTUPLEHDRSZ +
212 sizeof(BloomSignatureWord) * state->opts.bloomLength;
213}
#define BLOOMTUPLEHDRSZ
Definition: bloom.h:163
#define BloomPageIsMeta(page)
Definition: bloom.h:62
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:580
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:907
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1260

References BLOOM_HASH_PROC, BLOOM_MAGICK_NUMBER, BLOOM_METAPAGE_BLKNO, BloomPageGetMeta, BloomPageIsMeta, BLOOMTUPLEHDRSZ, BUFFER_LOCK_SHARE, BufferGetPage(), CurrentMemoryContext, elog, ERROR, fmgr_info_copy(), i, index_getprocinfo(), LockBuffer(), BloomMetaPageData::magickNumber, MemoryContextAlloc(), BloomMetaPageData::opts, opts, ReadBuffer(), and UnlockReleaseBuffer().

Referenced by blbeginscan(), blbuild(), blbulkdelete(), and blinsert().

◆ signValue()

void signValue ( BloomState state,
BloomSignatureWord sign,
Datum  value,
int  attno 
)

Definition at line 265 of file blutils.c.

266{
267 uint32 hashVal;
268 int nBit,
269 j;
270
271 /*
272 * init generator with "column's" number to get "hashed" seed for new
273 * value. We don't want to map the same numbers from different columns
274 * into the same bits!
275 */
276 mySrand(attno);
277
278 /*
279 * Init hash sequence to map our value into bits. the same values in
280 * different columns will be mapped into different bits because of step
281 * above
282 */
283 hashVal = DatumGetInt32(FunctionCall1Coll(&state->hashFn[attno], state->collations[attno], value));
284 mySrand(hashVal ^ myRand());
285
286 for (j = 0; j < state->opts.bitSize[attno]; j++)
287 {
288 /* prevent multiple evaluation in SETBIT macro */
289 nBit = myRand() % (state->opts.bloomLength * SIGNWORDBITS);
290 SETBIT(sign, nBit);
291 }
292}
static int32 myRand(void)
Definition: blutils.c:227
#define SETBIT(x, i)
Definition: blutils.c:29
static void mySrand(uint32 seed)
Definition: blutils.c:254
uint32_t uint32
Definition: c.h:502
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1129
static struct @165 value
char sign
Definition: informix.c:693
int j
Definition: isn.c:78
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207

References DatumGetInt32(), FunctionCall1Coll(), j, myRand(), mySrand(), SETBIT, sign, SIGNWORDBITS, and value.

Referenced by blgetbitmap(), and BloomFormTuple().