PostgreSQL Source Code  git master
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 131 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 134 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:213
#define MAXALIGN(LEN)
Definition: c.h:800
Definition: regguts.h:323

Definition at line 152 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 136 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:254

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 166 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 175 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 28 of file blscan.c.

29 {
30  IndexScanDesc scan;
31  BloomScanOpaque so;
32 
33  scan = RelationGetIndexScan(r, nkeys, norderbys);
34 
36  initBloomState(&so->state, scan->indexRelation);
37  so->sign = NULL;
38 
39  scan->opaque = so;
40 
41  return scan;
42 }
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:161
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:175
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:81
void * palloc(Size size)
Definition: mcxt.c:1226
BloomSignatureWord * sign
Definition: bloom.h:171
BloomState state
Definition: bloom.h:172
Relation indexRelation
Definition: relscan.h:118

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 121 of file blinsert.c.

122 {
123  IndexBuildResult *result;
124  double reltuples;
125  BloomBuildState buildstate;
126 
128  elog(ERROR, "index \"%s\" already contains data",
130 
131  /* Initialize the meta page */
133 
134  /* Initialize the bloom build state */
135  memset(&buildstate, 0, sizeof(buildstate));
136  initBloomState(&buildstate.blstate, index);
138  "Bloom build temporary context",
140  initCachedPage(&buildstate);
141 
142  /* Do the heap scan */
143  reltuples = table_index_build_scan(heap, index, indexInfo, true, true,
144  bloomBuildCallback, (void *) &buildstate,
145  NULL);
146 
147  /* Flush last page if needed (it will be, unless heap was empty) */
148  if (buildstate.count > 0)
149  flushCachedPage(index, &buildstate);
150 
151  MemoryContextDelete(buildstate.tmpCtx);
152 
153  result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
154  result->heap_tuples = reltuples;
155  result->index_tuples = buildstate.indtuples;
156 
157  return result;
158 }
static void initCachedPage(BloomBuildState *buildstate)
Definition: blinsert.c:64
static void flushCachedPage(Relation index, BloomBuildState *buildstate)
Definition: blinsert.c:47
static void bloomBuildCallback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition: blinsert.c:74
void BloomInitMetapage(Relation index, ForkNumber forknum)
Definition: blutils.c:446
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:227
#define ERROR
Definition: elog.h:39
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
#define RelationGetRelationName(relation)
Definition: rel.h:538
@ MAIN_FORKNUM
Definition: relpath.h:50
int64 indtuples
Definition: blinsert.c:36
BloomState blstate
Definition: blinsert.c:35
MemoryContext tmpCtx
Definition: blinsert.c:37
double heap_tuples
Definition: genam.h:32
double index_tuples
Definition: genam.h:33
Definition: type.h:95
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:1772

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 164 of file blinsert.c.

165 {
166  /* Initialize the meta page */
168 }
@ INIT_FORKNUM
Definition: relpath.h:53

References BloomInitMetapage(), and INIT_FORKNUM.

Referenced by blhandler().

◆ blbulkdelete()

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

Definition at line 34 of file blvacuum.c.

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

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 23 of file blcost.c.

27 {
28  IndexOptInfo *index = path->indexinfo;
29  GenericCosts costs = {0};
30 
31  /* We have to visit all index tuples anyway */
32  costs.numIndexTuples = index->tuples;
33 
34  /* Use generic estimate */
35  genericcostestimate(root, path, loop_count, &costs);
36 
37  *indexStartupCost = costs.indexStartupCost;
38  *indexTotalCost = costs.indexTotalCost;
39  *indexSelectivity = costs.indexSelectivity;
40  *indexCorrelation = costs.indexCorrelation;
41  *indexPages = costs.numIndexPages;
42 }
void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, GenericCosts *costs)
Definition: selfuncs.c:6431
Selectivity indexSelectivity
Definition: selfuncs.h:124
Cost indexStartupCost
Definition: selfuncs.h:122
double indexCorrelation
Definition: selfuncs.h:125
Cost indexTotalCost
Definition: selfuncs.h:123
double numIndexPages
Definition: selfuncs.h:128
double numIndexTuples
Definition: selfuncs.h:129
IndexOptInfo * indexinfo
Definition: pathnodes.h:1678

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

Referenced by blhandler().

◆ blendscan()

void blendscan ( IndexScanDesc  scan)

Definition at line 68 of file blscan.c.

