PostgreSQL Source Code git master
blscan.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * blscan.c
4 * Bloom index scan functions.
5 *
6 * Copyright (c) 2016-2025, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * contrib/bloom/blscan.c
10 *
11 *-------------------------------------------------------------------------
12 */
13#include "postgres.h"
14
15#include "access/relscan.h"
16#include "bloom.h"
17#include "miscadmin.h"
18#include "pgstat.h"
19#include "storage/bufmgr.h"
20
21/*
22 * Begin scan of bloom index.
23 */
25blbeginscan(Relation r, int nkeys, int norderbys)
26{
27 IndexScanDesc scan;
29
30 scan = RelationGetIndexScan(r, nkeys, norderbys);
31
34 so->sign = NULL;
35
36 scan->opaque = so;
37
38 return scan;
39}
40
41/*
42 * Rescan a bloom index.
43 */
44void
45blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
46 ScanKey orderbys, int norderbys)
47{
49
50 if (so->sign)
51 pfree(so->sign);
52 so->sign = NULL;
53
54 if (scankey && scan->numberOfKeys > 0)
55 memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
56}
57
58/*
59 * End scan of bloom index.
60 */
61void
63{
65
66 if (so->sign)
67 pfree(so->sign);
68 so->sign = NULL;
69}
70
71/*
72 * Insert all matching tuples into a bitmap.
73 */
76{
77 int64 ntids = 0;
79 npages;
80 int i;
83
84 if (so->sign == NULL)
85 {
86 /* New search: have to calculate search signature */
87 ScanKey skey = scan->keyData;
88
90
91 for (i = 0; i < scan->numberOfKeys; i++)
92 {
93 /*
94 * Assume bloom-indexable operators to be strict, so nothing could
95 * be found for NULL key.
96 */
97 if (skey->sk_flags & SK_ISNULL)
98 {
99 pfree(so->sign);
100 so->sign = NULL;
101 return 0;
102 }
103
104 /* Add next value to the signature */
105 signValue(&so->state, so->sign, skey->sk_argument,
106 skey->sk_attno - 1);
107
108 skey++;
109 }
110 }
111
112 /*
113 * We're going to read the whole index. This is why we use appropriate
114 * buffer access strategy.
115 */
119
120 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
121 {
122 Buffer buffer;
123 Page page;
124
126 blkno, RBM_NORMAL, bas);
127
129 page = BufferGetPage(buffer);
130
131 if (!PageIsNew(page) && !BloomPageIsDeleted(page))
132 {
133 OffsetNumber offset,
134 maxOffset = BloomPageGetMaxOffset(page);
135
136 for (offset = 1; offset <= maxOffset; offset++)
137 {
138 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
139 bool res = true;
140
141 /* Check index signature with scan signature */
142 for (i = 0; i < so->state.opts.bloomLength; i++)
143 {
144 if ((itup->sign[i] & so->sign[i]) != so->sign[i])
145 {
146 res = false;
147 break;
148 }
149 }
150
151 /* Add matching tuples to bitmap */
152 if (res)
153 {
154 tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
155 ntids++;
156 }
157 }
158 }
159
160 UnlockReleaseBuffer(buffer);
162 }
164
165 return ntids;
166}
uint32 BlockNumber
Definition: block.h:31
#define BloomPageGetMaxOffset(page)
Definition: bloom.h:61
#define BloomPageGetTuple(state, page, offset)
Definition: bloom.h:71
uint16 BloomSignatureWord
Definition: bloom.h:84
void signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno)
Definition: blutils.c:262
#define BloomPageIsDeleted(page)
Definition: bloom.h:64
void initBloomState(BloomState *state, Relation index)
Definition: blutils.c:163
BloomScanOpaqueData * BloomScanOpaque
Definition: bloom.h:172
#define BLOOM_HEAD_BLKNO
Definition: bloom.h:79
int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
Definition: blscan.c:75
IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys)
Definition: blscan.c:25
void blendscan(IndexScanDesc scan)
Definition: blscan.c:62
void blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
Definition: blscan.c:45
int Buffer
Definition: buf.h:23
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4883
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5100
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:793
@ BAS_BULKREAD
Definition: bufmgr.h:36
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:190
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:273
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:396
@ RBM_NORMAL
Definition: bufmgr.h:45
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
PageData * Page
Definition: bufpage.h:82
int64_t int64
Definition: c.h:485
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:541
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition: freelist.c:681
IndexScanDesc RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys)
Definition: genam.c:80
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
void * palloc(Size size)
Definition: mcxt.c:1317
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
uint16 OffsetNumber
Definition: off.h:24
#define pgstat_count_index_scan(rel)
Definition: pgstat.h:691
@ MAIN_FORKNUM
Definition: relpath.h:58
#define SK_ISNULL
Definition: skey.h:115
int bloomLength
Definition: bloom.h:104
BloomSignatureWord * sign
Definition: bloom.h:168
BloomState state
Definition: bloom.h:169
BloomOptions opts
Definition: bloom.h:139
BloomSignatureWord sign[FLEXIBLE_ARRAY_MEMBER]
Definition: bloom.h:160
ItemPointerData heapPtr
Definition: bloom.h:159
struct ScanKeyData * keyData
Definition: relscan.h:139
Relation indexRelation
Definition: relscan.h:135
int sk_flags
Definition: skey.h:66
Datum sk_argument
Definition: skey.h:72
AttrNumber sk_attno
Definition: skey.h:67
void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids, bool recheck)
Definition: tidbitmap.c:377