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 "nodes/relation.h"
#include "fmgr.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_NPROC   1
 
#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 _PG_init (void)
 
void initBloomState (BloomState *state, Relation index)
 
void BloomFillMetapage (Relation index, Page metaPage)
 
void BloomInitMetapage (Relation index)
 
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, 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 46 of file bloom.h.

◆ BLOOM_EQUAL_STRATEGY

#define BLOOM_EQUAL_STRATEGY   1

Definition at line 28 of file bloom.h.

◆ BLOOM_HASH_PROC

#define BLOOM_HASH_PROC   1

Definition at line 24 of file bloom.h.

Referenced by blvalidate(), and initBloomState().

◆ BLOOM_HEAD_BLKNO

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

Definition at line 78 of file bloom.h.

Referenced by blbulkdelete(), blgetbitmap(), and blvacuumcleanup().

◆ BLOOM_MAGICK_NUMBER

#define BLOOM_MAGICK_NUMBER   (0xDBAC0DED)

Definition at line 130 of file bloom.h.

Referenced by BloomFillMetapage(), and initBloomState().

◆ BLOOM_META

#define BLOOM_META   (1<<0)

Definition at line 45 of file bloom.h.

Referenced by BloomFillMetapage().

◆ BLOOM_METAPAGE_BLKNO

#define BLOOM_METAPAGE_BLKNO   (0)

Definition at line 77 of file bloom.h.

Referenced by blbuildempty(), blbulkdelete(), blinsert(), BloomInitMetapage(), and initBloomState().

◆ BLOOM_NPROC

#define BLOOM_NPROC   1

Definition at line 25 of file bloom.h.

Referenced by blhandler(), and blvalidate().

◆ BLOOM_NSTRATEGIES

#define BLOOM_NSTRATEGIES   1

Definition at line 29 of file bloom.h.

Referenced by blhandler(), and blvalidate().

◆ BLOOM_PAGE_ID

#define BLOOM_PAGE_ID   0xFF83

Definition at line 56 of file bloom.h.

Referenced by BloomInitPage().

◆ BloomMetaBlockN

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

Definition at line 133 of file bloom.h.

Referenced by blbulkdelete().

◆ BloomPageGetData

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

Definition at line 69 of file bloom.h.

◆ BloomPageGetFreeSpace

#define BloomPageGetFreeSpace (   state,
  page 
)
Value:
- BloomPageGetMaxOffset(page) * (state)->sizeOfBloomTuple \
#define SizeOfPageHeaderData
Definition: bufpage.h:212
Definition: regguts.h:298
#define MAXALIGN(LEN)
Definition: c.h:623
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60

Definition at line 150 of file bloom.h.

Referenced by blbulkdelete(), and BloomPageAddItem().

◆ BloomPageGetMaxOffset

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

Definition at line 60 of file bloom.h.

Referenced by blbulkdelete(), blgetbitmap(), and blvacuumcleanup().

◆ BloomPageGetMeta

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

Definition at line 135 of file bloom.h.

Referenced by blbulkdelete(), blinsert(), BloomFillMetapage(), and initBloomState().

◆ BloomPageGetNextTuple

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

Definition at line 73 of file bloom.h.

Referenced by blbulkdelete().

◆ BloomPageGetOpaque

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

Definition at line 59 of file bloom.h.

Referenced by blbulkdelete(), BloomInitPage(), and BloomPageAddItem().

◆ BloomPageGetTuple

#define BloomPageGetTuple (   state,
  page,
  offset 
)
Value:
+ (state)->sizeOfBloomTuple * ((offset) - 1)))
#define PageGetContents(page)
Definition: bufpage.h:242
Definition: regguts.h:298

Definition at line 70 of file bloom.h.

Referenced by blbulkdelete(), blgetbitmap(), and BloomPageAddItem().

◆ BloomPageIsDeleted

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

◆ BloomPageIsMeta

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

Definition at line 61 of file bloom.h.

Referenced by initBloomState().

◆ BloomPageSetDeleted

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

Definition at line 65 of file bloom.h.

Referenced by blbulkdelete().

◆ BloomPageSetNonDeleted

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

Definition at line 67 of file bloom.h.

◆ BLOOMTUPLEHDRSZ

#define BLOOMTUPLEHDRSZ   offsetof(BloomTuple, sign)

Definition at line 164 of file bloom.h.

Referenced by initBloomState().

◆ DEFAULT_BLOOM_BITS

#define DEFAULT_BLOOM_BITS   2

Definition at line 96 of file bloom.h.

Referenced by _PG_init(), and makeDefaultBloomOptions().

◆ DEFAULT_BLOOM_LENGTH

#define DEFAULT_BLOOM_LENGTH   (5 * SIGNWORDBITS)

Definition at line 90 of file bloom.h.

Referenced by _PG_init(), and makeDefaultBloomOptions().

◆ MAX_BLOOM_BITS

#define MAX_BLOOM_BITS   (MAX_BLOOM_LENGTH - 1)

Definition at line 97 of file bloom.h.

Referenced by _PG_init().

◆ MAX_BLOOM_LENGTH

#define MAX_BLOOM_LENGTH   (256 * SIGNWORDBITS)

Definition at line 91 of file bloom.h.

Referenced by _PG_init().

◆ SIGNWORDBITS

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

Definition at line 85 of file bloom.h.

Referenced by bloptions(), makeDefaultBloomOptions(), and signValue().

Typedef Documentation

◆ BloomMetaPageData

◆ BloomOptions

◆ BloomPageOpaque

Definition at line 42 of file bloom.h.

◆ BloomPageOpaqueData

◆ BloomScanOpaque

Definition at line 173 of file bloom.h.

◆ BloomScanOpaqueData

◆ BloomSignatureWord

Definition at line 83 of file bloom.h.

◆ BloomState

