Commit 805e5b59 authored by Marek Vavruša's avatar Marek Vavruša

cache: set maxsize, abort failed transactions, ideas for pruning

The pruning is going to be a little tricky with the db,
as of now first query that fills up cache to the brim clears it.
parent 49fbec42
......@@ -22,6 +22,7 @@
#include <libknot/internal/mempattern.h>
#include <libknot/internal/namedb/namedb_lmdb.h>
#include <libknot/dnssec/random.h>
#include <libknot/errcode.h>
#include <libknot/descriptor.h>
......@@ -31,9 +32,10 @@
#define DEBUG_MSG(fmt, ...) fprintf(stderr, "[cache] " fmt, ## __VA_ARGS__)
#define db_api namedb_lmdb_api()
namedb_t *kr_cache_open(const char *handle, mm_ctx_t *mm)
namedb_t *kr_cache_open(const char *handle, mm_ctx_t *mm, size_t maxsize)
{
struct namedb_lmdb_opts opts = NAMEDB_LMDB_OPTS_INITIALIZER;
opts.mapsize = maxsize;
opts.path = handle;
namedb_t *db = NULL;
......@@ -57,7 +59,11 @@ int kr_cache_txn_begin(namedb_t *cache, namedb_txn_t *txn, unsigned flags)
int kr_cache_txn_commit(namedb_txn_t *txn)
{
return db_api->txn_commit(txn);
int ret = db_api->txn_commit(txn);
if (ret != KNOT_EOK) {
kr_cache_txn_abort(txn);
}
return ret;
}
void kr_cache_txn_abort(namedb_txn_t *txn)
......@@ -136,7 +142,6 @@ int kr_cache_insert(namedb_txn_t *txn, const knot_rrset_t *rr, uint32_t timestam
uint8_t keybuf[KNOT_DNAME_MAXLEN + sizeof(uint16_t)];
size_t key_len = cache_key(keybuf, rr->owner, rr->type);
namedb_val_t key = { keybuf, key_len };
namedb_val_t val = { NULL, sizeof(struct kr_cache_rrset) + knot_rdataset_size(&rr->rrs) };
#ifndef NDEBUG
......@@ -144,7 +149,7 @@ int kr_cache_insert(namedb_txn_t *txn, const knot_rrset_t *rr, uint32_t timestam
knot_dname_to_str(name_str, rr->owner, sizeof(name_str));
char type_str[16];
knot_rrtype_to_string(rr->type, type_str, sizeof(type_str));
DEBUG_MSG("insert '%s %s' => %u RRs (%zuB)\n", name_str, type_str, rr->rrs.rr_count, val.len);
DEBUG_MSG("insert '%s %s' => %u RRs (key=%zuB,data=%zuB)\n", name_str, type_str, rr->rrs.rr_count, key.len, val.len);
#endif
int ret = db_api->insert(txn, &key, &val, 0);
......@@ -171,3 +176,27 @@ int kr_cache_remove(namedb_txn_t *txn, const knot_rrset_t *rr)
return db_api->del(txn, &key);
}
int kr_cache_clear(namedb_txn_t *txn)
{
return db_api->clear(txn);
}
int kr_cache_prune(namedb_txn_t *txn, uint32_t timestamp)
{
/* Whole cache sweep is not feasible as we don't have a list of items sorted
* by age nor any sort of LRU/MRU, completely random replace is not possible
* as well.
* - The LMDB also can't delete items when the MAPSIZE is reached.
* - So we're probably need to iteratively scan the LMDB and prune aged
* items.
* - This is not ideal, because queries won't be able to write to cache
* until at least some entry ages out.
* - Idea - make poor man's LRU with two databases doing following:
* - Fill up 1, mark that it's unwritable
* - Fill up 2, mark that it's unwritable
* - Clear 1, all writes will now go in there
* - This gives us LR(written) with resolution 2
*/
return KNOT_EOK;
}
......@@ -33,9 +33,10 @@ struct kr_cache_rrset
* \brief Open/create persistent cache in given path.
* \param handle Path to existing directory where the DB should be created.
* \param mm Memory context.
* \param maxsize Maximum database size (bytes)
* \return database instance or NULL
*/
namedb_t *kr_cache_open(const char *handle, mm_ctx_t *mm);
namedb_t *kr_cache_open(const char *handle, mm_ctx_t *mm, size_t maxsize);
/*!
* \brief Close persistent cache.
......@@ -94,3 +95,19 @@ int kr_cache_insert(namedb_txn_t *txn, const knot_rrset_t *rr, uint32_t timestam
* \return KNOT_E*
*/
int kr_cache_remove(namedb_txn_t *txn, const knot_rrset_t *rr);
/*!
* \brief Clear all items from the cache.
* \param txn transaction instance
* \return KNOT_E*
*/
int kr_cache_clear(namedb_txn_t *txn);
/*!
* \brief Clear aged items from the database.
* \param txn transaction instance
* \param timestamp current time
* \return KNOT_E*
*/
int kr_cache_prune(namedb_txn_t *txn, uint32_t timestamp);
Markdown is supported
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