From 78e79ab51780641bb9d5370840691f221ba56b28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Vavru=C5=A1a?= <marek.vavrusa@nic.cz> Date: Mon, 5 Oct 2015 18:25:49 +0200 Subject: [PATCH] lib/cache: key format change, code to check versions the key is now stored in a format friendly to prefix search, the values also contain one more 16bit field to store rank of the data (to be utilised later) --- daemon/bindings.c | 3 ++- lib/cache.c | 63 ++++++++++++++++++++++++++++++++++++--------- lib/cache.h | 1 + lib/layer/rrcache.c | 2 +- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/daemon/bindings.c b/daemon/bindings.c index d5c20d7f5..9221d27c1 100644 --- a/daemon/bindings.c +++ b/daemon/bindings.c @@ -328,7 +328,8 @@ static int cache_count(lua_State *L) lua_error(L); } - lua_pushinteger(L, storage->count(&txn.t)); + /* First key is a version counter, omit it. */ + lua_pushinteger(L, storage->count(&txn.t) - 1); kr_cache_txn_abort(&txn); return 1; } diff --git a/lib/cache.c b/lib/cache.c index f75cd76fd..5fd6ec115 100644 --- a/lib/cache.c +++ b/lib/cache.c @@ -29,22 +29,58 @@ #include "lib/defines.h" #include "lib/utils.h" +/* Cache version */ +#define KEY_VERSION "V\x01" /* Key size */ -#define KEY_HSIZE (1 + sizeof(uint16_t)) +#define KEY_HSIZE (sizeof(uint8_t) + sizeof(uint16_t)) #define KEY_SIZE (KEY_HSIZE + KNOT_DNAME_MAXLEN) -#define txn_api(txn) (txn->owner->api) +#define txn_api(txn) ((txn)->owner->api) + +/** @internal Check cache internal data version. Clear if it doesn't match. */ +static void assert_right_version(struct kr_cache *cache) +{ + /* Check cache ABI version */ + struct kr_cache_txn txn; + int ret = kr_cache_txn_begin(cache, &txn, 0); + if (ret != 0) { + return; /* N/A, doesn't work. */ + } + namedb_val_t key = { KEY_VERSION, 2 }; + namedb_val_t val = { NULL, 0 }; + ret = txn_api(&txn)->find(&txn.t, &key, &val, 0); + if (ret == 0) { /* Version is OK */ + kr_cache_txn_abort(&txn); + return; + } + /* Recreate cache and write version key */ + ret = txn_api(&txn)->count(&txn.t); + if (ret > 0) { /* Non-empty cache, purge it. */ + log_info("[cache] version mismatch, clearing\n"); + kr_cache_clear(&txn); + kr_cache_txn_commit(&txn); + ret = kr_cache_txn_begin(cache, &txn, 0); + } + /* Either purged or empty. */ + if (ret == 0) { + txn_api(&txn)->insert(&txn.t, &key, &val, 0); + kr_cache_txn_commit(&txn); + } +} int kr_cache_open(struct kr_cache *cache, const namedb_api_t *api, void *opts, mm_ctx_t *mm) { if (!cache) { return kr_error(EINVAL); } + /* Open cache */ cache->api = (api == NULL) ? namedb_lmdb_api() : api; int ret = cache->api->init(&cache->db, mm, opts); if (ret != 0) { return ret; } memset(&cache->stats, 0, sizeof(cache->stats)); + /* Check cache ABI version */ + assert_right_version(cache); return kr_ok(); } @@ -99,20 +135,23 @@ void kr_cache_txn_abort(struct kr_cache_txn *txn) } } -/** @internal Composed key as { u8 tag, u8[1-255] name, u16 type } */ +/** + * @internal Composed key as { u8 tag, u8[1-255] name, u16 type } + * The name is lowercased and label order is reverted for easy prefix search. + * e.g. '\x03nic\x02cz\x00' is saved as '\0x00cz\x00nic\x00' + */ static size_t cache_key(uint8_t *buf, uint8_t tag, const knot_dname_t *name, uint16_t rrtype) { - /* Write tag + type */ - buf[0] = tag; - memcpy(buf + 1, &rrtype, sizeof(uint16_t)); - buf += KEY_HSIZE; - /* Write lowercased name */ - int ret = knot_dname_to_wire(buf, name, KNOT_DNAME_MAXLEN); - if (ret <= 0) { + /* Convert to lookup format */ + int ret = knot_dname_lf(buf, name, NULL); + if (ret != 0) { return 0; } - knot_dname_to_lower(buf); - return KEY_HSIZE + ret; + /* Write tag + type */ + uint8_t name_len = buf[0]; + buf[0] = tag; + memcpy(buf + sizeof(uint8_t) + name_len, &rrtype, sizeof(uint16_t)); + return name_len + KEY_HSIZE; } static struct kr_cache_entry *cache_entry(struct kr_cache_txn *txn, uint8_t tag, const knot_dname_t *name, uint16_t type) diff --git a/lib/cache.h b/lib/cache.h index 4408a6bfa..79852f011 100644 --- a/lib/cache.h +++ b/lib/cache.h @@ -36,6 +36,7 @@ struct kr_cache_entry uint32_t timestamp; uint32_t ttl; uint16_t count; + uint16_t rank; uint8_t data[]; }; diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c index dde29829e..4c9598f22 100644 --- a/lib/layer/rrcache.c +++ b/lib/layer/rrcache.c @@ -47,7 +47,7 @@ static int loot_rr(struct kr_cache_txn *txn, knot_pkt_t *pkt, const knot_dname_t if (fetch_rrsig) { ret = kr_cache_peek_rrsig(txn, &cache_rr, &drift); } else { - ret = kr_cache_peek_rr(txn, &cache_rr, &drift); + ret = kr_cache_peek_rr(txn, &cache_rr, &drift); } if (ret != 0) { return ret; -- GitLab