◆ 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 117 of file bloom.h.

Function Documentation

◆ _PG_init()

void _PG_init ( void  )

Definition at line 56 of file auth_delay.c.

57 {
58  /* Define custom GUC variables */
59  DefineCustomIntVariable("auth_delay.milliseconds",
60  "Milliseconds to delay before reporting authentication failure",
61  NULL,
63  0,
64  0, INT_MAX / 1000,
65  PGC_SIGHUP,
67  NULL,
68  NULL,
69  NULL);
70  /* Install Hooks */
73 }
void DefineCustomIntVariable(const char *name, const char *short_desc, const char *long_desc, int *valueAddr, int bootValue, int minValue, int maxValue, GucContext context, int flags, GucIntCheckHook check_hook, GucIntAssignHook assign_hook, GucShowHook show_hook)
Definition: guc.c:7782
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:242
static ClientAuthentication_hook_type original_client_auth_hook
Definition: auth_delay.c:29
Definition: guc.h:72
static void auth_delay_checks(Port *port, int status)
Definition: auth_delay.c:35
static int auth_delay_milliseconds
Definition: auth_delay.c:26
#define GUC_UNIT_MS
Definition: guc.h:225

◆ blbeginscan()

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

Definition at line 29 of file blscan.c.

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

Referenced by blhandler().

30 {
31  IndexScanDesc scan;
32  BloomScanOpaque so;
33 
34  scan = RelationGetIndexScan(r, nkeys, norderbys);
35 
37  initBloomState(&so->state, scan->indexRelation);
38  so->sign = NULL;
39 
40  scan->opaque = so;
41 
42  return scan;
43 }
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:153
Relation indexRelation
Definition: relscan.h:90
BloomState state
Definition: bloom.h:170
void * palloc(Size size)
Definition: mcxt.c:848
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:78

◆ blbuild()

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

Definition at line 115 of file blinsert.c.

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

Referenced by blhandler().

116 {
117  IndexBuildResult *result;
118  double reltuples;
119  BloomBuildState buildstate;
120 
121  if (RelationGetNumberOfBlocks(index) != 0)
122  elog(ERROR, "index \"%s\" already contains data",
123  RelationGetRelationName(index));
124 
125  /* Initialize the meta page */
126  BloomInitMetapage(index);
127 
128  /* Initialize the bloom build state */
129  memset(&buildstate, 0, sizeof(buildstate));
130  initBloomState(&buildstate.blstate, index);
132  "Bloom build temporary context",
134  initCachedPage(&buildstate);
135 
136  /* Do the heap scan */
137  reltuples = IndexBuildHeapScan(heap, index, indexInfo, true,
138  bloomBuildCallback, (void *) &buildstate);
139 
140  /*
141  * There are could be some items in cached page. Flush this page if
142  * needed.
143  */
144  if (buildstate.count > 0)
145  flushCachedPage(index, &buildstate);
146 
147  MemoryContextDelete(buildstate.tmpCtx);
148 
149  result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult));
150  result->heap_tuples = result->index_tuples = reltuples;
151 
152  return result;
153 }
static void bloomBuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state)
Definition: blinsert.c:74
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:153
#define ERROR
Definition: elog.h:43
static void flushCachedPage(Relation index, BloomBuildState *buildstate)
Definition: blinsert.c:46
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:170
MemoryContext tmpCtx
Definition: blinsert.c:36
#define RelationGetRelationName(relation)
Definition: rel.h:445
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:342
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
static void initCachedPage(BloomBuildState *buildstate)
Definition: blinsert.c:63
double IndexBuildHeapScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, bool allow_sync, IndexBuildCallback callback, void *callback_state)
Definition: index.c:2178
void * palloc(Size size)
Definition: mcxt.c:848
BloomState blstate
Definition: blinsert.c:35
#define elog
Definition: elog.h:219
double index_tuples
Definition: genam.h:33
double heap_tuples
Definition: genam.h:32
void BloomInitMetapage(Relation index)
Definition: blutils.c:446

◆ blbuildempty()

void blbuildempty ( Relation  index)

Definition at line 159 of file blinsert.c.

References BLOOM_METAPAGE_BLKNO, BloomFillMetapage(), INIT_FORKNUM, log_newpage(), RelFileNodeBackend::node, PageSetChecksumInplace(), palloc(), RelationData::rd_smgr, SMgrRelationData::smgr_rnode, smgrimmedsync(), and smgrwrite().

Referenced by blhandler().

160 {
161  Page metapage;
162 
163  /* Construct metapage. */
164  metapage = (Page) palloc(BLCKSZ);
165  BloomFillMetapage(index, metapage);
166 
167  /*
168  * Write the page and log it. It might seem that an immediate sync would
169  * be sufficient to guarantee that the file exists on disk, but recovery
170  * itself might remove it while replaying, for example, an
171  * XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE record. Therefore, we need
172  * this even when wal_level=minimal.
173  */
176  (char *) metapage, true);
178  BLOOM_METAPAGE_BLKNO, metapage, true);
179 
180  /*
181  * An immediate sync is required even if we xlog'd the page, because the
182  * write did not go through shared_buffers and therefore a concurrent
183  * checkpoint may have moved the redo pointer past our xlog record.
184  */
186 }
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:77
struct SMgrRelationData * rd_smgr
Definition: rel.h:87
RelFileNodeBackend smgr_rnode
Definition: smgr.h:43
void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync)
Definition: smgr.c:647
RelFileNode node
Definition: relfilenode.h:74
void BloomFillMetapage(Relation index, Page metaPage)
Definition: blutils.c:414
void PageSetChecksumInplace(Page page, BlockNumber blkno)
Definition: bufpage.c:1195
void * palloc(Size size)
Definition: mcxt.c:848
XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
Definition: xloginsert.c:972
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:734
Pointer Page
Definition: bufpage.h:74

