4
4
* routines for mapping BufferTags to buffer indexes.
5
5
*
6
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
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).
9
11
*
10
12
*
11
13
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
12
14
* Portions Copyright (c) 1994, Regents of the University of California
13
15
*
14
16
*
15
17
* 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 $
17
19
*
18
20
*-------------------------------------------------------------------------
19
21
*/
@@ -58,29 +60,49 @@ InitBufTable(int size)
58
60
info .keysize = sizeof (BufferTag );
59
61
info .entrysize = sizeof (BufferLookupEnt );
60
62
info .hash = tag_hash ;
63
+ info .num_partitions = NUM_BUFFER_PARTITIONS ;
61
64
62
65
SharedBufHash = ShmemInitHash ("Shared Buffer Lookup Table" ,
63
66
size , size ,
64
67
& info ,
65
- HASH_ELEM | HASH_FUNCTION );
68
+ HASH_ELEM | HASH_FUNCTION | HASH_PARTITION );
66
69
67
70
if (!SharedBufHash )
68
71
elog (FATAL , "could not initialize shared buffer hash table" );
69
72
}
70
73
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
+
71
89
/*
72
90
* BufTableLookup
73
91
* Lookup the given BufferTag; return buffer ID, or -1 if not found
74
92
*
75
- * Caller must hold at least share lock on BufMappingLock
93
+ * Caller must hold at least share lock on BufMappingLock for tag's partition
76
94
*/
77
95
int
78
- BufTableLookup (BufferTag * tagPtr )
96
+ BufTableLookup (BufferTag * tagPtr , uint32 hashcode )
79
97
{
80
98
BufferLookupEnt * result ;
81
99
82
100
result = (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 );
84
106
85
107
if (!result )
86
108
return -1 ;
@@ -96,10 +118,10 @@ BufTableLookup(BufferTag *tagPtr)
96
118
* Returns -1 on successful insertion. If a conflicting entry exists
97
119
* already, returns the buffer ID in that entry.
98
120
*
99
- * Caller must hold write lock on BufMappingLock
121
+ * Caller must hold exclusive lock on BufMappingLock for tag's partition
100
122
*/
101
123
int
102
- BufTableInsert (BufferTag * tagPtr , int buf_id )
124
+ BufTableInsert (BufferTag * tagPtr , uint32 hashcode , int buf_id )
103
125
{
104
126
BufferLookupEnt * result ;
105
127
bool found ;
@@ -108,7 +130,11 @@ BufTableInsert(BufferTag *tagPtr, int buf_id)
108
130
Assert (tagPtr -> blockNum != P_NEW ); /* invalid tag */
109
131
110
132
result = (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 );
112
138
113
139
if (found ) /* found something already in the table */
114
140
return result -> id ;
@@ -122,15 +148,19 @@ BufTableInsert(BufferTag *tagPtr, int buf_id)
122
148
* BufTableDelete
123
149
* Delete the hashtable entry for given tag (which must exist)
124
150
*
125
- * Caller must hold write lock on BufMappingLock
151
+ * Caller must hold exclusive lock on BufMappingLock for tag's partition
126
152
*/
127
153
void
128
- BufTableDelete (BufferTag * tagPtr )
154
+ BufTableDelete (BufferTag * tagPtr , uint32 hashcode )
129
155
{
130
156
BufferLookupEnt * result ;
131
157
132
158
result = (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 );
134
164
135
165
if (!result ) /* shouldn't happen */
136
166
elog (ERROR , "shared buffer hash table corrupted" );
0 commit comments