69 {
71 
72  if (so->sign)
73  pfree(so->sign);
74  so->sign = NULL;
75 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
void pfree(void *pointer)
Definition: mcxt.c:1456

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

Referenced by blhandler().

◆ blgetbitmap()

int64 blgetbitmap ( IndexScanDesc  scan,
TIDBitmap tbm 
)

Definition at line 81 of file blscan.c.

82 {
83  int64 ntids = 0;
85  npages;
86  int i;
89 
90  if (so->sign == NULL)
91  {
92  /* New search: have to calculate search signature */
93  ScanKey skey = scan->keyData;
94 
95  so->sign = palloc0(sizeof(BloomSignatureWord) * so->state.opts.bloomLength);
96 
97  for (i = 0; i < scan->numberOfKeys; i++)
98  {
99  /*
100  * Assume bloom-indexable operators to be strict, so nothing could
101  * be found for NULL key.
102  */
103  if (skey->sk_flags & SK_ISNULL)
104  {
105  pfree(so->sign);
106  so->sign = NULL;
107  return 0;
108  }
109 
110  /* Add next value to the signature */
111  signValue(&so->state, so->sign, skey->sk_argument,
112  skey->sk_attno - 1);
113 
114  skey++;
115  }
116  }
117 
118  /*
119  * We're going to read the whole index. This is why we use appropriate
120  * buffer access strategy.
121  */
124 
125  for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
126  {
127  Buffer buffer;
128  Page page;
129 
131  blkno, RBM_NORMAL, bas);
132 
133  LockBuffer(buffer, BUFFER_LOCK_SHARE);
134  page = BufferGetPage(buffer);
135 
136  if (!PageIsNew(page) && !BloomPageIsDeleted(page))
137  {
138  OffsetNumber offset,
139  maxOffset = BloomPageGetMaxOffset(page);
140 
141  for (offset = 1; offset <= maxOffset; offset++)
142  {
143  BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
144  bool res = true;
145 
146  /* Check index signature with scan signature */
147  for (i = 0; i < so->state.opts.bloomLength; i++)
148  {
149  if ((itup->sign[i] & so->sign[i]) != so->sign[i])
150  {
151  res = false;
152  break;
153  }
154  }
155 
156  /* Add matching tuples to bitmap */
157  if (res)
158  {
159  tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
160  ntids++;
161  }
162  }
163  }
164 
165  UnlockReleaseBuffer(buffer);
167  }
168  FreeAccessStrategy(bas);
169 
170  return ntids;
171 }
uint16 BloomSignatureWord
Definition: bloom.h:84
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:260
@ BAS_BULKREAD
Definition: bufmgr.h:35
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:158
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:350
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:541
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition: freelist.c:639
int i
Definition: isn.c:73
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
uint16 OffsetNumber
Definition: off.h:24
#define SK_ISNULL
Definition: skey.h:115
int bloomLength
Definition: bloom.h:104
BloomOptions opts
Definition: bloom.h:142
BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]
Definition: bloom.h:163
struct ScanKeyData * keyData
Definition: relscan.h:122
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:376

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::keyData, LockBuffer(), MAIN_FORKNUM, IndexScanDescData::numberOfKeys, IndexScanDescData::opaque, BloomState::opts, PageIsNew(), palloc0(), pfree(), RBM_NORMAL, ReadBufferExtended(), RelationGetNumberOfBlocks, res, 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 174 of file blinsert.c.

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

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 414 of file blutils.c.

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

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 293 of file blutils.c.

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

References i, palloc0(), res, signValue(), and values.

Referenced by blinsert(), and bloomBuildCallback().

◆ BloomInitMetapage()

void BloomInitMetapage ( Relation  index,
ForkNumber  forknum 
)

Definition at line 446 of file blutils.c.

