LCOV - code coverage report
Current view: top level - contrib/bloom - blscan.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 78 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 4 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * blscan.c
       4              :  *              Bloom index scan functions.
       5              :  *
       6              :  * Copyright (c) 2016-2026, 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 "executor/instrument_node.h"
      18              : #include "miscadmin.h"
      19              : #include "pgstat.h"
      20              : #include "storage/bufmgr.h"
      21              : 
      22              : /*
      23              :  * Begin scan of bloom index.
      24              :  */
      25              : IndexScanDesc
      26            0 : blbeginscan(Relation r, int nkeys, int norderbys)
      27              : {
      28            0 :         IndexScanDesc scan;
      29            0 :         BloomScanOpaque so;
      30              : 
      31            0 :         scan = RelationGetIndexScan(r, nkeys, norderbys);
      32              : 
      33            0 :         so = (BloomScanOpaque) palloc_object(BloomScanOpaqueData);
      34            0 :         initBloomState(&so->state, scan->indexRelation);
      35            0 :         so->sign = NULL;
      36              : 
      37            0 :         scan->opaque = so;
      38              : 
      39            0 :         return scan;
      40            0 : }
      41              : 
      42              : /*
      43              :  * Rescan a bloom index.
      44              :  */
      45              : void
      46            0 : blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
      47              :                  ScanKey orderbys, int norderbys)
      48              : {
      49            0 :         BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      50              : 
      51            0 :         if (so->sign)
      52            0 :                 pfree(so->sign);
      53            0 :         so->sign = NULL;
      54              : 
      55            0 :         if (scankey && scan->numberOfKeys > 0)
      56            0 :                 memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
      57            0 : }
      58              : 
      59              : /*
      60              :  * End scan of bloom index.
      61              :  */
      62              : void
      63            0 : blendscan(IndexScanDesc scan)
      64              : {
      65            0 :         BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      66              : 
      67            0 :         if (so->sign)
      68            0 :                 pfree(so->sign);
      69            0 :         so->sign = NULL;
      70            0 : }
      71              : 
      72              : /*
      73              :  * Insert all matching tuples into a bitmap.
      74              :  */
      75              : int64
      76            0 : blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
      77              : {
      78            0 :         int64           ntids = 0;
      79            0 :         BlockNumber blkno = BLOOM_HEAD_BLKNO,
      80              :                                 npages;
      81            0 :         int                     i;
      82            0 :         BufferAccessStrategy bas;
      83            0 :         BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      84              : 
      85            0 :         if (so->sign == NULL)
      86              :         {
      87              :                 /* New search: have to calculate search signature */
      88            0 :                 ScanKey         skey = scan->keyData;
      89              : 
      90            0 :                 so->sign = palloc0_array(BloomSignatureWord, so->state.opts.bloomLength);
      91              : 
      92            0 :                 for (i = 0; i < scan->numberOfKeys; i++)
      93              :                 {
      94              :                         /*
      95              :                          * Assume bloom-indexable operators to be strict, so nothing could
      96              :                          * be found for NULL key.
      97              :                          */
      98            0 :                         if (skey->sk_flags & SK_ISNULL)
      99              :                         {
     100            0 :                                 pfree(so->sign);
     101            0 :                                 so->sign = NULL;
     102            0 :                                 return 0;
     103              :                         }
     104              : 
     105              :                         /* Add next value to the signature */
     106            0 :                         signValue(&so->state, so->sign, skey->sk_argument,
     107            0 :                                           skey->sk_attno - 1);
     108              : 
     109            0 :                         skey++;
     110            0 :                 }
     111            0 :         }
     112              : 
     113              :         /*
     114              :          * We're going to read the whole index. This is why we use appropriate
     115              :          * buffer access strategy.
     116              :          */
     117            0 :         bas = GetAccessStrategy(BAS_BULKREAD);
     118            0 :         npages = RelationGetNumberOfBlocks(scan->indexRelation);
     119            0 :         pgstat_count_index_scan(scan->indexRelation);
     120            0 :         if (scan->instrument)
     121            0 :                 scan->instrument->nsearches++;
     122              : 
     123            0 :         for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
     124              :         {
     125            0 :                 Buffer          buffer;
     126            0 :                 Page            page;
     127              : 
     128            0 :                 buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM,
     129            0 :                                                                         blkno, RBM_NORMAL, bas);
     130              : 
     131            0 :                 LockBuffer(buffer, BUFFER_LOCK_SHARE);
     132            0 :                 page = BufferGetPage(buffer);
     133              : 
     134            0 :                 if (!PageIsNew(page) && !BloomPageIsDeleted(page))
     135              :                 {
     136            0 :                         OffsetNumber offset,
     137            0 :                                                 maxOffset = BloomPageGetMaxOffset(page);
     138              : 
     139            0 :                         for (offset = 1; offset <= maxOffset; offset++)
     140              :                         {
     141            0 :                                 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
     142            0 :                                 bool            res = true;
     143              : 
     144              :                                 /* Check index signature with scan signature */
     145            0 :                                 for (i = 0; i < so->state.opts.bloomLength; i++)
     146              :                                 {
     147            0 :                                         if ((itup->sign[i] & so->sign[i]) != so->sign[i])
     148              :                                         {
     149            0 :                                                 res = false;
     150            0 :                                                 break;
     151              :                                         }
     152            0 :                                 }
     153              : 
     154              :                                 /* Add matching tuples to bitmap */
     155            0 :                                 if (res)
     156              :                                 {
     157            0 :                                         tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
     158            0 :                                         ntids++;
     159            0 :                                 }
     160            0 :                         }
     161            0 :                 }
     162              : 
     163            0 :                 UnlockReleaseBuffer(buffer);
     164            0 :                 CHECK_FOR_INTERRUPTS();
     165            0 :         }
     166            0 :         FreeAccessStrategy(bas);
     167              : 
     168            0 :         return ntids;
     169            0 : }
        

Generated by: LCOV version 2.3.2-1