Merged in enordstr/backend-database/enordstr/no-storage-for-negative-cache-entries (pull request #119)

Avoid allocating hypertable cache storage for negative entries.

Approved-by: Olof Rensfelt
Approved-by: ci-vast
This commit is contained in:
enordstr NA 2017-03-14 12:37:29 +00:00
commit 5f4b158c83
2 changed files with 39 additions and 46 deletions

View File

@ -17,18 +17,18 @@
#include "scanner.h"
#include "partitioning.h"
static void *hypertable_cache_create_entry(Cache *cache, CacheQueryCtx *ctx);
static void *hypertable_cache_create_entry(Cache * cache, CacheQueryCtx * ctx);
typedef struct HypertableCacheQueryCtx
{
CacheQueryCtx cctx;
Oid main_table_relid;
char *schema;
char *table_name;
} HypertableCacheQueryCtx;
const char *schema;
const char *table;
} HypertableCacheQueryCtx;
static void *
hypertable_cache_get_key(CacheQueryCtx *ctx)
hypertable_cache_get_key(CacheQueryCtx * ctx)
{
return &((HypertableCacheQueryCtx *) ctx)->main_table_relid;
}
@ -36,9 +36,8 @@ hypertable_cache_get_key(CacheQueryCtx *ctx)
typedef struct
{
Oid main_table_relid;
bool negative; /* true if no such hypertable exists */
Hypertable entry;
} HypertableNameCacheEntry;
Hypertable *hypertable;
} HypertableNameCacheEntry;
static Cache *
@ -77,15 +76,18 @@ static Cache *hypertable_cache_current = NULL;
/* Column numbers for 'hypertable' table in sql/common/tables.sql */
static bool
hypertable_tuple_found(TupleInfo *ti, void *data)
hypertable_tuple_found(TupleInfo * ti, void *data)
{
Hypertable *he = data;
HypertableNameCacheEntry *entry = data;
Hypertable *he;
Datum values[Natts_hypertable];
bool isnull[Natts_hypertable];
char *root_table_name;
char *root_table_schema;
int32 id;
he = palloc(sizeof(Hypertable));
heap_deform_tuple(ti->tuple, ti->desc, values, isnull);
id = DatumGetInt32(DATUM_GET(values, Anum_hypertable_id));
@ -109,58 +111,58 @@ hypertable_tuple_found(TupleInfo *ti, void *data)
he->chunk_size_bytes = DatumGetInt64(DATUM_GET(values, Anum_hypertable_chunk_size_bytes));
he->num_replicas = DatumGetInt16(DATUM_GET(values, Anum_hypertable_replication_factor));
entry->hypertable = he;
return false;
}
static void *
hypertable_cache_create_entry(Cache *cache, CacheQueryCtx *ctx)
hypertable_cache_create_entry(Cache * cache, CacheQueryCtx * ctx)
{
HypertableCacheQueryCtx *hctx = (HypertableCacheQueryCtx *) ctx;
Catalog *catalog = catalog_get();
HypertableNameCacheEntry *cache_entry = hctx->cctx.entry;
Hypertable *he = &cache_entry->entry;
HypertableNameCacheEntry *cache_entry = ctx->entry;
int number_found;
char *schema = hctx->schema;
char *table_name = hctx->table_name;
ScanKeyData scankey[2];
ScannerCtx scanCtx = {
.table = catalog->tables[HYPERTABLE].id,
.index = catalog->tables[HYPERTABLE].index_ids[HYPERTABLE_NAME_INDEX],
.scantype = ScannerTypeIndex,
.nkeys = 2,
.scankey = scankey,
.data = he,
.data = ctx->entry,
.tuple_found = hypertable_tuple_found,
.lockmode = AccessShareLock,
.scandirection = ForwardScanDirection,
};
if (NULL == schema)
if (NULL == hctx->schema)
{
schema = get_namespace_name(get_rel_namespace(hctx->main_table_relid));
hctx->schema = get_namespace_name(get_rel_namespace(hctx->main_table_relid));
}
if (NULL == table_name)
if (NULL == hctx->table)
{
table_name = get_rel_name(hctx->main_table_relid);
hctx->table = get_rel_name(hctx->main_table_relid);
}
/* Perform an index scan on schema and table. */
ScanKeyInit(&scankey[0], Anum_hypertable_name_idx_schema,
BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(schema));
BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(hctx->schema));
ScanKeyInit(&scankey[1], Anum_hypertable_name_idx_table,
BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(table_name));
BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(hctx->table));
number_found = scanner_scan(&scanCtx);
switch (number_found)
{
case 0:
cache_entry->negative = true;
/* Negative cache entry: table is not a hypertable */
cache_entry->hypertable = NULL;
break;
case 1:
cache_entry->negative = false;
Assert(strncmp(he->schema, get_namespace_name(get_rel_namespace(hctx->main_table_relid)), NAMEDATALEN) == 0);
Assert(strncmp(he->table, get_rel_name(hctx->main_table_relid), NAMEDATALEN) == 0);
Assert(strncmp(cache_entry->hypertable->schema, hctx->schema, NAMEDATALEN) == 0);
Assert(strncmp(cache_entry->hypertable->table, hctx->table, NAMEDATALEN) == 0);
break;
default:
elog(ERROR, "Got an unexpected number of records: %d", number_found);
@ -180,30 +182,22 @@ hypertable_cache_invalidate_callback(void)
/* Get hypertable cache entry. If the entry is not in the cache, add it. */
Hypertable *
hypertable_cache_get_entry(Cache *cache, Oid main_table_relid)
hypertable_cache_get_entry(Cache * cache, Oid main_table_relid)
{
return hypertable_cache_get_entry_with_table(cache, main_table_relid, NULL, NULL);
}
Hypertable *
hypertable_cache_get_entry_with_table(Cache *cache, Oid main_table_relid, char *schema, char *table_name)
hypertable_cache_get_entry_with_table(Cache * cache, Oid main_table_relid, const char *schema, const char *table)
{
HypertableCacheQueryCtx ctx = {
.main_table_relid = main_table_relid,
.schema = schema,
.table_name = table_name,
.table = table,
};
HypertableNameCacheEntry *entry = cache_fetch(cache, &ctx.cctx);
if (entry->negative)
{
return NULL;
}
else
{
return &entry->entry;
}
return entry->hypertable;
}
/* function to compare epochs */
@ -227,7 +221,7 @@ cmp_epochs(const void *time_pt_pointer, const void *test)
}
PartitionEpoch *
hypertable_cache_get_partition_epoch(Cache *cache, Hypertable * hce, int64 time_pt, Oid relid)
hypertable_cache_get_partition_epoch(Cache * cache, Hypertable * hce, int64 time_pt, Oid relid)
{
MemoryContext old;
PartitionEpoch *epoch,

View File

@ -30,16 +30,15 @@ typedef struct Hypertable
extern Hypertable *hypertable_cache_get_entry(Cache * cache, Oid main_table_relid);
extern Hypertable *
hypertable_cache_get_entry_with_table(Cache *cache, Oid main_table_relid, char *schema, char *table_name);
extern Hypertable *hypertable_cache_get_entry_with_table(Cache * cache, Oid main_table_relid, const char *schema, const char *table);
PartitionEpoch *hypertable_cache_get_partition_epoch(Cache * cache, Hypertable * hce, int64 time_pt, Oid relid);
extern PartitionEpoch *hypertable_cache_get_partition_epoch(Cache * cache, Hypertable * hce, int64 time_pt, Oid relid);
void hypertable_cache_invalidate_callback(void);
extern void hypertable_cache_invalidate_callback(void);
extern Cache *hypertable_cache_pin(void);
void _hypertable_cache_init(void);
void _hypertable_cache_fini(void);
extern void _hypertable_cache_init(void);
extern void _hypertable_cache_fini(void);
#endif /* TIMESCALEDB_HYPERTABLE_CACHE_H */