1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-13 16:22:44 +03:00
Files
postgres/src/backend/storage/buffer/buf_table.c
2006-03-05 15:59:11 +00:00

138 lines
3.2 KiB
C

/*-------------------------------------------------------------------------
*
* buf_table.c
* routines for mapping BufferTags to buffer indexes.
*
* Note: the routines in this file do no locking of their own. The caller
* must hold a suitable lock on the BufMappingLock, as specified in the
* comments.
*
*
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.44 2006/03/05 15:58:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "storage/buf_internals.h"
#include "storage/bufmgr.h"
/* entry for buffer lookup hashtable */
typedef struct
{
BufferTag key; /* Tag of a disk page */
int id; /* Associated buffer ID */
} BufferLookupEnt;
static HTAB *SharedBufHash;
/*
* Estimate space needed for mapping hashtable
* size is the desired hash table size (possibly more than NBuffers)
*/
Size
BufTableShmemSize(int size)
{
return hash_estimate_size(size, sizeof(BufferLookupEnt));
}
/*
* Initialize shmem hash table for mapping buffers
* size is the desired hash table size (possibly more than NBuffers)
*/
void
InitBufTable(int size)
{
HASHCTL info;
/* assume no locking is needed yet */
/* BufferTag maps to Buffer */
info.keysize = sizeof(BufferTag);
info.entrysize = sizeof(BufferLookupEnt);
info.hash = tag_hash;
SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table",
size, size,
&info,
HASH_ELEM | HASH_FUNCTION);
if (!SharedBufHash)
elog(FATAL, "could not initialize shared buffer hash table");
}
/*
* BufTableLookup
* Lookup the given BufferTag; return buffer ID, or -1 if not found
*
* Caller must hold at least share lock on BufMappingLock
*/
int
BufTableLookup(BufferTag *tagPtr)
{
BufferLookupEnt *result;
result = (BufferLookupEnt *)
hash_search(SharedBufHash, (void *) tagPtr, HASH_FIND, NULL);
if (!result)
return -1;
return result->id;
}
/*
* BufTableInsert
* Insert a hashtable entry for given tag and buffer ID,
* unless an entry already exists for that tag
*
* Returns -1 on successful insertion. If a conflicting entry exists
* already, returns the buffer ID in that entry.
*
* Caller must hold write lock on BufMappingLock
*/
int
BufTableInsert(BufferTag *tagPtr, int buf_id)
{
BufferLookupEnt *result;
bool found;
Assert(buf_id >= 0); /* -1 is reserved for not-in-table */
Assert(tagPtr->blockNum != P_NEW); /* invalid tag */
result = (BufferLookupEnt *)
hash_search(SharedBufHash, (void *) tagPtr, HASH_ENTER, &found);
if (found) /* found something already in the table */
return result->id;
result->id = buf_id;
return -1;
}
/*
* BufTableDelete
* Delete the hashtable entry for given tag (which must exist)
*
* Caller must hold write lock on BufMappingLock
*/
void
BufTableDelete(BufferTag *tagPtr)
{
BufferLookupEnt *result;
result = (BufferLookupEnt *)
hash_search(SharedBufHash, (void *) tagPtr, HASH_REMOVE, NULL);
if (!result) /* shouldn't happen */
elog(ERROR, "shared buffer hash table corrupted");
}