LCOV - code coverage report
Current view: top level - contrib/bloom - blscan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 55 59 93.2 %
Date: 2024-12-12 19:15:15 Functions: 4 4 100.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-2024, 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             :  */
      24             : IndexScanDesc
      25         774 : blbeginscan(Relation r, int nkeys, int norderbys)
      26             : {
      27             :     IndexScanDesc scan;
      28             :     BloomScanOpaque so;
      29             : 
      30         774 :     scan = RelationGetIndexScan(r, nkeys, norderbys);
      31             : 
      32         774 :     so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
      33         774 :     initBloomState(&so->state, scan->indexRelation);
      34         774 :     so->sign = NULL;
      35             : 
      36         774 :     scan->opaque = so;
      37             : 
      38         774 :     return scan;
      39             : }
      40             : 
      41             : /*
      42             :  * Rescan a bloom index.
      43             :  */
      44             : void
      45         774 : blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
      46             :          ScanKey orderbys, int norderbys)
      47             : {
      48         774 :     BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      49             : 
      50         774 :     if (so->sign)
      51           0 :         pfree(so->sign);
      52         774 :     so->sign = NULL;
      53             : 
      54         774 :     if (scankey && scan->numberOfKeys > 0)
      55         774 :         memcpy(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData));
      56         774 : }
      57             : 
      58             : /*
      59             :  * End scan of bloom index.
      60             :  */
      61             : void
      62         774 : blendscan(IndexScanDesc scan)
      63             : {
      64         774 :     BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      65             : 
      66         774 :     if (so->sign)
      67         774 :         pfree(so->sign);
      68         774 :     so->sign = NULL;
      69         774 : }
      70             : 
      71             : /*
      72             :  * Insert all matching tuples into a bitmap.
      73             :  */
      74             : int64
      75         774 : blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
      76             : {
      77         774 :     int64       ntids = 0;
      78         774 :     BlockNumber blkno = BLOOM_HEAD_BLKNO,
      79             :                 npages;
      80             :     int         i;
      81             :     BufferAccessStrategy bas;
      82         774 :     BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
      83             : 
      84         774 :     if (so->sign == NULL)
      85             :     {
      86             :         /* New search: have to calculate search signature */
      87         774 :         ScanKey     skey = scan->keyData;
      88             : 
      89         774 :         so->sign = palloc0(sizeof(BloomSignatureWord) * so->state.opts.bloomLength);
      90             : 
      91        1806 :         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        1032 :             if (skey->sk_flags & SK_ISNULL)
      98             :             {
      99           0 :                 pfree(so->sign);
     100           0 :                 so->sign = NULL;
     101           0 :                 return 0;
     102             :             }
     103             : 
     104             :             /* Add next value to the signature */
     105        1032 :             signValue(&so->state, so->sign, skey->sk_argument,
     106        1032 :                       skey->sk_attno - 1);
     107             : 
     108        1032 :             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             :      */
     116         774 :     bas = GetAccessStrategy(BAS_BULKREAD);
     117         774 :     npages = RelationGetNumberOfBlocks(scan->indexRelation);
     118         774 :     pgstat_count_index_scan(scan->indexRelation);
     119             : 
     120       58668 :     for (blkno = BLOOM_HEAD_BLKNO; blkno < npages; blkno++)
     121             :     {
     122             :         Buffer      buffer;
     123             :         Page        page;
     124             : 
     125       57894 :         buffer = ReadBufferExtended(scan->indexRelation, MAIN_FORKNUM,
     126             :                                     blkno, RBM_NORMAL, bas);
     127             : 
     128       57894 :         LockBuffer(buffer, BUFFER_LOCK_SHARE);
     129       57894 :         page = BufferGetPage(buffer);
     130             : 
     131       57894 :         if (!PageIsNew(page) && !BloomPageIsDeleted(page))
     132             :         {
     133             :             OffsetNumber offset,
     134       57852 :                         maxOffset = BloomPageGetMaxOffset(page);
     135             : 
     136    28322352 :             for (offset = 1; offset <= maxOffset; offset++)
     137             :             {
     138    28264500 :                 BloomTuple *itup = BloomPageGetTuple(&so->state, page, offset);
     139    28264500 :                 bool        res = true;
     140             : 
     141             :                 /* Check index signature with scan signature */
     142    70743696 :                 for (i = 0; i < so->state.opts.bloomLength; i++)
     143             :                 {
     144    68972372 :                     if ((itup->sign[i] & so->sign[i]) != so->sign[i])
     145             :                     {
     146    26493176 :                         res = false;
     147    26493176 :                         break;
     148             :                     }
     149             :                 }
     150             : 
     151             :                 /* Add matching tuples to bitmap */
     152    28264500 :                 if (res)
     153             :                 {
     154     1771324 :                     tbm_add_tuples(tbm, &itup->heapPtr, 1, true);
     155     1771324 :                     ntids++;
     156             :                 }
     157             :             }
     158             :         }
     159             : 
     160       57894 :         UnlockReleaseBuffer(buffer);
     161       57894 :         CHECK_FOR_INTERRUPTS();
     162             :     }
     163         774 :     FreeAccessStrategy(bas);
     164             : 
     165         774 :     return ntids;
     166             : }

Generated by: LCOV version 1.14