Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "postgres.h"
00020
00021 #include "access/reloptions.h"
00022 #include "catalog/pg_tablespace.h"
00023 #include "commands/tablespace.h"
00024 #include "miscadmin.h"
00025 #include "optimizer/cost.h"
00026 #include "utils/catcache.h"
00027 #include "utils/hsearch.h"
00028 #include "utils/inval.h"
00029 #include "utils/spccache.h"
00030 #include "utils/syscache.h"
00031
00032
00033
00034 static HTAB *TableSpaceCacheHash = NULL;
00035
00036 typedef struct
00037 {
00038 Oid oid;
00039 TableSpaceOpts *opts;
00040 } TableSpaceCacheEntry;
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 static void
00053 InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
00054 {
00055 HASH_SEQ_STATUS status;
00056 TableSpaceCacheEntry *spc;
00057
00058 hash_seq_init(&status, TableSpaceCacheHash);
00059 while ((spc = (TableSpaceCacheEntry *) hash_seq_search(&status)) != NULL)
00060 {
00061 if (spc->opts)
00062 pfree(spc->opts);
00063 if (hash_search(TableSpaceCacheHash,
00064 (void *) &spc->oid,
00065 HASH_REMOVE,
00066 NULL) == NULL)
00067 elog(ERROR, "hash table corrupted");
00068 }
00069 }
00070
00071
00072
00073
00074
00075 static void
00076 InitializeTableSpaceCache(void)
00077 {
00078 HASHCTL ctl;
00079
00080
00081 MemSet(&ctl, 0, sizeof(ctl));
00082 ctl.keysize = sizeof(Oid);
00083 ctl.entrysize = sizeof(TableSpaceCacheEntry);
00084 ctl.hash = oid_hash;
00085 TableSpaceCacheHash =
00086 hash_create("TableSpace cache", 16, &ctl,
00087 HASH_ELEM | HASH_FUNCTION);
00088
00089
00090 if (!CacheMemoryContext)
00091 CreateCacheMemoryContext();
00092
00093
00094 CacheRegisterSyscacheCallback(TABLESPACEOID,
00095 InvalidateTableSpaceCacheCallback,
00096 (Datum) 0);
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106 static TableSpaceCacheEntry *
00107 get_tablespace(Oid spcid)
00108 {
00109 TableSpaceCacheEntry *spc;
00110 HeapTuple tp;
00111 TableSpaceOpts *opts;
00112
00113
00114
00115
00116
00117 if (spcid == InvalidOid)
00118 spcid = MyDatabaseTableSpace;
00119
00120
00121 if (!TableSpaceCacheHash)
00122 InitializeTableSpaceCache();
00123 spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
00124 (void *) &spcid,
00125 HASH_FIND,
00126 NULL);
00127 if (spc)
00128 return spc;
00129
00130
00131
00132
00133
00134
00135
00136 tp = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spcid));
00137 if (!HeapTupleIsValid(tp))
00138 opts = NULL;
00139 else
00140 {
00141 Datum datum;
00142 bool isNull;
00143
00144 datum = SysCacheGetAttr(TABLESPACEOID,
00145 tp,
00146 Anum_pg_tablespace_spcoptions,
00147 &isNull);
00148 if (isNull)
00149 opts = NULL;
00150 else
00151 {
00152 bytea *bytea_opts = tablespace_reloptions(datum, false);
00153
00154 opts = MemoryContextAlloc(CacheMemoryContext, VARSIZE(bytea_opts));
00155 memcpy(opts, bytea_opts, VARSIZE(bytea_opts));
00156 }
00157 ReleaseSysCache(tp);
00158 }
00159
00160
00161
00162
00163
00164
00165 spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
00166 (void *) &spcid,
00167 HASH_ENTER,
00168 NULL);
00169 spc->opts = opts;
00170 return spc;
00171 }
00172
00173
00174
00175
00176
00177 void
00178 get_tablespace_page_costs(Oid spcid,
00179 double *spc_random_page_cost,
00180 double *spc_seq_page_cost)
00181 {
00182 TableSpaceCacheEntry *spc = get_tablespace(spcid);
00183
00184 Assert(spc != NULL);
00185
00186 if (spc_random_page_cost)
00187 {
00188 if (!spc->opts || spc->opts->random_page_cost < 0)
00189 *spc_random_page_cost = random_page_cost;
00190 else
00191 *spc_random_page_cost = spc->opts->random_page_cost;
00192 }
00193
00194 if (spc_seq_page_cost)
00195 {
00196 if (!spc->opts || spc->opts->seq_page_cost < 0)
00197 *spc_seq_page_cost = seq_page_cost;
00198 else
00199 *spc_seq_page_cost = spc->opts->seq_page_cost;
00200 }
00201 }