LCOV - differential code coverage report
Current view: top level - src/backend/storage/buffer - buf_table.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 96.4 % 28 27 1 27
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 6 6 6
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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-2023, 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                 : #include "storage/bufmgr.h"
      26                 : 
      27                 : /* entry for buffer lookup hashtable */
      28                 : typedef struct
      29                 : {
      30                 :     BufferTag   key;            /* Tag of a disk page */
      31                 :     int         id;             /* Associated buffer ID */
      32                 : } BufferLookupEnt;
      33                 : 
      34                 : static HTAB *SharedBufHash;
      35                 : 
      36                 : 
      37                 : /*
      38                 :  * Estimate space needed for mapping hashtable
      39                 :  *      size is the desired hash table size (possibly more than NBuffers)
      40                 :  */
      41                 : Size
      42 CBC        2738 : BufTableShmemSize(int size)
      43                 : {
      44            2738 :     return hash_estimate_size(size, sizeof(BufferLookupEnt));
      45                 : }
      46                 : 
      47                 : /*
      48                 :  * Initialize shmem hash table for mapping buffers
      49                 :  *      size is the desired hash table size (possibly more than NBuffers)
      50                 :  */
      51                 : void
      52            1826 : InitBufTable(int size)
      53                 : {
      54                 :     HASHCTL     info;
      55                 : 
      56                 :     /* assume no locking is needed yet */
      57                 : 
      58                 :     /* BufferTag maps to Buffer */
      59            1826 :     info.keysize = sizeof(BufferTag);
      60            1826 :     info.entrysize = sizeof(BufferLookupEnt);
      61            1826 :     info.num_partitions = NUM_BUFFER_PARTITIONS;
      62                 : 
      63            1826 :     SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
      64                 :                                   size, size,
      65                 :                                   &info,
      66                 :                                   HASH_ELEM | HASH_BLOBS | HASH_PARTITION);
      67            1826 : }
      68                 : 
      69                 : /*
      70                 :  * BufTableHashCode
      71                 :  *      Compute the hash code associated with a BufferTag
      72                 :  *
      73                 :  * This must be passed to the lookup/insert/delete routines along with the
      74                 :  * tag.  We do it like this because the callers need to know the hash code
      75                 :  * in order to determine which buffer partition to lock, and we don't want
      76                 :  * to do the hash computation twice (hash_any is a bit slow).
      77                 :  */
      78                 : uint32
      79        71628090 : BufTableHashCode(BufferTag *tagPtr)
      80                 : {
      81        71628090 :     return get_hash_value(SharedBufHash, (void *) tagPtr);
      82                 : }
      83                 : 
      84                 : /*
      85                 :  * BufTableLookup
      86                 :  *      Lookup the given BufferTag; return buffer ID, or -1 if not found
      87                 :  *
      88                 :  * Caller must hold at least share lock on BufMappingLock for tag's partition
      89                 :  */
      90                 : int
      91        70122394 : BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
      92                 : {
      93                 :     BufferLookupEnt *result;
      94                 : 
      95                 :     result = (BufferLookupEnt *)
      96        70122394 :         hash_search_with_hash_value(SharedBufHash,
      97                 :                                     tagPtr,
      98                 :                                     hashcode,
      99                 :                                     HASH_FIND,
     100                 :                                     NULL);
     101                 : 
     102        70122394 :     if (!result)
     103         1712231 :         return -1;
     104                 : 
     105        68410163 :     return result->id;
     106                 : }
     107                 : 
     108                 : /*
     109                 :  * BufTableInsert
     110                 :  *      Insert a hashtable entry for given tag and buffer ID,
     111                 :  *      unless an entry already exists for that tag
     112                 :  *
     113                 :  * Returns -1 on successful insertion.  If a conflicting entry exists
     114                 :  * already, returns the buffer ID in that entry.
     115                 :  *
     116                 :  * Caller must hold exclusive lock on BufMappingLock for tag's partition
     117                 :  */
     118                 : int
     119         1869538 : BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
     120                 : {
     121                 :     BufferLookupEnt *result;
     122                 :     bool        found;
     123                 : 
     124         1869538 :     Assert(buf_id >= 0);     /* -1 is reserved for not-in-table */
     125         1869538 :     Assert(tagPtr->blockNum != P_NEW);   /* invalid tag */
     126                 : 
     127                 :     result = (BufferLookupEnt *)
     128         1869538 :         hash_search_with_hash_value(SharedBufHash,
     129                 :                                     tagPtr,
     130                 :                                     hashcode,
     131                 :                                     HASH_ENTER,
     132                 :                                     &found);
     133                 : 
     134         1869538 :     if (found)                  /* found something already in the table */
     135             809 :         return result->id;
     136                 : 
     137         1868729 :     result->id = buf_id;
     138                 : 
     139         1868729 :     return -1;
     140                 : }
     141                 : 
     142                 : /*
     143                 :  * BufTableDelete
     144                 :  *      Delete the hashtable entry for given tag (which must exist)
     145                 :  *
     146                 :  * Caller must hold exclusive lock on BufMappingLock for tag's partition
     147                 :  */
     148                 : void
     149         1135698 : BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
     150                 : {
     151                 :     BufferLookupEnt *result;
     152                 : 
     153                 :     result = (BufferLookupEnt *)
     154         1135698 :         hash_search_with_hash_value(SharedBufHash,
     155                 :                                     tagPtr,
     156                 :                                     hashcode,
     157                 :                                     HASH_REMOVE,
     158                 :                                     NULL);
     159                 : 
     160         1135698 :     if (!result)                /* shouldn't happen */
     161 UBC           0 :         elog(ERROR, "shared buffer hash table corrupted");
     162 CBC     1135698 : }
        

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