Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Postgres/src/backend/utils/cache/   (Postgres Database Version 18.4©)  Datei vom 11.4.2026 mit Größe 6 kB image not shown  

Quelle  spccache.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * spccache.c
 *   Tablespace cache management.
 *
 * We cache the parsed version of spcoptions for each tablespace to avoid
 * needing to reparse on every lookup.  Right now, there doesn't appear to
 * be a measurable performance gain from doing this, but that might change
 * in the future as we add more options.
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *   src/backend/utils/cache/spccache.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/reloptions.h"
#include "catalog/pg_tablespace.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "optimizer/optimizer.h"
#include "storage/bufmgr.h"
#include "utils/catcache.h"
#include "utils/hsearch.h"
#include "utils/inval.h"
#include "utils/spccache.h"
#include "utils/syscache.h"
#include "varatt.h"


/* Hash table for information about each tablespace */
static HTAB *TableSpaceCacheHash = NULL;

typedef struct
{
 Oid   oid;   /* lookup key - must be first */
 TableSpaceOpts *opts;  /* options, or NULL if none */
} TableSpaceCacheEntry;


/*
 * InvalidateTableSpaceCacheCallback
 *  Flush all cache entries when pg_tablespace is updated.
 *
 * When pg_tablespace is updated, we must flush the cache entry at least
 * for that tablespace.  Currently, we just flush them all.  This is quick
 * and easy and doesn't cost much, since there shouldn't be terribly many
 * tablespaces, nor do we expect them to be frequently modified.
 */

static void
InvalidateTableSpaceCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
{
 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,
      &spc->oid,
      HASH_REMOVE,
      NULL) == NULL)
   elog(ERROR, "hash table corrupted");
 }
}

/*
 * InitializeTableSpaceCache
 *  Initialize the tablespace cache.
 */

static void
InitializeTableSpaceCache(void)
{
 HASHCTL  ctl;

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

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

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

/*
 * get_tablespace
 *  Fetch TableSpaceCacheEntry structure for a specified table OID.
 *
 * Pointers returned by this function should not be stored, since a cache
 * flush will invalidate them.
 */

static TableSpaceCacheEntry *
get_tablespace(Oid spcid)
{
 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,
              &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,
              &spcid,
              HASH_ENTER,
              NULL);
 spc->opts = opts;
 return spc;
}

/*
 * get_tablespace_page_costs
 *  Return random and/or sequential page costs for a given tablespace.
 *
 *  This value is not locked by the transaction, so this value may
 *  be changed while a SELECT that has used these values for planning
 *  is still executing.
 */

void
get_tablespace_page_costs(Oid spcid,
        double *spc_random_page_cost,
        double *spc_seq_page_cost)
{
 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;
 }
}

/*
 * get_tablespace_io_concurrency
 *
 *  This value is not locked by the transaction, so this value may
 *  be changed while a SELECT that has used these values for planning
 *  is still executing.
 */

int
get_tablespace_io_concurrency(Oid spcid)
{
 TableSpaceCacheEntry *spc = get_tablespace(spcid);

 if (!spc->opts || spc->opts->effective_io_concurrency < 0)
  return effective_io_concurrency;
 else
  return spc->opts->effective_io_concurrency;
}

/*
 * get_tablespace_maintenance_io_concurrency
 */

int
get_tablespace_maintenance_io_concurrency(Oid spcid)
{
 TableSpaceCacheEntry *spc = get_tablespace(spcid);

 if (!spc->opts || spc->opts->maintenance_io_concurrency < 0)
  return maintenance_io_concurrency;
 else
  return spc->opts->maintenance_io_concurrency;
}

Messung V0.5 in Prozent
C=94 H=94 G=93

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.