int (*check_health)(kr_cdb_pt db, struct kr_cdb_stats *stat);
- /** Start iterating; return the first *val with *key.
+ /** Start iterating: get the first *val with *key + return error code.
*
* - in cache: ensures a RO transaction (and commits the RW txn if any)
* - in ruledb: transaction is preserved if exists, otherwise RO txn gets opened
*/
int (*it_first)(kr_cdb_pt db, struct kr_cdb_stats *stat,
const knot_db_val_t *key, knot_db_val_t *val);
- /** Advance to the next *val with the same key. */
+ /** Advance to the next *val with the same key. Return error code. */
int (*it_next)(kr_cdb_pt db, struct kr_cdb_stats *stat, knot_db_val_t *val);
+ /** Delete the current *val + return error code.
+ *
+ * You can it_next() to continue.
+ * This assumed that you got it_first() in a RW txn.
+ */
+ int (*it_del)(kr_cdb_pt db, struct kr_cdb_stats *stat);
};
*val = val_mdb2knot(val2_m);
return kr_ok();
}
+static int cdb_it_del(kr_cdb_pt db, struct kr_cdb_stats *stats)
+{
+ if (kr_fails_assert(db))
+ return kr_error(EINVAL);
+ struct lmdb_env *env = db2env(db);
+ if (kr_fails_assert(!env->is_cache && env->txn.rw_curs))
+ return kr_error(EINVAL);
+
+ MDB_cursor *curs = NULL;
+ int ret = txn_curs_get(env, &curs, stats);
+ if (ret) return ret;
+ ret = mdb_cursor_del(curs, 0/*no flags*/);
+ if (ret) return lmdb_error(env, ret);
+ return kr_ok();
+}
const struct kr_cdb_api *kr_cdb_lmdb(void)
cdb_read_leq, cdb_read_less,
cdb_usage_percent, cdb_get_maxsize,
cdb_check_health,
- cdb_it_first, cdb_it_next,
+ cdb_it_first, cdb_it_next, cdb_it_del,
};
return &api;
}