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

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
No related branches found
No related tags found
No related merge requests found
......@@ -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);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment