From 852ba7ee971a6e18463b54c7decd1949a0deee84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstro=CC=88m?= Date: Tue, 14 Mar 2017 11:20:23 +0100 Subject: [PATCH] Avoid allocating hypertable cache storage for negative entries. The hypertable cache stores negative cache entries to speed up checks for tables that aren't hypertables. However, a full hypertable cache entry was allocated for these negative entries, thus wasting cache storage. With this update, the full entry is only allocated for positive entries that actually represent hypertables. --- src/hypertable_cache.c | 74 +++++++++++++++++++----------------------- src/hypertable_cache.h | 11 +++---- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/hypertable_cache.c b/src/hypertable_cache.c index 439937f01..d6e764f39 100644 --- a/src/hypertable_cache.c +++ b/src/hypertable_cache.c @@ -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, diff --git a/src/hypertable_cache.h b/src/hypertable_cache.h index a1b30422b..e73ab9211 100644 --- a/src/hypertable_cache.h +++ b/src/hypertable_cache.h @@ -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 */