◆ blbulkdelete()

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

Definition at line 34 of file blvacuum.c.

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

Referenced by blhandler().

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 
51  initBloomState(&state, index);
52 
53  /*
54  * Iterate over the pages. We don't care about concurrently added pages,
55  * they can't contain tuples to delete.
56  */
57  npages = RelationGetNumberOfBlocks(index);
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  */
146  buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO);
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 }
BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(BloomPageOpaqueData)) - MAXALIGN(sizeof(uint16) *2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]
Definition: bloom.h:117
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:77
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
double tuples_removed
Definition: genam.h:77
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:153
uint16 nEnd
Definition: bloom.h:124
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
BufferAccessStrategy strategy
Definition: genam.h:51
Relation index
Definition: genam.h:46
uint32 BlockNumber
Definition: block.h:31
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:78
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:298
Definition: type.h:89
char * Pointer
Definition: c.h:273
#define BloomMetaBlockN
Definition: bloom.h:133
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define BloomPageGetOpaque(page)
Definition: bloom.h:59
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
#define BloomPageGetFreeSpace(state, page)
Definition: bloom.h:150
#define memmove(d, s, c)
Definition: c.h:1045
#define FirstOffsetNumber
Definition: off.h:27
FreeBlockNumberArray notFullPage
Definition: bloom.h:126
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:70
#define BloomPageGetMeta(page)
Definition: bloom.h:135
void * palloc0(Size size)
Definition: mcxt.c:877
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
#define BloomPageGetNextTuple(state, tuple)
Definition: bloom.h:73
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define Assert(condition)
Definition: c.h:670
Definition: regguts.h:298
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:336
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define OffsetNumberNext(offsetNumber)
Definition: off.h:53
uint16 nStart
Definition: bloom.h:123
ItemPointerData heapPtr
Definition: bloom.h:160
#define PageIsNew(page)
Definition: bufpage.h:225
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60
void GenericXLogAbort(GenericXLogState *state)
Definition: generic_xlog.c:447
void vacuum_delay_point(void)
Definition: vacuum.c:1695
Size sizeOfBloomTuple
Definition: bloom.h:147
int Buffer
Definition: buf.h:23
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:270
Pointer Page
Definition: bufpage.h:74
#define BloomPageSetDeleted(page)
Definition: bloom.h:65

◆ blcostestimate()

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

Definition at line 25 of file blcost.c.

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

Referenced by blhandler().

29 {
30  IndexOptInfo *index = path->indexinfo;
31  List *qinfos;
32  GenericCosts costs;
33 
34  /* Do preliminary analysis of indexquals */
35  qinfos = deconstruct_indexquals(path);
36 
37  MemSet(&costs, 0, sizeof(costs));
38 
39  /* We have to visit all index tuples anyway */
40  costs.numIndexTuples = index->tuples;
41 
42  /* Use generic estimate */
43  genericcostestimate(root, path, loop_count, qinfos, &costs);
44 
45  *indexStartupCost = costs.indexStartupCost;
46  *indexTotalCost = costs.indexTotalCost;
47  *indexSelectivity = costs.indexSelectivity;
48  *indexCorrelation = costs.indexCorrelation;
49  *indexPages = costs.numIndexPages;
50 }
Selectivity indexSelectivity
Definition: selfuncs.h:131
IndexOptInfo * indexinfo
Definition: relation.h:1119
#define MemSet(start, val, len)
Definition: c.h:853
double tuples
Definition: relation.h:725
List * deconstruct_indexquals(IndexPath *path)
Definition: selfuncs.c:6490
Definition: type.h:89
Cost indexTotalCost
Definition: selfuncs.h:130
double indexCorrelation
Definition: selfuncs.h:132
double numIndexTuples
Definition: selfuncs.h:136
Cost indexStartupCost
Definition: selfuncs.h:129
Definition: pg_list.h:45
void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, List *qinfos, GenericCosts *costs)
Definition: selfuncs.c:6639
double numIndexPages
Definition: selfuncs.h:135

◆ blendscan()

void blendscan ( IndexScanDesc  scan)

Definition at line 69 of file blscan.c.

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

Referenced by blhandler().

70 {
72 
73  if (so->sign)
74  pfree(so->sign);
75  so->sign = NULL;
76 }
void pfree(void *pointer)
Definition: mcxt.c:949
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169

◆ blgetbitmap()

int64 blgetbitmap ( IndexScanDesc  scan,
TIDBitmap tbm 
)

Definition at line 82 of file blscan.c.

References BAS_BULKREAD, BLOOM_HEAD_BLKNO, BloomOptions::bloomLength, BloomPageGetMaxOffset, BloomPageGetTuple, BloomPageIsDeleted, buffer, BUFFER_LOCK_SHARE, BufferGetPage, CHECK_FOR_INTERRUPTS, FreeAccessStrategy(), GetAccessStrategy(), BloomTuple::heapPtr, i, IndexScanDescData::indexRelation, IndexScanDescData::keyData, LockBuffer(), MAIN_FORKNUM, IndexScanDescData::numberOfKeys, IndexScanDescData::opaque, BloomState::opts, PageIsNew, palloc0(), pfree(), 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(), TestForOldSnapshot(), UnlockReleaseBuffer(), and IndexScanDescData::xs_snapshot.

Referenced by blhandler().

