LCOV - differential code coverage report
Current view: top level - contrib/bloom - blscan.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 93.3 % 60 56 4 56
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 4 4 4
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a