Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

spccache.c File Reference

#include "postgres.h"
#include "access/reloptions.h"
#include "catalog/pg_tablespace.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "optimizer/cost.h"
#include "utils/catcache.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/spccache.h"
#include "utils/syscache.h"
Include dependency graph for spccache.c:

Go to the source code of this file.

Data Structures

struct  TableSpaceCacheEntry

Functions

static void InvalidateTableSpaceCacheCallback (Datum arg, int cacheid, uint32 hashvalue)
static void InitializeTableSpaceCache (void)
static TableSpaceCacheEntryget_tablespace (Oid spcid)
void get_tablespace_page_costs (Oid spcid, double *spc_random_page_cost, double *spc_seq_page_cost)

Variables

static HTABTableSpaceCacheHash = NULL

Function Documentation

static TableSpaceCacheEntry* get_tablespace ( Oid  spcid  )  [static]

Definition at line 107 of file spccache.c.

References Anum_pg_tablespace_spcoptions, CacheMemoryContext, hash_search(), HeapTupleIsValid, InitializeTableSpaceCache(), InvalidOid, MemoryContextAlloc(), MyDatabaseTableSpace, ObjectIdGetDatum, TableSpaceCacheEntry::opts, ReleaseSysCache(), SearchSysCache1, SysCacheGetAttr(), tablespace_reloptions(), TABLESPACEOID, and VARSIZE.

Referenced by get_tablespace_page_costs().

{
    TableSpaceCacheEntry *spc;
    HeapTuple   tp;
    TableSpaceOpts *opts;

    /*
     * Since spcid is always from a pg_class tuple, InvalidOid implies the
     * default.
     */
    if (spcid == InvalidOid)
        spcid = MyDatabaseTableSpace;

    /* Find existing cache entry, if any. */
    if (!TableSpaceCacheHash)
        InitializeTableSpaceCache();
    spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
                                               (void *) &spcid,
                                               HASH_FIND,
                                               NULL);
    if (spc)
        return spc;

    /*
     * Not found in TableSpace cache.  Check catcache.  If we don't find a
     * valid HeapTuple, it must mean someone has managed to request tablespace
     * details for a non-existent tablespace.  We'll just treat that case as
     * if no options were specified.
     */
    tp = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spcid));
    if (!HeapTupleIsValid(tp))
        opts = NULL;
    else
    {
        Datum       datum;
        bool        isNull;

        datum = SysCacheGetAttr(TABLESPACEOID,
                                tp,
                                Anum_pg_tablespace_spcoptions,
                                &isNull);
        if (isNull)
            opts = NULL;
        else
        {
            bytea      *bytea_opts = tablespace_reloptions(datum, false);

            opts = MemoryContextAlloc(CacheMemoryContext, VARSIZE(bytea_opts));
            memcpy(opts, bytea_opts, VARSIZE(bytea_opts));
        }
        ReleaseSysCache(tp);
    }

    /*
     * Now create the cache entry.  It's important to do this only after
     * reading the pg_tablespace entry, since doing so could cause a cache
     * flush.
     */
    spc = (TableSpaceCacheEntry *) hash_search(TableSpaceCacheHash,
                                               (void *) &spcid,
                                               HASH_ENTER,
                                               NULL);
    spc->opts = opts;
    return spc;
}

void get_tablespace_page_costs ( Oid  spcid,
double *  spc_random_page_cost,
double *  spc_seq_page_cost 
)

Definition at line 178 of file spccache.c.

References Assert, get_tablespace(), NULL, TableSpaceCacheEntry::opts, random_page_cost, TableSpaceOpts::random_page_cost, seq_page_cost, and TableSpaceOpts::seq_page_cost.

Referenced by cost_bitmap_heap_scan(), cost_index(), cost_seqscan(), cost_tidscan(), genericcostestimate(), and gincostestimate().

{
    TableSpaceCacheEntry *spc = get_tablespace(spcid);

    Assert(spc != NULL);

    if (spc_random_page_cost)
    {
        if (!spc->opts || spc->opts->random_page_cost < 0)
            *spc_random_page_cost = random_page_cost;
        else
            *spc_random_page_cost = spc->opts->random_page_cost;
    }

    if (spc_seq_page_cost)
    {
        if (!spc->opts || spc->opts->seq_page_cost < 0)
            *spc_seq_page_cost = seq_page_cost;
        else
            *spc_seq_page_cost = spc->opts->seq_page_cost;
    }
}

static void InitializeTableSpaceCache ( void   )  [static]

Definition at line 76 of file spccache.c.

References CacheMemoryContext, CacheRegisterSyscacheCallback(), CreateCacheMemoryContext(), HASHCTL::entrysize, HASHCTL::hash, hash_create(), HASH_ELEM, HASH_FUNCTION, InvalidateTableSpaceCacheCallback(), HASHCTL::keysize, MemSet, and TABLESPACEOID.

Referenced by get_tablespace().

{
    HASHCTL     ctl;

    /* Initialize the hash table. */
    MemSet(&ctl, 0, sizeof(ctl));
    ctl.keysize = sizeof(Oid);
    ctl.entrysize = sizeof(TableSpaceCacheEntry);
    ctl.hash = oid_hash;
    TableSpaceCacheHash =
        hash_create("TableSpace cache", 16, &ctl,
                    HASH_ELEM | HASH_FUNCTION);

    /* Make sure we've initialized CacheMemoryContext. */
    if (!CacheMemoryContext)
        CreateCacheMemoryContext();

    /* Watch for invalidation events. */
    CacheRegisterSyscacheCallback(TABLESPACEOID,
                                  InvalidateTableSpaceCacheCallback,
                                  (Datum) 0);
}

static void InvalidateTableSpaceCacheCallback ( Datum  arg,
int  cacheid,
uint32  hashvalue 
) [static]

Definition at line 53 of file spccache.c.

References elog, ERROR, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), NULL, TableSpaceCacheEntry::oid, TableSpaceCacheEntry::opts, and pfree().

Referenced by InitializeTableSpaceCache().

{
    HASH_SEQ_STATUS status;
    TableSpaceCacheEntry *spc;

    hash_seq_init(&status, TableSpaceCacheHash);
    while ((spc = (TableSpaceCacheEntry *) hash_seq_search(&status)) != NULL)
    {
        if (spc->opts)
            pfree(spc->opts);
        if (hash_search(TableSpaceCacheHash,
                        (void *) &spc->oid,
                        HASH_REMOVE,
                        NULL) == NULL)
            elog(ERROR, "hash table corrupted");
    }
}


Variable Documentation

HTAB* TableSpaceCacheHash = NULL [static]

Definition at line 34 of file spccache.c.