PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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

#define BLOOM_DELETED   (2<<0)

Definition at line 46 of file bloom.h.

#define BLOOM_EQUAL_STRATEGY   1

Definition at line 28 of file bloom.h.

#define BLOOM_HASH_PROC   1

Definition at line 24 of file bloom.h.

Referenced by blvalidate(), and initBloomState().

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

Definition at line 78 of file bloom.h.

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

#define BLOOM_MAGICK_NUMBER   (0xDBAC0DED)

Definition at line 130 of file bloom.h.

Referenced by BloomFillMetapage(), and initBloomState().

#define BLOOM_META   (1<<0)

Definition at line 45 of file bloom.h.

Referenced by BloomFillMetapage().

#define BLOOM_METAPAGE_BLKNO   (0)

Definition at line 77 of file bloom.h.

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

#define BLOOM_NPROC   1

Definition at line 25 of file bloom.h.

Referenced by blhandler(), and blvalidate().

#define BLOOM_NSTRATEGIES   1

Definition at line 29 of file bloom.h.

Referenced by blhandler(), and blvalidate().

#define BLOOM_PAGE_ID   0xFF83

Definition at line 56 of file bloom.h.

Referenced by BloomInitPage().

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

Definition at line 133 of file bloom.h.

Referenced by blbulkdelete().

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

Definition at line 69 of file bloom.h.

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

Definition at line 150 of file bloom.h.

Referenced by blbulkdelete(), and BloomPageAddItem().

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

Definition at line 60 of file bloom.h.

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

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

Definition at line 135 of file bloom.h.

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

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

Definition at line 73 of file bloom.h.

Referenced by blbulkdelete().

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

Definition at line 59 of file bloom.h.

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

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

Definition at line 70 of file bloom.h.

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

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

Definition at line 61 of file bloom.h.

Referenced by initBloomState().

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

Definition at line 65 of file bloom.h.

Referenced by blbulkdelete().

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

Definition at line 67 of file bloom.h.

#define BLOOMTUPLEHDRSZ   offsetof(BloomTuple, sign)

Definition at line 164 of file bloom.h.

Referenced by initBloomState().

#define DEFAULT_BLOOM_BITS   2

Definition at line 96 of file bloom.h.

Referenced by _PG_init(), and makeDefaultBloomOptions().

#define DEFAULT_BLOOM_LENGTH   (5 * SIGNWORDBITS)

Definition at line 90 of file bloom.h.

Referenced by _PG_init(), and makeDefaultBloomOptions().

#define MAX_BLOOM_BITS   (MAX_BLOOM_LENGTH - 1)

Definition at line 97 of file bloom.h.

Referenced by _PG_init().

#define MAX_BLOOM_LENGTH   (256 * SIGNWORDBITS)

Definition at line 91 of file bloom.h.

Referenced by _PG_init().

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

Definition at line 85 of file bloom.h.

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

Typedef Documentation

Definition at line 42 of file bloom.h.

Definition at line 173 of file bloom.h.

Definition at line 83 of file bloom.h.

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

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:7719
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
#define NULL
Definition: c.h:229
static int auth_delay_milliseconds
Definition: auth_delay.c:26
#define GUC_UNIT_MS
Definition: guc.h:224
IndexScanDesc blbeginscan ( Relation  r,
int  nkeys,
int  norderbys 
)

Definition at line 29 of file blscan.c.

References IndexScanDescData::indexRelation, initBloomState(), NULL, 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:89
BloomState state
Definition: bloom.h:170
#define NULL
Definition: c.h:229
void * palloc(Size size)
Definition: mcxt.c:849
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:78
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, BloomBuildState::count, 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:165
MemoryContext tmpCtx
Definition: blinsert.c:36
#define RelationGetRelationName(relation)
Definition: rel.h:433
MemoryContext CurrentMemoryContext
Definition: mcxt.c:37
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
#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:2169
void * palloc(Size size)
Definition: mcxt.c:849
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
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
169  * would be sufficient to guarantee that the file exists on disk, but
170  * recovery itself might remove it while replaying, for example, an
171  * XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE record. Therefore, we
172  * need this even when wal_level=minimal.
173  */
176  (char *) metapage, true);
178  BLOOM_METAPAGE_BLKNO, metapage, false);
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:1199
void * palloc(Size size)
Definition: mcxt.c:849
XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, Page page, bool page_std)
Definition: xloginsert.c:973
void smgrimmedsync(SMgrRelation reln, ForkNumber forknum)
Definition: smgr.c:734
Pointer Page
Definition: bufpage.h:74
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_LOCK_EXCLUSIVE, callback(), FirstOffsetNumber, GenericXLogAbort(), GenericXLogFinish(), GenericXLogRegisterBuffer(), GenericXLogStart(), BloomTuple::heapPtr, IndexVacuumInfo::index, initBloomState(), LockBuffer(), MAIN_FORKNUM, memmove, BloomMetaPageData::nEnd, BloomMetaPageData::notFullPage, BloomMetaPageData::nStart, NULL, 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 pg_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 }
#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:90
char * Pointer
Definition: c.h:245
#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:1058
#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:878
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 NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
Definition: regguts.h:298
XLogRecPtr GenericXLogFinish(GenericXLogState *state)
Definition: generic_xlog.c:336
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:226
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60
void GenericXLogAbort(GenericXLogState *state)
Definition: generic_xlog.c:447
void vacuum_delay_point(void)
Definition: vacuum.c:1560
BlockNumber FreeBlockNumberArray[MAXALIGN_DOWN(BLCKSZ-SizeOfPageHeaderData-MAXALIGN(sizeof(BloomPageOpaqueData))-MAXALIGN(sizeof(uint16)*2+sizeof(uint32)+sizeof(BloomOptions)))/sizeof(BlockNumber)]
Definition: bloom.h:117
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
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:130
IndexOptInfo * indexinfo
Definition: relation.h:976
#define MemSet(start, val, len)
Definition: c.h:857
double tuples
Definition: relation.h:598
List * deconstruct_indexquals(IndexPath *path)
Definition: selfuncs.c:6063
Definition: type.h:90
Cost indexTotalCost
Definition: selfuncs.h:129
double indexCorrelation
Definition: selfuncs.h:131
double numIndexTuples
Definition: selfuncs.h:135
Cost indexStartupCost
Definition: selfuncs.h:128
Definition: pg_list.h:45
void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, List *qinfos, GenericCosts *costs)
Definition: selfuncs.c:6212
double numIndexPages
Definition: selfuncs.h:134
void blendscan ( IndexScanDesc  scan)