83 {
84  int64 ntids = 0;
86  npages;
87  int i;
90 
91  if (so->sign == NULL)
92  {
93  /* New search: have to calculate search signature */
94  ScanKey skey = scan->keyData;
95 
96  so->sign = palloc0(sizeof(BloomSignatureWord) * so->state.opts.bloomLength);
97 
98  for (i = 0; i < scan->numberOfKeys; i++)
99  {
100  /*
101  * Assume bloom-indexable operators to be strict, so nothing could
102  * be found for NULL key.
103  */
104  if (skey->sk_flags & SK_ISNULL)
105  {
106  pfree(so->sign);
107  so->sign = NULL;
108  return 0;
109  }
110 
111  /* Add next value to the signature */
112  signValue(&so->state, so->sign, skey->sk_argument,
113  skey->sk_attno - 1);
114 
115  skey++;
116  }
117  }
118 
119  /*
120  * We're going to read the whole index. This is why we use appropriate
121  * buffer access strategy.
122  */
125 
126  for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
127  {
128  Buffer buffer;
129  Page page;
130 
132  blkno, RBM_NORMAL, bas);
133 
134  LockBuffer(buffer, BUFFER_LOCK_SHARE);
135  page = BufferGetPage(buffer);
136  TestForOldSnapshot(scan->xs_snapshot, scan->indexRelation, page);
137 
138  if (!PageIsNew(page) && !BloomPageIsDeleted(page))
139  {
140  OffsetNumber offset,
141  maxOffset = BloomPageGetMaxOffset(page);
142 
143  for (offset = 1; offset <= maxOffset; offset++)
144  {
145  BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
146  bool res = true;
147 
148  /* Check index signature with scan signature */
149  for (i = 0; i < so->state.opts.bloomLength; i++)
150  {
151  if ((itup->sign[i] & so->sign[i]) != so->sign[i])
152  {
153  res = false;
154  break;
155  }
156  }
157 
158  /* Add matching tuples to bitmap */
159  if (res)
160  {
161  tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
162  ntids++;
163  }
164  }
165  }
166 
167  UnlockReleaseBuffer(buffer);
169  }
170  FreeAccessStrategy(bas);
171 
172  return ntids;
173 }
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:542
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
static void TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page)
Definition: bufmgr.h:265
BloomOptions opts
Definition: bloom.h:140
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:251
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
Definition: tidbitmap.c:376
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
Snapshot xs_snapshot
Definition: relscan.h:91
uint32 BlockNumber
Definition: block.h:31
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:78
Relation indexRelation
Definition: relscan.h:90
uint16 OffsetNumber
Definition: off.h:24
uint16 BloomSignatureWord
Definition: bloom.h:83
void pfree(void *pointer)
Definition: mcxt.c:949
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:70
#define SK_ISNULL
Definition: skey.h:115
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void * palloc0(Size size)
Definition: mcxt.c:877
BloomState state
Definition: bloom.h:170
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition: freelist.c:597
int sk_flags
Definition: skey.h:66
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
ScanKey keyData
Definition: relscan.h:94
BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]
Definition: bloom.h:161
int bloomLength
Definition: bloom.h:103
ItemPointerData heapPtr
Definition: bloom.h:160
#define PageIsNew(page)
Definition: bufpage.h:225
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60
int i
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
int Buffer
Definition: buf.h:23
Datum sk_argument
Definition: skey.h:72
AttrNumber sk_attno
Definition: skey.h:67
Pointer Page
Definition: bufpage.h:74

◆ blinsert()

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

Definition at line 192 of file blinsert.c.

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate(), Assert, BLOOM_METAPAGE_BLKNO, BloomFormTuple(), BloomInitPage(), BloomNewBuffer(), BloomPageAddItem(), BloomPageGetMeta, BloomPageIsDeleted, buffer, 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(), and UnlockReleaseBuffer().

Referenced by blhandler().

