📄 buf_table.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 appropriate BufMappingLock, as specified * in the comments. We can't do the locking inside these functions because * in most cases the caller needs to adjust the buffer header contents * before the lock is released (see notes in README). * * * Portions Copyright (c) 1996-2008, 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.49 2008/01/01 19:45:51 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "storage/bufmgr.h"#include "storage/buf_internals.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) */SizeBufTableShmemSize(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) */voidInitBufTable(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; info.num_partitions = NUM_BUFFER_PARTITIONS; SharedBufHash = ShmemInitHash("Shared Buffer Lookup Table", size, size, &info, HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); if (!SharedBufHash) elog(FATAL, "could not initialize shared buffer hash table");}/* * BufTableHashCode * Compute the hash code associated with a BufferTag * * This must be passed to the lookup/insert/delete routines along with the * tag. We do it like this because the callers need to know the hash code * in order to determine which buffer partition to lock, and we don't want * to do the hash computation twice (hash_any is a bit slow). */uint32BufTableHashCode(BufferTag *tagPtr){ return get_hash_value(SharedBufHash, (void *) tagPtr);}/* * BufTableLookup * Lookup the given BufferTag; return buffer ID, or -1 if not found * * Caller must hold at least share lock on BufMappingLock for tag's partition */intBufTableLookup(BufferTag *tagPtr, uint32 hashcode){ BufferLookupEnt *result; result = (BufferLookupEnt *) hash_search_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, 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 exclusive lock on BufMappingLock for tag's partition */intBufTableInsert(BufferTag *tagPtr, uint32 hashcode, 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_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, 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 exclusive lock on BufMappingLock for tag's partition */voidBufTableDelete(BufferTag *tagPtr, uint32 hashcode){ BufferLookupEnt *result; result = (BufferLookupEnt *) hash_search_with_hash_value(SharedBufHash, (void *) tagPtr, hashcode, HASH_REMOVE, NULL); if (!result) /* shouldn't happen */ elog(ERROR, "shared buffer hash table corrupted");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -