1 /*-------------------------------------------------------------------------
4 * Bloom index scan functions.
6 * Copyright (c) 2016, PostgreSQL Global Development Group
9 * contrib/bloom/blscan.c
11 *-------------------------------------------------------------------------
15 #include "access/relscan.h"
17 #include "miscadmin.h"
18 #include "storage/bufmgr.h"
19 #include "storage/lmgr.h"
20 #include "utils/memutils.h"
21 #include "utils/rel.h"
26 * Begin scan of bloom index.
29 blbeginscan(Relation r, int nkeys, int norderbys)
34 scan = RelationGetIndexScan(r, nkeys, norderbys);
36 so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
37 initBloomState(&so->state, scan->indexRelation);
46 * Rescan a bloom index.
49 blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
50 ScanKey orderbys, int norderbys)
52 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
58 if (scankey && scan->numberOfKeys > 0)
60 memmove(scan->keyData, scankey,
61 scan->numberOfKeys * sizeof(ScanKeyData));
66 * End scan of bloom index.
69 blendscan(IndexScanDesc scan)
71 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
79 * Insert all matching tuples into to a bitmap.
82 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
85 BlockNumber blkno = BLOOM_HEAD_BLKNO,
88 BufferAccessStrategy bas;
89 BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
93 /* New search: have to calculate search signature */
94 ScanKey skey = scan->keyData;
96 so->sign = palloc0(sizeof(SignType) * so->state.opts.bloomLength);
98 for (i = 0; i < scan->numberOfKeys; i++)
101 * Assume bloom-indexable operators to be strict, so nothing could
102 * be found for NULL key.
104 if (skey->sk_flags & SK_ISNULL)
111 /* Add next value to the signature */
112 signValue(&so->state, so->sign, skey->sk_argument,
120 * We're going to read the whole index. This is why we use appropriate
121 * buffer access strategy.
123 bas = GetAccessStrategy(BAS_BULKREAD);
124 npages = RelationGetNumberOfBlocks(scan->indexRelation);
126 for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
131 buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM,
132 blkno, RBM_NORMAL, bas);
134 LockBuffer(buffer, BUFFER_LOCK_SHARE);
135 page = BufferGetPage(buffer);
136 TestForOldSnapshot(scan->xs_snapshot, scan->indexRelation, page);
138 if (!BloomPageIsDeleted(page))
141 maxOffset = BloomPageGetMaxOffset(page);
143 for (offset = 1; offset <= maxOffset; offset++)
145 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
148 /* Check index signature with scan signature */
149 for (i = 0; i < so->state.opts.bloomLength; i++)
151 if ((itup->sign[i] & so->sign[i]) != so->sign[i])
158 /* Add matching tuples to bitmap */
161 tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
167 UnlockReleaseBuffer(buffer);
168 CHECK_FOR_INTERRUPTS();
170 FreeAccessStrategy(bas);