196 {
197  BloomState blstate;
198  BloomTuple *itup;
199  MemoryContext oldCtx;
200  MemoryContext insertCtx;
201  BloomMetaPageData *metaData;
202  Buffer buffer,
203  metaBuffer;
204  Page page,
205  metaPage;
207  OffsetNumber nStart;
209 
211  "Bloom insert temporary context",
213 
214  oldCtx = MemoryContextSwitchTo(insertCtx);
215 
216  initBloomState(&blstate, index);
217  itup = BloomFormTuple(&blstate, ht_ctid, values, isnull);
218 
219  /*
220  * At first, try to insert new tuple to the first page in notFullPage
221  * array. If successful, we don't need to modify the meta page.
222  */
223  metaBuffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO);
224  LockBuffer(metaBuffer, BUFFER_LOCK_SHARE);
225  metaData = BloomPageGetMeta(BufferGetPage(metaBuffer));
226 
227  if (metaData->nEnd > metaData->nStart)
228  {
229  Page page;
230 
231  blkno = metaData->notFullPage[metaData->nStart];
232  Assert(blkno != InvalidBlockNumber);
233 
234  /* Don't hold metabuffer lock while doing insert */
235  LockBuffer(metaBuffer, BUFFER_LOCK_UNLOCK);
236 
237  buffer = ReadBuffer(index, blkno);
239 
240  state = GenericXLogStart(index);
241  page = GenericXLogRegisterBuffer(state, buffer, 0);
242 
243  /*
244  * We might have found a page that was recently deleted by VACUUM. If
245  * so, we can reuse it, but we must reinitialize it.
246  */
247  if (PageIsNew(page) || BloomPageIsDeleted(page))
248  BloomInitPage(page, 0);
249 
250  if (BloomPageAddItem(&blstate, page, itup))
251  {
252  /* Success! Apply the change, clean up, and exit */
253  GenericXLogFinish(state);
254  UnlockReleaseBuffer(buffer);
255  ReleaseBuffer(metaBuffer);
256  MemoryContextSwitchTo(oldCtx);
257  MemoryContextDelete(insertCtx);
258  return false;
259  }
260 
261  /* Didn't fit, must try other pages */
262  GenericXLogAbort(state);
263  UnlockReleaseBuffer(buffer);
264  }
265  else
266  {
267  /* No entries in notFullPage */
268  LockBuffer(metaBuffer, BUFFER_LOCK_UNLOCK);
269  }
270 
271  /*
272  * Try other pages in notFullPage array. We will have to change nStart in
273  * metapage. Thus, grab exclusive lock on metapage.
274  */
275  LockBuffer(metaBuffer, BUFFER_LOCK_EXCLUSIVE);
276 
277  /* nStart might have changed while we didn't have lock */
278  nStart = metaData->nStart;
279 
280  /* Skip first page if we already tried it above */
281  if (nStart < metaData->nEnd &&
282  blkno == metaData->notFullPage[nStart])
283  nStart++;
284 
285  /*
286  * This loop iterates for each page we try from the notFullPage array, and
287  * will also initialize a GenericXLogState for the fallback case of having
288  * to allocate a new page.
289  */
290  for (;;)
291  {
292  state = GenericXLogStart(index);
293 
294  /* get modifiable copy of metapage */
295  metaPage = GenericXLogRegisterBuffer(state, metaBuffer, 0);
296  metaData = BloomPageGetMeta(metaPage);
297 
298  if (nStart >= metaData->nEnd)
299  break; /* no more entries in notFullPage array */
300 
301  blkno = metaData->notFullPage[nStart];
302  Assert(blkno != InvalidBlockNumber);
303 
304  buffer = ReadBuffer(index, blkno);
306  page = GenericXLogRegisterBuffer(state, buffer, 0);
307 
308  /* Basically same logic as above */
309  if (PageIsNew(page) || BloomPageIsDeleted(page))
310  BloomInitPage(page, 0);
311 
312  if (BloomPageAddItem(&blstate, page, itup))
313  {
314  /* Success! Apply the changes, clean up, and exit */
315  metaData->nStart = nStart;
316  GenericXLogFinish(state);
317  UnlockReleaseBuffer(buffer);
318  UnlockReleaseBuffer(metaBuffer);
319  MemoryContextSwitchTo(oldCtx);
320  MemoryContextDelete(insertCtx);
321  return false;
322  }
323 
324  /* Didn't fit, must try other pages */
325  GenericXLogAbort(state);
326  UnlockReleaseBuffer(buffer);
327  nStart++;
328  }
329 
330  /*
331  * Didn't find place to insert in notFullPage array. Allocate new page.
332  * (XXX is it good to do this while holding ex-lock on the metapage??)
333  */
334  buffer = BloomNewBuffer(index);
335 
336  page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE);
337  BloomInitPage(page, 0);
338 
339  if (!BloomPageAddItem(&blstate, page, itup))
340  {
341  /* We shouldn't be here since we're inserting to an empty page */
342  elog(ERROR, "could not add new bloom tuple to empty page");
343  }
344 
345  /* Reset notFullPage array to contain just this new page */
346  metaData->nStart = 0;
347  metaData->nEnd = 1;
348  metaData->notFullPage[0] = BufferGetBlockNumber(buffer);
349 
350  /* Apply the changes, clean up, and exit */
351  GenericXLogFinish(state);
352 
353  UnlockReleaseBuffer(buffer);
354  UnlockReleaseBuffer(metaBuffer);
355 
356  MemoryContextSwitchTo(oldCtx);
357  MemoryContextDelete(insertCtx);
358 
359  return false;
360 }
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:77
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:200
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:153
uint16 nEnd
Definition: bloom.h:124
Buffer BloomNewBuffer(Relation index)
Definition: blutils.c:344
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:298
uint16 OffsetNumber
Definition: off.h:24
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
void BloomInitPage(Page page, uint16 flags)
Definition: blutils.c:398
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:170
bool BloomPageAddItem(BloomState *state, Page page, BloomTuple *tuple)
Definition: blutils.c:309
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
FreeBlockNumberArray notFullPage
Definition: bloom.h:126
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BloomPageGetMeta(page)
Definition: bloom.h:135
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:342
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define Assert(condition)
Definition: c.h:670
Definition: regguts.h:298
BloomTuple * BloomFormTuple(BloomState *state, ItemPointer iptr, Datum *values, bool *isnull)
Definition: blutils.c:284
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:336
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define InvalidBlockNumber
Definition: block.h:33
uint16 nStart
Definition: bloom.h:123
static Datum values[MAXATTR]
Definition: bootstrap.c:164
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
#define PageIsNew(page)
Definition: bufpage.h:225
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
void GenericXLogAbort(GenericXLogState *state)
Definition: generic_xlog.c:447
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:270
Pointer Page
Definition: bufpage.h:74

◆ BloomFillMetapage()

void BloomFillMetapage ( Relation  index,
Page  metaPage 
)

Definition at line 414 of file blutils.c.

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

Referenced by blbuildempty(), and BloomInitMetapage().

415 {
416  BloomOptions *opts;
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)
425  opts = makeDefaultBloomOptions();
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 }
static BloomOptions * makeDefaultBloomOptions(void)
Definition: blutils.c:86
#define BloomPageGetMeta(page)
Definition: bloom.h:135
BloomOptions opts
Definition: bloom.h:125
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define Assert(condition)
Definition: c.h:670
uint32 magickNumber
Definition: bloom.h:122
void BloomInitPage(Page page, uint16 flags)
Definition: blutils.c:398
#define BLOOM_META
Definition: bloom.h:45
struct BloomMetaPageData BloomMetaPageData
#define BLOOM_MAGICK_NUMBER
Definition: bloom.h:130
bytea * rd_options
Definition: rel.h:156

◆ BloomFormTuple()

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

Definition at line 284 of file blutils.c.

References BloomTuple::heapPtr, i, BloomState::nColumns, palloc0(), BloomTuple::sign, signValue(), and BloomState::sizeOfBloomTuple.

Referenced by blinsert(), and bloomBuildCallback().