447 {
448  Buffer metaBuffer;
449  Page metaPage;
451 
452  /*
453  * Make a new page; since it is first page it should be associated with
454  * block number 0 (BLOOM_METAPAGE_BLKNO). No need to hold the extension
455  * lock because there cannot be concurrent inserters yet.
456  */
457  metaBuffer = ReadBufferExtended(index, forknum, P_NEW, RBM_NORMAL, NULL);
458  LockBuffer(metaBuffer, BUFFER_LOCK_EXCLUSIVE);
460 
461  /* Initialize contents of meta page */
463  metaPage = GenericXLogRegisterBuffer(state, metaBuffer,
465  BloomFillMetapage(index, metaPage);
467 
468  UnlockReleaseBuffer(metaBuffer);
469 }
void BloomFillMetapage(Relation index, Page metaPage)
Definition: blutils.c:414
#define P_NEW
Definition: bufmgr.h:152

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 399 of file blutils.c.

400 {
401  BloomPageOpaque opaque;
402 
403  PageInit(page, BLCKSZ, sizeof(BloomPageOpaqueData));
404 
405  opaque = BloomPageGetOpaque(page);
406  opaque->flags = flags;
407  opaque->bloom_page_id = BLOOM_PAGE_ID;
408 }
#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 353 of file blutils.c.

354 {
355  Buffer buffer;
356 
357  /* First, try to get a page from FSM */
358  for (;;)
359  {
361 
362  if (blkno == InvalidBlockNumber)
363  break;
364 
365  buffer = ReadBuffer(index, blkno);
366 
367  /*
368  * We have to guard against the possibility that someone else already
369  * recycled this page; the buffer may be locked if so.
370  */
371  if (ConditionalLockBuffer(buffer))
372  {
373  Page page = BufferGetPage(buffer);
374 
375  if (PageIsNew(page))
376  return buffer; /* OK to use, if never initialized */
377 
378  if (BloomPageIsDeleted(page))
379  return buffer; /* OK to use */
380 
382  }
383 
384  /* Can't use it, so release buffer and try again */
385  ReleaseBuffer(buffer);
386  }
387 
388  /* Must extend the file */
389  buffer = ExtendBufferedRel(BMR_REL(index), MAIN_FORKNUM, NULL,
390  EB_LOCK_FIRST);
391 
392  return buffer;
393 }
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
Definition: bufmgr.c:812
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:4741
@ EB_LOCK_FIRST
Definition: bufmgr.h:85
#define BMR_REL(p_rel)
Definition: bufmgr.h:106
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 318 of file blutils.c.

319 {
320  BloomTuple *itup;
321  BloomPageOpaque opaque;
322  Pointer ptr;
323 
324  /* We shouldn't be pointed to an invalid page */
325  Assert(!PageIsNew(page) && !BloomPageIsDeleted(page));
326 
327  /* Does new tuple fit on the page? */
328  if (BloomPageGetFreeSpace(state, page) < state->sizeOfBloomTuple)
329  return false;
330 
331  /* Copy new tuple to the end of page */
332  opaque = BloomPageGetOpaque(page);
333  itup = BloomPageGetTuple(state, page, opaque->maxoff + 1);
334  memcpy((Pointer) itup, (Pointer) tuple, state->sizeOfBloomTuple);
335 
336  /* Adjust maxoff and pd_lower */
337  opaque->maxoff++;
338  ptr = (Pointer) BloomPageGetTuple(state, page, opaque->maxoff + 1);
339  ((PageHeader) page)->pd_lower = ptr - page;
340 
341  /* Assert we didn't overrun available space */
342  Assert(((PageHeader) page)->pd_lower <= ((PageHeader) page)->pd_upper);
343 
344  return true;
345 }
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 475 of file blutils.c.

476 {
477  BloomOptions *rdopts;
478 
479  /* Parse the user-given reloptions */
480  rdopts = (BloomOptions *) build_reloptions(reloptions, validate,
482  sizeof(BloomOptions),
485 
486  /* Convert signature length from # of bits to # to words, rounding up */
487  if (rdopts)
488  rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
489 
490  return (bytea *) rdopts;
491 }
#define SIGNWORDBITS
Definition: bloom.h:86
static relopt_kind bl_relopt_kind
Definition: blutils.c:38
static relopt_parse_elt bl_relopt_tab[INDEX_MAX_KEYS+1]
Definition: blutils.c:41
#define lengthof(array)
Definition: c.h:777
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:1910
Definition: c.h:676

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

Referenced by blhandler().

◆ blrescan()

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

Definition at line 48 of file blscan.c.

50 {
52 
53  if (so->sign)
54  pfree(so->sign);
55  so->sign = NULL;
56 
57  if (scankey && scan->numberOfKeys > 0)
58  {
59  memmove(scan->keyData, scankey,
60  scan->numberOfKeys * sizeof(ScanKeyData));
61  }
62 }

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 169 of file blvacuum.c.

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

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 32 of file blvalidate.c.

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

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

Referenced by blhandler().

◆ initBloomState()

void initBloomState ( BloomState state,
Relation  index 
)

Definition at line 161 of file blutils.c.

162 {
163  int i;
164 
165  state->nColumns = index->rd_att->natts;
166 
167  /* Initialize hash function for each attribute */
168  for (i = 0; i < index->rd_att->natts; i++)
169  {
170  fmgr_info_copy(&(state->hashFn[i]),
173  state->collations[i] = index->rd_indcollation[i];
174  }
175 
176  /* Initialize amcache if needed with options from metapage */
177  if (!index->rd_amcache)
178  {
179  Buffer buffer;
180  Page page;
181  BloomMetaPageData *meta;
183 
184  opts = MemoryContextAlloc(index->rd_indexcxt, sizeof(BloomOptions));
185 
187  LockBuffer(buffer, BUFFER_LOCK_SHARE);
188 
189  page = BufferGetPage(buffer);
190 
191  if (!BloomPageIsMeta(page))
192  elog(ERROR, "Relation is not a bloom index");
193  meta = BloomPageGetMeta(BufferGetPage(buffer));
194 
195  if (meta->magickNumber != BLOOM_MAGICK_NUMBER)
196  elog(ERROR, "Relation is not a bloom index");
197 
198  *opts = meta->opts;
199 
200  UnlockReleaseBuffer(buffer);
201 
202  index->rd_amcache = (void *) opts;
203  }
204 
205  memcpy(&state->opts, index->rd_amcache, sizeof(state->opts));
206  state->sizeOfBloomTuple = BLOOMTUPLEHDRSZ +
207  sizeof(BloomSignatureWord) * state->opts.bloomLength;
208 }
#define BLOOMTUPLEHDRSZ
Definition: bloom.h:166
#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:811
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1021

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 260 of file blutils.c.

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

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

Referenced by blgetbitmap(), and BloomFormTuple().