summaryrefslogtreecommitdiffstats
path: root/lib/cache
diff options
context:
space:
mode:
authorVladimír Čunát <vladimir.cunat@nic.cz>2022-07-02 12:49:38 +0200
committerVladimír Čunát <vladimir.cunat@nic.cz>2023-06-12 10:32:28 +0200
commit18da5a5855386c98e67bc5ce8d841f4869f8586e (patch)
tree92bc218a59e31ac6f136afdee39d5429fb075da7 /lib/cache
parentlib/rules: refactor kr_rule_local_data_answer() a bit (diff)
downloadknot-resolver-18da5a5855386c98e67bc5ce8d841f4869f8586e.tar.xz
knot-resolver-18da5a5855386c98e67bc5ce8d841f4869f8586e.zip
lib/cache: add a "<" search in addition to "<="
Diffstat (limited to 'lib/cache')
-rw-r--r--lib/cache/cdb_api.h7
-rw-r--r--lib/cache/cdb_lmdb.c29
2 files changed, 35 insertions, 1 deletions
diff --git a/lib/cache/cdb_api.h b/lib/cache/cdb_api.h
index f0d810fc..43d1433f 100644
--- a/lib/cache/cdb_api.h
+++ b/lib/cache/cdb_api.h
@@ -32,6 +32,7 @@ struct kr_cdb_stats {
uint64_t match_miss;
uint64_t read_leq;
uint64_t read_leq_miss;
+ uint64_t read_less;
double usage_percent;
};
@@ -85,6 +86,12 @@ struct kr_cdb_api {
int (*read_leq)(kr_cdb_pt db, struct kr_cdb_stats *stat,
knot_db_val_t *key, knot_db_val_t *val);
+ /** Less-than search (lexicographic ordering).
+ * On successful return, key->data and val->data point to DB-owned data.
+ * return: > 0 for less, < 0 kr_error */
+ int (*read_less)(kr_cdb_pt db, struct kr_cdb_stats *stat,
+ knot_db_val_t *key, knot_db_val_t *val);
+
/** Return estimated space usage (0--100). */
double (*usage_percent)(kr_cdb_pt db);
diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c
index 1b6c33f5..76570f19 100644
--- a/lib/cache/cdb_lmdb.c
+++ b/lib/cache/cdb_lmdb.c
@@ -833,6 +833,33 @@ failure:
return lmdb_error(ret);
}
+static int cdb_read_less(kr_cdb_pt db, struct kr_cdb_stats *stats,
+ knot_db_val_t *key, knot_db_val_t *val)
+{
+ if (kr_fails_assert(db && key && key->data && val))
+ return kr_error(EINVAL);
+ struct lmdb_env *env = db2env(db);
+ MDB_cursor *curs = NULL;
+ int ret = txn_curs_get(env, &curs, stats);
+ if (ret) return ret;
+
+ MDB_val key2_m = val_knot2mdb(*key);
+ MDB_val val2_m = { 0, NULL };
+ stats->read_less++;
+ ret = mdb_cursor_get(curs, &key2_m, &val2_m, MDB_PREV);
+ if (!ret) {
+ /* finalize the output */
+ *key = val_mdb2knot(key2_m);
+ *val = val_mdb2knot(val2_m);
+ return 1;
+ } else if (ret == MDB_NOTFOUND) {
+ // stats->read_less++; // seems a pointless stat
+ } else {
+ txn_abort(env);
+ }
+ return lmdb_error(ret);
+}
+
static double cdb_usage_percent(kr_cdb_pt db)
{
knot_db_t *kdb = kr_cdb_pt2knot_db_t(db);
@@ -870,7 +897,7 @@ const struct kr_cdb_api *kr_cdb_lmdb(void)
cdb_init, cdb_deinit, cdb_count, cdb_clear, cdb_commit,
cdb_readv, cdb_writev, cdb_remove,
cdb_match,
- cdb_read_leq,
+ cdb_read_leq, cdb_read_less,
cdb_usage_percent, cdb_get_maxsize,
cdb_check_health,
};