1 /*-------------------------------------------------------------------------
4 * Bloom index scan functions.
6 * Copyright (c) 2016-2019, PostgreSQL Global Development Group
9 * contrib/bloom/blscan.c
11 *-------------------------------------------------------------------------
15 #include "access/relscan.h"
17 #include "miscadmin.h"
19 #include "storage/bufmgr.h"
20 #include "storage/lmgr.h"
21 #include "utils/memutils.h"
22 #include "utils/rel.h"
25 * Begin scan of bloom index.
28 blbeginscan(Relation r, int nkeys, int norderbys)
33 scan = RelationGetIndexScan(r, nkeys, norderbys);
35 so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
36 initBloomState(&so->state, scan->indexRelation);
45 * Rescan a bloom index.
48 blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
49 ScanKey orderbys, int norderbys)
51 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
57 if (scankey && scan->numberOfKeys > 0)
59 memmove(scan->keyData, scankey,
60 scan->numberOfKeys * sizeof(ScanKeyData));
65 * End scan of bloom index.
68 blendscan(IndexScanDesc scan)
70 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
78 * Insert all matching tuples into a bitmap.
81 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
84 BlockNumber blkno = BLOOM_HEAD_BLKNO,
87 BufferAccessStrategy bas;
88 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
92 /* New search: have to calculate search signature */
93 ScanKey skey = scan->keyData;
95 so->sign = palloc0(sizeof(BloomSignatureWord) * so->state.opts.bloomLength);
97 for (i = 0; i < scan->numberOfKeys; i++)
100 * Assume bloom-indexable operators to be strict, so nothing could
101 * be found for NULL key.
103 if (skey->sk_flags & SK_ISNULL)
110 /* Add next value to the signature */
111 signValue(&so->state, so->sign, skey->sk_argument,
119 * We're going to read the whole index. This is why we use appropriate
120 * buffer access strategy.
122 bas = GetAccessStrategy(BAS_BULKREAD);
123 npages = RelationGetNumberOfBlocks(scan->indexRelation);
125 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
130 buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM,
131 blkno, RBM_NORMAL, bas);
133 LockBuffer(buffer, BUFFER_LOCK_SHARE);
134 page = BufferGetPage(buffer);
135 TestForOldSnapshot(scan->xs_snapshot, scan->indexRelation, page);
137 if (!PageIsNew(page) && !BloomPageIsDeleted(page))
140 maxOffset = BloomPageGetMaxOffset(page);
142 for (offset = 1; offset <= maxOffset; offset++)
144 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
147 /* Check index signature with scan signature */
148 for (i = 0; i < so->state.opts.bloomLength; i++)
150 if ((itup->sign[i] & so->sign[i]) != so->sign[i])
157 /* Add matching tuples to bitmap */
160 tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
166 UnlockReleaseBuffer(buffer);
167 CHECK_FOR_INTERRUPTS();
169 FreeAccessStrategy(bas);