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

cache: resolution-persistent r/w transactions

this is a little hacked, I'd like to do list of nested
transactions later and short-lived read transactions.
parent 98076cd8
Branches
Tags
No related merge requests found
......@@ -22,5 +22,7 @@ lib/rplan.c
lib/layer/stats.h
lib/layer/stats.c
lib/defines.h
lib/layer/itercache.h
lib/layer/itercache.c
lib/cache.h
lib/cache.c
.
include
\ No newline at end of file
include
lib/layer
lib
......@@ -20,6 +20,7 @@ struct kr_cache
struct kr_txn
{
MDB_dbi dbi;
unsigned flags;
MDB_txn *txn;
MDB_txn *parent;
mm_ctx_t *mm;
......@@ -233,7 +234,7 @@ void kr_cache_close(struct kr_cache *cache)
mm_free(cache->pool, cache);
}
struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent, mm_ctx_t *mm)
struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent, unsigned flags, mm_ctx_t *mm)
{
struct kr_txn *txn = mm_alloc(mm, sizeof(struct kr_txn));
if (txn == NULL) {
......@@ -247,7 +248,13 @@ struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent,
txn->parent = parent->txn;
}
int ret = mdb_txn_begin(cache->env, txn->parent, 0, &txn->txn);
unsigned mdb_flags = 0;
txn->flags = flags;
if (flags & KR_CACHE_RDONLY) {
mdb_flags |= MDB_RDONLY;
}
int ret = mdb_txn_begin(cache->env, txn->parent, mdb_flags, &txn->txn);
if (ret != 0) {
mm_free(mm, txn);
return NULL;
......@@ -256,7 +263,7 @@ struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent,
#ifndef NDEBUG
MDB_stat stat;
mdb_stat(txn->txn, txn->dbi, &stat);
DEBUG_MSG("TX_BEGIN, %zu entries\n", stat.ms_entries);
DEBUG_MSG("TX_BEGIN, flags=%u, %zu entries\n", flags, stat.ms_entries);
#endif
return txn;
......
......@@ -17,16 +17,21 @@ limitations under the License.
#include <libknot/rrset.h>
enum kr_cache_flag {
KR_CACHE_NOFLAG = 0,
KR_CACHE_RDONLY = 1 << 0
};
struct kr_cache;
struct kr_txn;
struct kr_cache *kr_cache_open(const char *handle, unsigned flags, mm_ctx_t *mm);
void kr_cache_close(struct kr_cache *cache);
struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent, mm_ctx_t *mm);
struct kr_txn *kr_cache_txn_begin(struct kr_cache *cache, struct kr_txn *parent, unsigned flags, mm_ctx_t *mm);
int kr_cache_txn_commit(struct kr_txn *txn);
void kr_cache_txn_abort(struct kr_txn *txn);
int kr_cache_query(struct kr_txn *txn, knot_rrset_t *rr);
int kr_cache_insert(struct kr_txn *txn, const knot_rrset_t *rr, unsigned flags);
int kr_cache_remove(struct kr_txn *txn, const knot_rrset_t *rr);
\ No newline at end of file
int kr_cache_remove(struct kr_txn *txn, const knot_rrset_t *rr);
......@@ -21,10 +21,20 @@ int kr_context_init(struct kr_context *ctx, mm_ctx_t *mm)
int kr_context_reset(struct kr_context *ctx)
{
/* Finalize transactions. */
if (ctx->txn.write) {
kr_cache_txn_commit(ctx->txn.write);
}
if (ctx->txn.read) {
kr_cache_txn_abort(ctx->txn.read);
}
ctx->state = 0;
ctx->resolved_qry = NULL;
ctx->current_ns = NULL;
ctx->query = NULL;
ctx->txn.read = NULL;
ctx->txn.write = NULL;
kr_rplan_clear(&ctx->rplan);
return 0;
......@@ -38,12 +48,29 @@ int kr_context_deinit(struct kr_context *ctx)
return -1;
}
struct kr_txn *kr_context_txn_acquire(struct kr_context *ctx, unsigned flags)
{
struct kr_txn **txn = &ctx->txn.write;
if (flags & KR_CACHE_RDONLY) {
txn = &ctx->txn.read;
}
if (*txn != NULL) {
return *txn;
}
return *txn = kr_cache_txn_begin(ctx->cache, NULL, flags, ctx->pool);
}
void kr_context_txn_release(struct kr_txn *txn)
{
}
int kr_result_init(struct kr_context *ctx, struct kr_result *result)
{
memset(result, 0, sizeof(struct kr_result));
/* Initialize answer packet. */
knot_pkt_t *ans = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, ctx->pool);
if (ans == NULL) {
return -1;
......@@ -61,20 +88,12 @@ int kr_result_init(struct kr_context *ctx, struct kr_result *result)
result->ans = ans;
/* Start cache transaction. */
result->txn = kr_cache_txn_begin(ctx->cache, NULL, ctx->pool);
if (result->txn == NULL) {
knot_pkt_free(&ans);
return -1;
}
return 0;
}
int kr_result_deinit(struct kr_result *result)
{
knot_pkt_free(&result->ans);
kr_cache_txn_commit(result->txn);
return 0;
}
......@@ -30,7 +30,6 @@ struct kr_result {
struct timeval t_start, t_end;
unsigned total_rtt;
unsigned nr_queries;
struct kr_txn *txn;
};
/*! \brief Name resolution context. */
......@@ -42,6 +41,10 @@ struct kr_context
struct kr_rplan rplan;
struct kr_delegmap dp_map;
struct kr_cache *cache;
struct {
struct kr_txn *read;
struct kr_txn *write;
} txn;
mm_ctx_t *pool;
unsigned state;
unsigned options;
......@@ -50,6 +53,8 @@ struct kr_context
int kr_context_init(struct kr_context *ctx, mm_ctx_t *mm);
int kr_context_reset(struct kr_context *ctx);
int kr_context_deinit(struct kr_context *ctx);
struct kr_txn *kr_context_txn_acquire(struct kr_context *ctx, unsigned flags);
void kr_context_txn_release(struct kr_txn *txn);
int kr_result_init(struct kr_context *ctx, struct kr_result *result);
int kr_result_deinit(struct kr_result *result);
\ No newline at end of file
int kr_result_deinit(struct kr_result *result);
......@@ -209,7 +209,9 @@ static int resolve_auth(knot_pkt_t *pkt, struct kr_layer_param *param)
}
/* Update cache. */
kr_cache_insert(result->txn, &an->rr[i], 0);
struct kr_txn *txn = kr_context_txn_acquire(resolve, 0);
kr_cache_insert(txn, &an->rr[i], 0);
kr_context_txn_release(txn);
/* Check canonical name. */
follow_cname_chain(&cname, &an->rr[i], param);
......@@ -272,10 +274,11 @@ static int prepare_query(knot_layer_t *ctx, knot_pkt_t *pkt)
return -1;
}
/* TODO: hacked cache */
struct kr_txn *txn = kr_context_txn_acquire(resolve, KR_CACHE_RDONLY);
knot_rrset_t cached_reply;
knot_rrset_init(&cached_reply, next->sname, next->stype, next->sclass);
if (kr_cache_query(result->txn, &cached_reply) == 0) {
if (kr_cache_query(txn, &cached_reply) == 0) {
/* Solve this from cache. */
update_result(next, result, &cached_reply);
knot_rdataset_clear(&cached_reply.rrs, resolve->pool);
......@@ -283,9 +286,11 @@ static int prepare_query(knot_layer_t *ctx, knot_pkt_t *pkt)
/* Resolved current SNAME. */
knot_wire_set_rcode(result->ans->wire, KNOT_RCODE_NOERROR);
resolve->resolved_qry = next;
kr_context_txn_release(txn);
return NS_PROC_DONE;
}
knot_rdataset_clear(&cached_reply.rrs, resolve->pool);
kr_context_txn_release(txn);
knot_pkt_clear(pkt);
......
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