285 {
286  int i;
287  BloomTuple *res = (BloomTuple *) palloc0(state->sizeOfBloomTuple);
288 
289  res->heapPtr = *iptr;
290 
291  /* Blooming each column */
292  for (i = 0; i < state->nColumns; i++)
293  {
294  /* skip nulls */
295  if (isnull[i])
296  continue;
297 
298  signValue(state, res->sign, values[i], i);
299  }
300 
301  return res;
302 }
void * palloc0(Size size)
Definition: mcxt.c:877
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:251
int32 nColumns
Definition: bloom.h:141
BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]
Definition: bloom.h:161
static Datum values[MAXATTR]
Definition: bootstrap.c:164
ItemPointerData heapPtr
Definition: bloom.h:160
int i
Size sizeOfBloomTuple
Definition: bloom.h:147

◆ BloomInitMetapage()

void BloomInitMetapage ( Relation  index)

Definition at line 446 of file blutils.c.

References Assert, BLOOM_METAPAGE_BLKNO, BloomFillMetapage(), BloomNewBuffer(), BufferGetBlockNumber(), GENERIC_XLOG_FULL_IMAGE, GenericXLogFinish(), GenericXLogRegisterBuffer(), GenericXLogStart(), and UnlockReleaseBuffer().

Referenced by blbuild().

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).
455  */
456  metaBuffer = BloomNewBuffer(index);
458 
459  /* Initialize contents of meta page */
460  state = GenericXLogStart(index);
461  metaPage = GenericXLogRegisterBuffer(state, metaBuffer,
463  BloomFillMetapage(index, metaPage);
464  GenericXLogFinish(state);
465 
466  UnlockReleaseBuffer(metaBuffer);
467 }
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:77
Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, int flags)
Definition: generic_xlog.c:298
Buffer BloomNewBuffer(Relation index)
Definition: blutils.c:344
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
void BloomFillMetapage(Relation index, Page metaPage)
Definition: blutils.c:414
#define Assert(condition)
Definition: c.h:670
Definition: regguts.h:298
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:336
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
int Buffer
Definition: buf.h:23
#define GENERIC_XLOG_FULL_IMAGE
Definition: generic_xlog.h:26
GenericXLogState * GenericXLogStart(Relation relation)
Definition: generic_xlog.c:270
Pointer Page
Definition: bufpage.h:74

◆ BloomInitPage()

void BloomInitPage ( Page  page,
uint16  flags 
)

Definition at line 398 of file blutils.c.

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

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

399 {
400  BloomPageOpaque opaque;
401 
402  PageInit(page, BLCKSZ, sizeof(BloomPageOpaqueData));
403 
404  opaque = BloomPageGetOpaque(page);
405  memset(opaque, 0, sizeof(BloomPageOpaqueData));
406  opaque->flags = flags;
407  opaque->bloom_page_id = BLOOM_PAGE_ID;
408 }
#define BLOOM_PAGE_ID
Definition: bloom.h:56
uint16 bloom_page_id
Definition: bloom.h:39
uint16 flags
Definition: bloom.h:35
#define BloomPageGetOpaque(page)
Definition: bloom.h:59
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:41

◆ BloomNewBuffer()

Buffer BloomNewBuffer ( Relation  index)

Definition at line 344 of file blutils.c.

References BloomPageIsDeleted, buffer, BUFFER_LOCK_EXCLUSIVE, BUFFER_LOCK_UNLOCK, BufferGetPage, ConditionalLockBuffer(), ExclusiveLock, GetFreeIndexPage(), InvalidBlockNumber, LockBuffer(), LockRelationForExtension(), P_NEW, PageIsNew, ReadBuffer(), RELATION_IS_LOCAL, ReleaseBuffer(), and UnlockRelationForExtension().

Referenced by blinsert(), BloomInitMetapage(), and flushCachedPage().

345 {
346  Buffer buffer;
347  bool needLock;
348 
349  /* First, try to get a page from FSM */
350  for (;;)
351  {
352  BlockNumber blkno = GetFreeIndexPage(index);
353 
354  if (blkno == InvalidBlockNumber)
355  break;
356 
357  buffer = ReadBuffer(index, blkno);
358 
359  /*
360  * We have to guard against the possibility that someone else already
361  * recycled this page; the buffer may be locked if so.
362  */
363  if (ConditionalLockBuffer(buffer))
364  {
365  Page page = BufferGetPage(buffer);
366 
367  if (PageIsNew(page))
368  return buffer; /* OK to use, if never initialized */
369 
370  if (BloomPageIsDeleted(page))
371  return buffer; /* OK to use */
372 
374  }
375 
376  /* Can't use it, so release buffer and try again */
377  ReleaseBuffer(buffer);
378  }
379 
380  /* Must extend the file */
381  needLock = !RELATION_IS_LOCAL(index);
382  if (needLock)
384 
385  buffer = ReadBuffer(index, P_NEW);
387 
388  if (needLock)
390 
391  return buffer;
392 }
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
#define ExclusiveLock
Definition: lockdefs.h:44
#define RELATION_IS_LOCAL(relation)
Definition: rel.h:532
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
#define P_NEW
Definition: bufmgr.h:82
#define BUFFER_LOCK_EXCLUSIVE
Definition: bufmgr.h:89
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
bool ConditionalLockBuffer(Buffer buffer)
Definition: bufmgr.c:3572
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:332
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition: lmgr.c:382
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
BlockNumber GetFreeIndexPage(Relation rel)
Definition: indexfsm.c:38
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define InvalidBlockNumber
Definition: block.h:33
#define PageIsNew(page)
Definition: bufpage.h:225
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74

◆ BloomPageAddItem()

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

Definition at line 309 of file blutils.c.

References Assert, BloomPageGetFreeSpace, BloomPageGetOpaque, BloomPageGetTuple, BloomPageIsDeleted, BloomPageOpaqueData::maxoff, PageIsNew, and BloomState::sizeOfBloomTuple.

Referenced by blinsert(), and bloomBuildCallback().

310 {
311  BloomTuple *itup;
312  BloomPageOpaque opaque;
313  Pointer ptr;
314 
315  /* We shouldn't be pointed to an invalid page */
316  Assert(!PageIsNew(page) && !BloomPageIsDeleted(page));
317 
318  /* Does new tuple fit on the page? */
319  if (BloomPageGetFreeSpace(state, page) < state->sizeOfBloomTuple)
320  return false;
321 
322  /* Copy new tuple to the end of page */
323  opaque = BloomPageGetOpaque(page);
324  itup = BloomPageGetTuple(state, page, opaque->maxoff + 1);
325  memcpy((Pointer) itup, (Pointer) tuple, state->sizeOfBloomTuple);
326 
327  /* Adjust maxoff and pd_lower */
328  opaque->maxoff++;
329  ptr = (Pointer) BloomPageGetTuple(state, page, opaque->maxoff + 1);
330  ((PageHeader) page)->pd_lower = ptr - page;
331 
332  /* Assert we didn't overrun available space */
333  Assert(((PageHeader) page)->pd_lower <= ((PageHeader) page)->pd_upper);
334 
335  return true;
336 }
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
OffsetNumber maxoff
Definition: bloom.h:34
char * Pointer
Definition: c.h:273
#define BloomPageGetOpaque(page)
Definition: bloom.h:59
#define BloomPageGetFreeSpace(state, page)
Definition: bloom.h:150
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:70
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define Assert(condition)
Definition: c.h:670
#define PageIsNew(page)
Definition: bufpage.h:225
Size sizeOfBloomTuple
Definition: bloom.h:147

◆ bloptions()

bytea* bloptions ( Datum  reloptions,
bool  validate 
)

Definition at line 473 of file blutils.c.

References allocateReloptStruct(), bl_relopt_kind, fillRelOptions(), lengthof, options, parseRelOptions(), and SIGNWORDBITS.

Referenced by blhandler().

474 {
476  int numoptions;
477  BloomOptions *rdopts;
478 
479  /* Parse the user-given reloptions */
480  options = parseRelOptions(reloptions, validate, bl_relopt_kind, &numoptions);
481  rdopts = allocateReloptStruct(sizeof(BloomOptions), options, numoptions);
482  fillRelOptions((void *) rdopts, sizeof(BloomOptions), options, numoptions,
483  validate, bl_relopt_tab, lengthof(bl_relopt_tab));
484 
485  /* Convert signature length from # of bits to # to words, rounding up */
486  rdopts->bloomLength = (rdopts->bloomLength + SIGNWORDBITS - 1) / SIGNWORDBITS;
487 
488  return (bytea *) rdopts;
489 }
#define lengthof(array)
Definition: c.h:600
static relopt_kind bl_relopt_kind
Definition: blutils.c:39
static relopt_parse_elt bl_relopt_tab[INDEX_MAX_KEYS+1]
Definition: blutils.c:42
#define SIGNWORDBITS
Definition: bloom.h:85
void * allocateReloptStruct(Size base, relopt_value *options, int numoptions)
Definition: reloptions.c:1225
static char ** options
void fillRelOptions(void *rdopts, Size basesize, relopt_value *options, int numoptions, bool validate, const relopt_parse_elt *elems, int numelems)
Definition: reloptions.c:1249
Definition: c.h:487
relopt_value * parseRelOptions(Datum options, bool validate, relopt_kind kind, int *numrelopts)
Definition: reloptions.c:1030

◆ blrescan()

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

Definition at line 49 of file blscan.c.

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

Referenced by blhandler().

51 {
53 
54  if (so->sign)
55  pfree(so->sign);
56  so->sign = NULL;
57 
58  if (scankey && scan->numberOfKeys > 0)
59  {
60  memmove(scan->keyData, scankey,
61  scan->numberOfKeys * sizeof(ScanKeyData));
62  }
63 }
void pfree(void *pointer)
Definition: mcxt.c:949
#define memmove(d, s, c)
Definition: c.h:1045
ScanKey keyData
Definition: relscan.h:94
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169

◆ blvacuumcleanup()

IndexBulkDeleteResult* blvacuumcleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 169 of file blvacuum.c.

References IndexVacuumInfo::analyze_only, BLOOM_HEAD_BLKNO, BloomPageGetMaxOffset, BloomPageIsDeleted, buffer, 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().

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  */
185  npages = RelationGetNumberOfBlocks(index);
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 }
#define BloomPageIsDeleted(page)
Definition: bloom.h:63
bool analyze_only
Definition: genam.h:47
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
BufferAccessStrategy strategy
Definition: genam.h:51
Relation index
Definition: genam.h:46
uint32 BlockNumber
Definition: block.h:31
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:78
Definition: type.h:89
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
BlockNumber num_pages
Definition: genam.h:73
BlockNumber pages_free
Definition: genam.h:79
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
void * palloc0(Size size)
Definition: mcxt.c:877
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
void IndexFreeSpaceMapVacuum(Relation rel)
Definition: indexfsm.c:71
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
#define PageIsNew(page)
Definition: bufpage.h:225
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
void vacuum_delay_point(void)
Definition: vacuum.c:1695
void RecordFreeIndexPage(Relation rel, BlockNumber freeBlock)
Definition: indexfsm.c:52
double num_index_tuples
Definition: genam.h:76
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74

◆ blvalidate()

bool blvalidate ( Oid  opclassoid)

Definition at line 33 of file blvalidate.c.

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

Referenced by blhandler().

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

◆ initBloomState()

void initBloomState ( BloomState state,
Relation  index 
)

Definition at line 153 of file blutils.c.

