44 * routines for mapping BufferTags to buffer indexes.
55 *
66 * 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
8- * comments.
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).
911 *
1012 *
1113 * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
1214 * Portions Copyright (c) 1994, Regents of the University of California
1315 *
1416 *
1517 * IDENTIFICATION
16- * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.46 2006/07/14 16:59:19 tgl Exp $
18+ * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_table.c,v 1.47 2006/07/23 03:07:58 tgl Exp $
1719 *
1820 *-------------------------------------------------------------------------
1921 */
@@ -58,29 +60,49 @@ InitBufTable(int size)
5860info .keysize = sizeof (BufferTag );
5961info .entrysize = sizeof (BufferLookupEnt );
6062info .hash = tag_hash ;
63+ info .num_partitions = NUM_BUFFER_PARTITIONS ;
6164
6265SharedBufHash = ShmemInitHash ("Shared Buffer Lookup Table" ,
6366size ,size ,
6467& info ,
65- HASH_ELEM |HASH_FUNCTION );
68+ HASH_ELEM |HASH_FUNCTION | HASH_PARTITION );
6669
6770if (!SharedBufHash )
6871elog (FATAL ,"could not initialize shared buffer hash table" );
6972}
7073
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+ */
83+ uint32
84+ BufTableHashCode (BufferTag * tagPtr )
85+ {
86+ return get_hash_value (SharedBufHash , (void * )tagPtr );
87+ }
88+
7189/*
7290 * BufTableLookup
7391 *Lookup the given BufferTag; return buffer ID, or -1 if not found
7492 *
75- * Caller must hold at least share lock on BufMappingLock
93+ * Caller must hold at least share lock on BufMappingLock for tag's partition
7694 */
7795int
78- BufTableLookup (BufferTag * tagPtr )
96+ BufTableLookup (BufferTag * tagPtr , uint32 hashcode )
7997{
8098BufferLookupEnt * result ;
8199
82100result = (BufferLookupEnt * )
83- hash_search (SharedBufHash , (void * )tagPtr ,HASH_FIND ,NULL );
101+ hash_search_with_hash_value (SharedBufHash ,
102+ (void * )tagPtr ,
103+ hashcode ,
104+ HASH_FIND ,
105+ NULL );
84106
85107if (!result )
86108return -1 ;
@@ -96,10 +118,10 @@ BufTableLookup(BufferTag *tagPtr)
96118 * Returns -1 on successful insertion.If a conflicting entry exists
97119 * already, returns the buffer ID in that entry.
98120 *
99- * Caller must holdwrite lock on BufMappingLock
121+ * Caller must holdexclusive lock on BufMappingLock for tag's partition
100122 */
101123int
102- BufTableInsert (BufferTag * tagPtr ,int buf_id )
124+ BufTableInsert (BufferTag * tagPtr ,uint32 hashcode , int buf_id )
103125{
104126BufferLookupEnt * result ;
105127bool found ;
@@ -108,7 +130,11 @@ BufTableInsert(BufferTag *tagPtr, int buf_id)
108130Assert (tagPtr -> blockNum != P_NEW );/* invalid tag */
109131
110132result = (BufferLookupEnt * )
111- hash_search (SharedBufHash , (void * )tagPtr ,HASH_ENTER ,& found );
133+ hash_search_with_hash_value (SharedBufHash ,
134+ (void * )tagPtr ,
135+ hashcode ,
136+ HASH_ENTER ,
137+ & found );
112138
113139if (found )/* found something already in the table */
114140return result -> id ;
@@ -122,15 +148,19 @@ BufTableInsert(BufferTag *tagPtr, int buf_id)
122148 * BufTableDelete
123149 *Delete the hashtable entry for given tag (which must exist)
124150 *
125- * Caller must holdwrite lock on BufMappingLock
151+ * Caller must holdexclusive lock on BufMappingLock for tag's partition
126152 */
127153void
128- BufTableDelete (BufferTag * tagPtr )
154+ BufTableDelete (BufferTag * tagPtr , uint32 hashcode )
129155{
130156BufferLookupEnt * result ;
131157
132158result = (BufferLookupEnt * )
133- hash_search (SharedBufHash , (void * )tagPtr ,HASH_REMOVE ,NULL );
159+ hash_search_with_hash_value (SharedBufHash ,
160+ (void * )tagPtr ,
161+ hashcode ,
162+ HASH_REMOVE ,
163+ NULL );
134164
135165if (!result )/* shouldn't happen */
136166elog (ERROR ,"shared buffer hash table corrupted" );