LCOV - code coverage report
Current view: top level - src/backend/storage/buffer - buf_table.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 96.2 % 26 25
Test Date: 2026-03-16 01:14:54 Functions: 100.0 % 6 6
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * buf_table.c
       4              :  *    routines for mapping BufferTags to buffer indexes.
       5              :  *
       6              :  * Note: the routines in this file do no locking of their own.  The caller
       7              :  * must hold a suitable lock on the appropriate BufMappingLock, as specified
       8              :  * in the comments.  We can't do the locking inside these functions because
       9              :  * in most cases the caller needs to adjust the buffer header contents
      10              :  * before the lock is released (see notes in README).
      11              :  *
      12              :  *
      13              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      14              :  * Portions Copyright (c) 1994, Regents of the University of California
      15              :  *
      16              :  *
      17              :  * IDENTIFICATION
      18              :  *    src/backend/storage/buffer/buf_table.c
      19              :  *
      20              :  *-------------------------------------------------------------------------
      21              :  */
      22              : #include "postgres.h"
      23              : 
      24              : #include "storage/buf_internals.h"
      25              : 
      26              : /* entry for buffer lookup hashtable */
      27              : typedef struct
      28              : {
      29              :     BufferTag   key;            /* Tag of a disk page */
      30              :     int         id;             /* Associated buffer ID */
      31              : } BufferLookupEnt;
      32              : 
      33              : static HTAB *SharedBufHash;
      34              : 
      35              : 
      36              : /*
      37              :  * Estimate space needed for mapping hashtable
      38              :  *      size is the desired hash table size (possibly more than NBuffers)
      39              :  */
      40              : Size
      41         2165 : BufTableShmemSize(int size)
      42              : {
      43         2165 :     return hash_estimate_size(size, sizeof(BufferLookupEnt));
      44              : }
      45              : 
      46              : /*
      47              :  * Initialize shmem hash table for mapping buffers
      48              :  *      size is the desired hash table size (possibly more than NBuffers)
      49              :  */
      50              : void
      51         1159 : InitBufTable(int size)
      52              : {
      53              :     HASHCTL     info;
      54              : 
      55              :     /* assume no locking is needed yet */
      56              : 
      57              :     /* BufferTag maps to Buffer */
      58         1159 :     info.keysize = sizeof(BufferTag);
      59         1159 :     info.entrysize = sizeof(BufferLookupEnt);
      60         1159 :     info.num_partitions = NUM_BUFFER_PARTITIONS;
      61              : 
      62         1159 :     SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
      63              :                                   size, size,
      64              :                                   &info,
      65              :                                   HASH_ELEM | HASH_BLOBS | HASH_PARTITION | HASH_FIXED_SIZE);
      66         1159 : }
      67              : 
      68              : /*
      69              :  * BufTableHashCode
      70              :  *      Compute the hash code associated with a BufferTag
      71              :  *
      72              :  * This must be passed to the lookup/insert/delete routines along with the
      73              :  * tag.  We do it like this because the callers need to know the hash code
      74              :  * in order to determine which buffer partition to lock, and we don't want
      75              :  * to do the hash computation twice (hash_any is a bit slow).
      76              :  */
      77              : uint32
      78     67976045 : BufTableHashCode(BufferTag *tagPtr)
      79              : {
      80     67976045 :     return get_hash_value(SharedBufHash, tagPtr);
      81              : }
      82              : 
      83              : /*
      84              :  * BufTableLookup
      85              :  *      Lookup the given BufferTag; return buffer ID, or -1 if not found
      86              :  *
      87              :  * Caller must hold at least share lock on BufMappingLock for tag's partition
      88              :  */
      89              : int
      90     66389972 : BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
      91              : {
      92              :     BufferLookupEnt *result;
      93              : 
      94              :     result = (BufferLookupEnt *)
      95     66389972 :         hash_search_with_hash_value(SharedBufHash,
      96              :                                     tagPtr,
      97              :                                     hashcode,
      98              :                                     HASH_FIND,
      99              :                                     NULL);
     100              : 
     101     66389972 :     if (!result)
     102      1787343 :         return -1;
     103              : 
     104     64602629 :     return result->id;
     105              : }
     106              : 
     107              : /*
     108              :  * BufTableInsert
     109              :  *      Insert a hashtable entry for given tag and buffer ID,
     110              :  *      unless an entry already exists for that tag
     111              :  *
     112              :  * Returns -1 on successful insertion.  If a conflicting entry exists
     113              :  * already, returns the buffer ID in that entry.
     114              :  *
     115              :  * Caller must hold exclusive lock on BufMappingLock for tag's partition
     116              :  */
     117              : int
     118      2007885 : BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
     119              : {
     120              :     BufferLookupEnt *result;
     121              :     bool        found;
     122              : 
     123              :     Assert(buf_id >= 0);     /* -1 is reserved for not-in-table */
     124              :     Assert(tagPtr->blockNum != P_NEW);   /* invalid tag */
     125              : 
     126              :     result = (BufferLookupEnt *)
     127      2007885 :         hash_search_with_hash_value(SharedBufHash,
     128              :                                     tagPtr,
     129              :                                     hashcode,
     130              :                                     HASH_ENTER,
     131              :                                     &found);
     132              : 
     133      2007885 :     if (found)                  /* found something already in the table */
     134          744 :         return result->id;
     135              : 
     136      2007141 :     result->id = buf_id;
     137              : 
     138      2007141 :     return -1;
     139              : }
     140              : 
     141              : /*
     142              :  * BufTableDelete
     143              :  *      Delete the hashtable entry for given tag (which must exist)
     144              :  *
     145              :  * Caller must hold exclusive lock on BufMappingLock for tag's partition
     146              :  */
     147              : void
     148      1355702 : BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
     149              : {
     150              :     BufferLookupEnt *result;
     151              : 
     152              :     result = (BufferLookupEnt *)
     153      1355702 :         hash_search_with_hash_value(SharedBufHash,
     154              :                                     tagPtr,
     155              :                                     hashcode,
     156              :                                     HASH_REMOVE,
     157              :                                     NULL);
     158              : 
     159      1355702 :     if (!result)                /* shouldn't happen */
     160            0 :         elog(ERROR, "shared buffer hash table corrupted");
     161      1355702 : }
        

Generated by: LCOV version 2.0-1