Definition at line 69 of file blscan.c.

References NULL, 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:950
#define NULL
Definition: c.h:229
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169
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_LOCK_SHARE, BufferGetPage, CHECK_FOR_INTERRUPTS, FreeAccessStrategy(), GetAccessStrategy(), BloomTuple::heapPtr, i, IndexScanDescData::indexRelation, IndexScanDescData::keyData, LockBuffer(), MAIN_FORKNUM, NULL, 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:525
#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:403
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
Snapshot xs_snapshot
Definition: relscan.h:90
uint32 BlockNumber
Definition: block.h:31
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:78
Relation indexRelation
Definition: relscan.h:89
uint16 OffsetNumber
Definition: off.h:24
uint16 BloomSignatureWord
Definition: bloom.h:83
void pfree(void *pointer)
Definition: mcxt.c:950
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:878
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:580
int sk_flags
Definition: skey.h:66
#define NULL
Definition: c.h:229
ScanKey keyData
Definition: relscan.h:93
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:226
#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:97
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
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_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:165
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:322
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define Assert(condition)
Definition: c.h:675
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
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:162
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2605
#define PageIsNew(page)
Definition: bufpage.h:226
#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
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:675
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:152
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:878
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:162
ItemPointerData heapPtr
Definition: bloom.h:160
int i
Size sizeOfBloomTuple
Definition: bloom.h:147
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:675
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
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
Buffer BloomNewBuffer ( Relation  index)

Definition at line 344 of file blutils.c.

References BloomPageIsDeleted, 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:520
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
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define InvalidBlockNumber
Definition: block.h:33
#define PageIsNew(page)
Definition: bufpage.h:226
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
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:245
#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:675
#define PageIsNew(page)
Definition: bufpage.h:226
Size sizeOfBloomTuple
Definition: bloom.h:147
bytea* bloptions ( Datum  reloptions,
bool  validate 
)

Definition at line 473 of file blutils.c.

References allocateReloptStruct(), bl_relopt_kind, BloomOptions::bloomLength, 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:562
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:1208
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:1232
int bloomLength
Definition: bloom.h:103
Definition: c.h:439
relopt_value * parseRelOptions(Datum options, bool validate, relopt_kind kind, int *numrelopts)
Definition: reloptions.c:1010
void blrescan ( IndexScanDesc  scan,
ScanKey  scankey,
int  nscankeys,
ScanKey  orderbys,
int  norderbys 
)

Definition at line 49 of file blscan.c.

References IndexScanDescData::keyData, memmove, NULL, 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:950
#define memmove(d, s, c)
Definition: c.h:1058
#define NULL
Definition: c.h:229
ScanKey keyData
Definition: relscan.h:93
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:173
BloomSignatureWord * sign
Definition: bloom.h:169
IndexBulkDeleteResult* blvacuumcleanup ( IndexVacuumInfo info,
IndexBulkDeleteResult stats 
)

Definition at line 169 of file blvacuum.c.

References IndexVacuumInfo::analyze_only, BLOOM_HEAD_BLKNO, BloomPageGetMaxOffset, BloomPageIsDeleted, BUFFER_LOCK_SHARE, BufferGetPage, IndexVacuumInfo::index, IndexFreeSpaceMapVacuum(), LockBuffer(), MAIN_FORKNUM, NULL, 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:90
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:878
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3546
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
#define NULL
Definition: c.h:229
void IndexFreeSpaceMapVacuum(Relation rel)
Definition: indexfsm.c:71
#define PageIsNew(page)
Definition: bufpage.h:226
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:60
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
void vacuum_delay_point(void)
Definition: vacuum.c:1560
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
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, NULL, 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:154
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#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:904
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:149
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:1665
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:155
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:194
#define ereport(elevel, rest)
Definition: elog.h:122
#define BLOOM_NSTRATEGIES
Definition: bloom.h:29
FormData_pg_opfamily * Form_pg_opfamily
Definition: pg_opfamily.h:44
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1081
char * format_procedure(Oid procedure_oid)
Definition: regproc.c:367
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#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:499
HeapTupleData tuple
Definition: catcache.h:116
#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
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_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:73
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:583
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:114
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:707
MemoryContext rd_indexcxt
Definition: rel.h:175
int i
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define elog
Definition: elog.h:219
void * rd_amcache
Definition: rel.h:188
#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
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
static struct @76 value
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
char sign
Definition: informix.c:693
unsigned int uint32
Definition: c.h:268
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:594