1 /*-------------------------------------------------------------------------
4 * Bloom index scan functions.
6 * Copyright (c) 2016-2024, 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
);
136 if (!PageIsNew(page
) && !BloomPageIsDeleted(page
))
139 maxOffset
= BloomPageGetMaxOffset(page
);
141 for (offset
= 1; offset
<= maxOffset
; offset
++)
143 BloomTuple
*itup
= BloomPageGetTuple(&so
->state
, page
, offset
);
146 /* Check index signature with scan signature */
147 for (i
= 0; i
< so
->state
.opts
.bloomLength
; i
++)
149 if ((itup
->sign
[i
] & so
->sign
[i
]) != so
->sign
[i
])
156 /* Add matching tuples to bitmap */
159 tbm_add_tuples(tbm
, &itup
->heapPtr
, 1, true);
165 UnlockReleaseBuffer(buffer
);
166 CHECK_FOR_INTERRUPTS();
168 FreeAccessStrategy(bas
);