12
12
* Portions Copyright (c) 1994, Regents of the University of California
13
13
*
14
14
* IDENTIFICATION
15
- * $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.2 2010/01/06 22:27:09 tgl Exp $
15
+ * $PostgreSQL: pgsql/src/backend/utils/cache/spccache.c,v 1.3 2010/01/06 23:00:02 tgl Exp $
16
16
*
17
17
*-------------------------------------------------------------------------
18
18
*/
19
-
20
19
#include "postgres.h"
20
+
21
21
#include "access/reloptions.h"
22
22
#include "catalog/pg_tablespace.h"
23
23
#include "commands/tablespace.h"
29
29
#include "utils/spccache.h"
30
30
#include "utils/syscache.h"
31
31
32
+
33
+ /* Hash table for information about each tablespace */
32
34
static HTAB * TableSpaceCacheHash = NULL ;
33
35
34
- typedef struct {
35
- Oid oid ;
36
- TableSpaceOpts * opts ;
37
- } TableSpace ;
36
+ typedef struct
37
+ {
38
+ Oid oid ; /* lookup key - must be first */
39
+ TableSpaceOpts * opts ; /* options, or NULL if none */
40
+ } TableSpaceCacheEntry ;
41
+
38
42
39
43
/*
40
44
* InvalidateTableSpaceCacheCallback
@@ -49,10 +53,10 @@ static void
49
53
InvalidateTableSpaceCacheCallback (Datum arg , int cacheid , ItemPointer tuplePtr )
50
54
{
51
55
HASH_SEQ_STATUS status ;
52
- TableSpace * spc ;
56
+ TableSpaceCacheEntry * spc ;
53
57
54
58
hash_seq_init (& status , TableSpaceCacheHash );
55
- while ((spc = (TableSpace * ) hash_seq_search (& status )) != NULL )
59
+ while ((spc = (TableSpaceCacheEntry * ) hash_seq_search (& status )) != NULL )
56
60
{
57
61
if (spc -> opts )
58
62
pfree (spc -> opts );
@@ -66,7 +70,7 @@ InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, ItemPointer tuplePtr)
66
70
67
71
/*
68
72
* InitializeTableSpaceCache
69
- * Initiate the tablespace cache.
73
+ * Initialize the tablespace cache.
70
74
*/
71
75
static void
72
76
InitializeTableSpaceCache (void )
@@ -76,8 +80,8 @@ InitializeTableSpaceCache(void)
76
80
/* Initialize the hash table. */
77
81
MemSet (& ctl , 0 , sizeof (ctl ));
78
82
ctl .keysize = sizeof (Oid );
79
- ctl .entrysize = sizeof (TableSpace );
80
- ctl .hash = tag_hash ;
83
+ ctl .entrysize = sizeof (TableSpaceCacheEntry );
84
+ ctl .hash = oid_hash ;
81
85
TableSpaceCacheHash =
82
86
hash_create ("TableSpace cache" , 16 , & ctl ,
83
87
HASH_ELEM | HASH_FUNCTION );
@@ -94,17 +98,17 @@ InitializeTableSpaceCache(void)
94
98
95
99
/*
96
100
* get_tablespace
97
- * Fetch TableSpace structure for a specified table OID.
101
+ * Fetch TableSpaceCacheEntry structure for a specified table OID.
98
102
*
99
103
* Pointers returned by this function should not be stored, since a cache
100
104
* flush will invalidate them.
101
105
*/
102
- static TableSpace *
106
+ static TableSpaceCacheEntry *
103
107
get_tablespace (Oid spcid )
104
108
{
109
+ TableSpaceCacheEntry * spc ;
105
110
HeapTuple tp ;
106
- TableSpace * spc ;
107
- bool found ;
111
+ TableSpaceOpts * opts ;
108
112
109
113
/*
110
114
* Since spcid is always from a pg_class tuple, InvalidOid implies the
@@ -113,12 +117,14 @@ get_tablespace(Oid spcid)
113
117
if (spcid == InvalidOid )
114
118
spcid = MyDatabaseTableSpace ;
115
119
116
- /* Find existing cache entry, or create a new one . */
120
+ /* Find existing cache entry, if any . */
117
121
if (!TableSpaceCacheHash )
118
122
InitializeTableSpaceCache ();
119
- spc = (TableSpace * ) hash_search (TableSpaceCacheHash , (void * ) & spcid ,
120
- HASH_ENTER , & found );
121
- if (found )
123
+ spc = (TableSpaceCacheEntry * ) hash_search (TableSpaceCacheHash ,
124
+ (void * ) & spcid ,
125
+ HASH_FIND ,
126
+ NULL );
127
+ if (spc )
122
128
return spc ;
123
129
124
130
/*
@@ -127,9 +133,11 @@ get_tablespace(Oid spcid)
127
133
* details for a non-existent tablespace. We'll just treat that case as if
128
134
* no options were specified.
129
135
*/
130
- tp = SearchSysCache (TABLESPACEOID , ObjectIdGetDatum (spcid ), 0 , 0 , 0 );
136
+ tp = SearchSysCache (TABLESPACEOID ,
137
+ ObjectIdGetDatum (spcid ),
138
+ 0 , 0 , 0 );
131
139
if (!HeapTupleIsValid (tp ))
132
- spc -> opts = NULL ;
140
+ opts = NULL ;
133
141
else
134
142
{
135
143
Datum datum ;
@@ -141,29 +149,40 @@ get_tablespace(Oid spcid)
141
149
Anum_pg_tablespace_spcoptions ,
142
150
& isNull );
143
151
if (isNull )
144
- spc -> opts = NULL ;
152
+ opts = NULL ;
145
153
else
146
154
{
155
+ /* XXX should NOT do the parsing work in CacheMemoryContext */
147
156
octx = MemoryContextSwitchTo (CacheMemoryContext );
148
- spc -> opts = (TableSpaceOpts * ) tablespace_reloptions (datum , false);
157
+ opts = (TableSpaceOpts * ) tablespace_reloptions (datum , false);
149
158
MemoryContextSwitchTo (octx );
150
159
}
151
160
ReleaseSysCache (tp );
152
161
}
153
162
154
- /* Update new TableSpace cache entry with results of option parsing. */
163
+ /*
164
+ * Now create the cache entry. It's important to do this only after
165
+ * reading the pg_tablespace entry, since doing so could cause a cache
166
+ * flush.
167
+ */
168
+ spc = (TableSpaceCacheEntry * ) hash_search (TableSpaceCacheHash ,
169
+ (void * ) & spcid ,
170
+ HASH_ENTER ,
171
+ NULL );
172
+ spc -> opts = opts ;
155
173
return spc ;
156
174
}
157
175
158
176
/*
159
177
* get_tablespace_page_costs
160
- * Return random and sequential page costs for a given tablespace.
178
+ * Return random and/or sequential page costs for a given tablespace.
161
179
*/
162
180
void
163
- get_tablespace_page_costs (Oid spcid , double * spc_random_page_cost ,
164
- double * spc_seq_page_cost )
181
+ get_tablespace_page_costs (Oid spcid ,
182
+ double * spc_random_page_cost ,
183
+ double * spc_seq_page_cost )
165
184
{
166
- TableSpace * spc = get_tablespace (spcid );
185
+ TableSpaceCacheEntry * spc = get_tablespace (spcid );
167
186
168
187
Assert (spc != NULL );
169
188
0 commit comments