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

Generated by: LCOV version 1.11