References BLOOM_HASH_PROC, BLOOM_MAGICK_NUMBER, BLOOM_METAPAGE_BLKNO, BloomOptions::bloomLength, BloomPageGetMeta, BloomPageIsMeta, BLOOMTUPLEHDRSZ, buffer, BUFFER_LOCK_SHARE, BufferGetPage, CurrentMemoryContext, elog, ERROR, fmgr_info_copy(), BloomState::hashFn, i, index_getprocinfo(), LockBuffer(), BloomMetaPageData::magickNumber, MemoryContextAlloc(), tupleDesc::natts, BloomState::nColumns, BloomMetaPageData::opts, BloomState::opts, RelationData::rd_amcache, RelationData::rd_att, RelationData::rd_indexcxt, ReadBuffer(), BloomState::sizeOfBloomTuple, and UnlockReleaseBuffer().

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

154 {
155  int i;
156 
157  state->nColumns = index->rd_att->natts;
158 
159  /* Initialize hash function for each attribute */
160  for (i = 0; i < index->rd_att->natts; i++)
161  {
162  fmgr_info_copy(&(state->hashFn[i]),
163  index_getprocinfo(index, i + 1, BLOOM_HASH_PROC),
165  }
166 
167  /* Initialize amcache if needed with options from metapage */
168  if (!index->rd_amcache)
169  {
170  Buffer buffer;
171  Page page;
172  BloomMetaPageData *meta;
173  BloomOptions *opts;
174 
175  opts = MemoryContextAlloc(index->rd_indexcxt, sizeof(BloomOptions));
176 
177  buffer = ReadBuffer(index, BLOOM_METAPAGE_BLKNO);
178  LockBuffer(buffer, BUFFER_LOCK_SHARE);
179 
180  page = BufferGetPage(buffer);
181 
182  if (!BloomPageIsMeta(page))
183  elog(ERROR, "Relation is not a bloom index");
184  meta = BloomPageGetMeta(BufferGetPage(buffer));
185 
186  if (meta->magickNumber != BLOOM_MAGICK_NUMBER)
187  elog(ERROR, "Relation is not a bloom index");
188 
189  *opts = meta->opts;
190 
191  UnlockReleaseBuffer(buffer);
192 
193  index->rd_amcache = (void *) opts;
194  }
195 
196  memcpy(&state->opts, index->rd_amcache, sizeof(state->opts));
198  sizeof(BloomSignatureWord) * state->opts.bloomLength;
199 }
#define BLOOM_METAPAGE_BLKNO
Definition: bloom.h:77
BloomOptions opts
Definition: bloom.h:140
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
Definition: indexam.c:855
#define BloomPageIsMeta(page)
Definition: bloom.h:61
FmgrInfo hashFn[INDEX_MAX_KEYS]
Definition: bloom.h:139
int natts
Definition: tupdesc.h:79
uint16 BloomSignatureWord
Definition: bloom.h:83
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3332
#define ERROR
Definition: elog.h:43
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
Definition: fmgr.c:519
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define BloomPageGetMeta(page)
Definition: bloom.h:135
#define BLOOMTUPLEHDRSZ
Definition: bloom.h:164
BloomOptions opts
Definition: bloom.h:125
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
int32 nColumns
Definition: bloom.h:141
TupleDesc rd_att
Definition: rel.h:115
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
int bloomLength
Definition: bloom.h:103
uint32 magickNumber
Definition: bloom.h:122
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:706
MemoryContext rd_indexcxt
Definition: rel.h:179
int i
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define elog
Definition: elog.h:219
void * rd_amcache
Definition: rel.h:192
#define BLOOM_MAGICK_NUMBER
Definition: bloom.h:130
Size sizeOfBloomTuple
Definition: bloom.h:147
int Buffer
Definition: buf.h:23
#define BLOOM_HASH_PROC
Definition: bloom.h:24
Pointer Page
Definition: bufpage.h:74

◆ signValue()

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

Definition at line 251 of file blutils.c.

References BloomOptions::bitSize, BloomOptions::bloomLength, DatumGetInt32, FunctionCall1, BloomState::hashFn, myRand(), mySrand(), BloomState::opts, SETBIT, and SIGNWORDBITS.

Referenced by blgetbitmap(), and BloomFormTuple().

252 {
253  uint32 hashVal;
254  int nBit,
255  j;
256 
257  /*
258  * init generator with "column's" number to get "hashed" seed for new
259  * value. We don't want to map the same numbers from different columns
260  * into the same bits!
261  */
262  mySrand(attno);
263 
264  /*
265  * Init hash sequence to map our value into bits. the same values in
266  * different columns will be mapped into different bits because of step
267  * above
268  */
269  hashVal = DatumGetInt32(FunctionCall1(&state->hashFn[attno], value));
270  mySrand(hashVal ^ myRand());
271 
272  for (j = 0; j < state->opts.bitSize[attno]; j++)
273  {
274  /* prevent multiple evaluation in SETBIT macro */
275  nBit = myRand() % (state->opts.bloomLength * SIGNWORDBITS);
276  SETBIT(sign, nBit);
277  }
278 }
#define SETBIT(x, i)
Definition: blutils.c:33
BloomOptions opts
Definition: bloom.h:140
#define DatumGetInt32(X)
Definition: postgres.h:478
FmgrInfo hashFn[INDEX_MAX_KEYS]
Definition: bloom.h:139
int bitSize[INDEX_MAX_KEYS]
Definition: bloom.h:104
#define SIGNWORDBITS
Definition: bloom.h:85
static struct @121 value
char sign
Definition: informix.c:693
unsigned int uint32
Definition: c.h:296
static int32 myRand(void)
Definition: blutils.c:213
static void mySrand(uint32 seed)
Definition: blutils.c:240
int bloomLength
Definition: bloom.h:103
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:603