PostgreSQL Source Code git master
Loading...
Searching...
No Matches
buf_table.c
Go to the documentation of this file.
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
25#include "storage/subsystems.h"
26
27/* entry for buffer lookup hashtable */
28typedef struct
29{
30 BufferTag key; /* Tag of a disk page */
31 int id; /* Associated buffer ID */
33
35
36static void BufTableShmemRequest(void *arg);
37
40 /* no special initialization needed, the hash table will start empty */
41};
42
43/*
44 * Register shmem hash table for mapping buffers.
45 * size is the desired hash table size (possibly more than NBuffers)
46 */
47void
49{
50 int size;
51
52 /*
53 * Request the shared buffer lookup hashtable.
54 *
55 * Since we can't tolerate running out of lookup table entries, we must be
56 * sure to specify an adequate table size here. The maximum steady-state
57 * usage is of course NBuffers entries, but BufferAlloc() tries to insert
58 * a new entry before deleting the old. In principle this could be
59 * happening in each partition concurrently, so we could need as many as
60 * NBuffers + NUM_BUFFER_PARTITIONS entries.
61 */
63
64 ShmemRequestHash(.name = "Shared Buffer Lookup Table",
65 .nelems = size,
66 .ptr = &SharedBufHash,
67 .hash_info.keysize = sizeof(BufferTag),
68 .hash_info.entrysize = sizeof(BufferLookupEnt),
69 .hash_info.num_partitions = NUM_BUFFER_PARTITIONS,
71 );
72}
73
74/*
75 * BufTableHashCode
76 * Compute the hash code associated with a BufferTag
77 *
78 * This must be passed to the lookup/insert/delete routines along with the
79 * tag. We do it like this because the callers need to know the hash code
80 * in order to determine which buffer partition to lock, and we don't want
81 * to do the hash computation twice (hash_any is a bit slow).
82 */
88
89/*
90 * BufTableLookup
91 * Lookup the given BufferTag; return buffer ID, or -1 if not found
92 *
93 * Caller must hold at least share lock on BufMappingLock for tag's partition
94 */
95int
97{
99
102 tagPtr,
103 hashcode,
104 HASH_FIND,
105 NULL);
106
107 if (!result)
108 return -1;
109
110 return result->id;
111}
112
113/*
114 * BufTableInsert
115 * Insert a hashtable entry for given tag and buffer ID,
116 * unless an entry already exists for that tag
117 *
118 * Returns -1 on successful insertion. If a conflicting entry exists
119 * already, returns the buffer ID in that entry.
120 *
121 * Caller must hold exclusive lock on BufMappingLock for tag's partition
122 */
123int
124BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
125{
127 bool found;
128
129 Assert(buf_id >= 0); /* -1 is reserved for not-in-table */
130 Assert(tagPtr->blockNum != P_NEW); /* invalid tag */
131
134 tagPtr,
135 hashcode,
137 &found);
138
139 if (found) /* found something already in the table */
140 return result->id;
141
142 result->id = buf_id;
143
144 return -1;
145}
146
147/*
148 * BufTableDelete
149 * Delete the hashtable entry for given tag (which must exist)
150 *
151 * Caller must hold exclusive lock on BufMappingLock for tag's partition
152 */
153void
155{
157
160 tagPtr,
161 hashcode,
163 NULL);
164
165 if (!result) /* shouldn't happen */
166 elog(ERROR, "shared buffer hash table corrupted");
167}
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:154
static HTAB * SharedBufHash
Definition buf_table.c:34
static void BufTableShmemRequest(void *arg)
Definition buf_table.c:48
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:96
const ShmemCallbacks BufTableShmemCallbacks
Definition buf_table.c:38
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition buf_table.c:84
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
Definition buf_table.c:124
#define P_NEW
Definition bufmgr.h:200
#define Assert(condition)
Definition c.h:943
uint32_t uint32
Definition c.h:624
uint32 result
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
Definition dynahash.c:902
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
Definition dynahash.c:845
Datum arg
Definition elog.c:1322
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
int NBuffers
Definition globals.c:144
@ HASH_FIND
Definition hsearch.h:108
@ HASH_REMOVE
Definition hsearch.h:110
@ HASH_ENTER
Definition hsearch.h:109
#define HASH_ELEM
Definition hsearch.h:90
#define HASH_BLOBS
Definition hsearch.h:92
#define HASH_FIXED_SIZE
Definition hsearch.h:100
#define HASH_PARTITION
Definition hsearch.h:87
#define NUM_BUFFER_PARTITIONS
Definition lwlock.h:83
static int fb(int x)
#define ShmemRequestHash(...)
Definition shmem.h:179
BufferTag key
Definition buf_table.c:30
Size keysize
Definition dynahash.c:241
ShmemRequestCallback request_fn
Definition shmem.h:133
const char * name