diff options
author | Vladimír Čunát <vladimir.cunat@nic.cz> | 2022-07-02 12:49:38 +0200 |
---|---|---|
committer | Vladimír Čunát <vladimir.cunat@nic.cz> | 2023-06-12 10:32:28 +0200 |
commit | 18da5a5855386c98e67bc5ce8d841f4869f8586e (patch) | |
tree | 92bc218a59e31ac6f136afdee39d5429fb075da7 /lib/cache | |
parent | lib/rules: refactor kr_rule_local_data_answer() a bit (diff) | |
download | knot-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.h | 7 | ||||
-rw-r--r-- | lib/cache/cdb_lmdb.c | 29 |
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, }; |