PostgreSQL Source Code git master
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-2025, 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
26/* entry for buffer lookup hashtable */
27typedef struct
28{
29 BufferTag key; /* Tag of a disk page */
30 int id; /* Associated buffer ID */
32
34
35
36/*
37 * Estimate space needed for mapping hashtable
38 * size is the desired hash table size (possibly more than NBuffers)
39 */
40Size
42{
43 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 */
50void
51InitBufTable(int size)
52{
53 HASHCTL info;
54
55 /* assume no locking is needed yet */
56
57 /* BufferTag maps to Buffer */
58 info.keysize = sizeof(BufferTag);
59 info.entrysize = sizeof(BufferLookupEnt);
61
62 SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
63 size, size,
64 &info,
66}
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 */
79{
80 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 */
89int
91{
92 BufferLookupEnt *result;
93
94 result = (BufferLookupEnt *)
96 tagPtr,
97 hashcode,
99 NULL);
100
101 if (!result)
102 return -1;
103
104 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 */
117int
118BufTableInsert(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 *)
128 tagPtr,
129 hashcode,
131 &found);
132
133 if (found) /* found something already in the table */
134 return result->id;
135
136 result->id = buf_id;
137
138 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 */
147void
149{
150 BufferLookupEnt *result;
151
152 result = (BufferLookupEnt *)
154 tagPtr,
155 hashcode,
157 NULL);
158
159 if (!result) /* shouldn't happen */
160 elog(ERROR, "shared buffer hash table corrupted");
161}
struct buftag BufferTag
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
Definition: buf_table.c:148
static HTAB * SharedBufHash
Definition: buf_table.c:33
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition: buf_table.c:90
void InitBufTable(int size)
Definition: buf_table.c:51
Size BufTableShmemSize(int size)
Definition: buf_table.c:41
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition: buf_table.c:78
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
Definition: buf_table.c:118
#define P_NEW
Definition: bufmgr.h:185
uint32_t uint32
Definition: c.h:502
size_t Size
Definition: c.h:576
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:968
Size hash_estimate_size(long num_entries, Size entrysize)
Definition: dynahash.c:783
uint32 get_hash_value(HTAB *hashp, const void *keyPtr)
Definition: dynahash.c:911
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
Assert(PointerIsAligned(start, uint64))
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_REMOVE
Definition: hsearch.h:115
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
#define HASH_PARTITION
Definition: hsearch.h:92
#define NUM_BUFFER_PARTITIONS
Definition: lwlock.h:93
HTAB * ShmemInitHash(const char *name, long init_size, long max_size, HASHCTL *infoP, int hash_flags)
Definition: shmem.c:327
BufferTag key
Definition: buf_table.c:29
Size keysize
Definition: hsearch.h:75
Size entrysize
Definition: hsearch.h:76
long num_partitions
Definition: hsearch.h:68
Definition: dynahash.c:220
BlockNumber blockNum