Skip to content
Snippets Groups Projects
Commit 78e79ab5 authored by Marek Vavruša's avatar Marek Vavruša
Browse files

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)
parent 08e29126
Branches
Tags
No related merge requests found
......@@ -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;
}
......
......@@ -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)
......
......@@ -36,6 +36,7 @@ struct kr_cache_entry
uint32_t timestamp;
uint32_t ttl;
uint16_t count;
uint16_t rank;
uint8_t data[];
};
......
......@@ -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;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment