1 /*-------------------------------------------------------------------------
4 * routines for mapping BufferTags to buffer indexes.
6 * Note: the routines in this file do no locking of their own. The caller
7 * must hold a suitable lock on the BufMappingLock, as specified in the
11 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
16 * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.46 2006/07/14 16:59:19 tgl Exp $
18 *-------------------------------------------------------------------------
22 #include "storage/bufmgr.h"
23 #include "storage/buf_internals.h"
26 /* entry for buffer lookup hashtable */
29 BufferTag key; /* Tag of a disk page */
30 int id; /* Associated buffer ID */
33 static HTAB *SharedBufHash;
37 * Estimate space needed for mapping hashtable
38 * size is the desired hash table size (possibly more than NBuffers)
41 BufTableShmemSize(int size)
43 return hash_estimate_size(size, sizeof(BufferLookupEnt));
47 * Initialize shmem hash table for mapping buffers
48 * size is the desired hash table size (possibly more than NBuffers)
51 InitBufTable(int size)
55 /* assume no locking is needed yet */
57 /* BufferTag maps to Buffer */
58 info.keysize = sizeof(BufferTag);
59 info.entrysize = sizeof(BufferLookupEnt);
62 SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
65 HASH_ELEM | HASH_FUNCTION);
68 elog(FATAL, "could not initialize shared buffer hash table");
73 * Lookup the given BufferTag; return buffer ID, or -1 if not found
75 * Caller must hold at least share lock on BufMappingLock
78 BufTableLookup(BufferTag *tagPtr)
80 BufferLookupEnt *result;
82 result = (BufferLookupEnt *)
83 hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, NULL);
93 * Insert a hashtable entry for given tag and buffer ID,
94 * unless an entry already exists for that tag
96 * Returns -1 on successful insertion. If a conflicting entry exists
97 * already, returns the buffer ID in that entry.
99 * Caller must hold write lock on BufMappingLock
102 BufTableInsert(BufferTag *tagPtr, int buf_id)
104 BufferLookupEnt *result;
107 Assert(buf_id >= 0); /* -1 is reserved for not-in-table */
108 Assert(tagPtr->blockNum != P_NEW); /* invalid tag */
110 result = (BufferLookupEnt *)
111 hash_search(SharedBufHash, (void *) tagPtr, HASH_ENTER, &found);
113 if (found) /* found something already in the table */
123 * Delete the hashtable entry for given tag (which must exist)
125 * Caller must hold write lock on BufMappingLock
128 BufTableDelete(BufferTag *tagPtr)
130 BufferLookupEnt *result;
132 result = (BufferLookupEnt *)
133 hash_search(SharedBufHash, (void *) tagPtr, HASH_REMOVE, NULL);
135 if (!result) /* shouldn't happen */
136 elog(ERROR, "shared buffer hash table corrupted");