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

@ -23,8 +23,8 @@ typedef struct HypertableCacheQueryCtx
{
CacheQueryCtx cctx;
Oid main_table_relid;
char *schema;
char *table_name;
const char *schema;
const char *table;
} HypertableCacheQueryCtx;
static void *
@ -36,8 +36,7 @@ hypertable_cache_get_key(CacheQueryCtx *ctx)
typedef struct
{
Oid main_table_relid;
bool negative; /* true if no such hypertable exists */
Hypertable entry;
Hypertable *hypertable;
} HypertableNameCacheEntry;
@ -79,13 +78,16 @@ static Cache *hypertable_cache_current = NULL;
static bool
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,6 +111,8 @@ 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;
}
@ -117,50 +121,48 @@ 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);
@ -186,24 +188,16 @@ hypertable_cache_get_entry(Cache *cache, Oid main_table_relid)
}
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 */

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 */