It is more convenient to return 0 instead of ENOENT.
if (ret) return kr_error(ret);
knot_db_val_t key = key_exact_type(k, type);
- ret = cache_op(cache, remove, &key, 1);
- switch (ret) {
- case 0: return 1;
- case -ABS(ENOENT): return 0;
- default: return ret;
- }
-
+ return cache_op(cache, remove, &key, 1);
}
int kr_cache_match(struct kr_cache *cache, const knot_dname_t *name,
knot_db_val_t keyval[maxcount][2], keys[maxcount];
int ret = kr_cache_match(cache, name, exact_name, keyval, maxcount);
- if (ret < 0) {
- return ret;
+ if (ret <= 0) { /* ENOENT -> nothing to remove */
+ return (ret == KNOT_ENOENT) ? 0 : ret;
}
const int count = ret;
/* Duplicate the key strings, as deletion may invalidate the pointers. */
while (--i >= 0) {
free(keys[i].data);
}
- return ret ? ret : count;
+ return ret;
}
/**
* Remove a subtree in cache. It's like _match but removing them instead of returning.
+ * @return number of deleted entries or an errcode
*/
KR_EXPORT
int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name,
int maxcount);
int (*write)(knot_db_t *db, const knot_db_val_t *key, knot_db_val_t *val,
int maxcount);
- /** Remove maxcount keys. Return error code. (Returns on first error.) */
+
+ /** Remove maxcount keys.
+ * \returns the number of succesfully removed keys or the first error code
+ * It returns on first error, but ENOENT is not considered an error. */
int (*remove)(knot_db_t *db, knot_db_val_t keys[], int maxcount);
/* Specialised operations */
struct lmdb_env *env = db;
MDB_txn *txn = NULL;
int ret = txn_get(env, &txn, false);
+ int deleted = 0;
for (int i = 0; ret == kr_ok() && i < maxcount; ++i) {
MDB_val _key = val_knot2mdb(keys[i]);
MDB_val val = { 0, NULL };
ret = lmdb_error(mdb_del(txn, env->dbi, &_key, &val));
+ if (ret == kr_ok())
+ deleted++;
+ else if (ret == KNOT_ENOENT)
+ ret = kr_ok(); /* skip over non-existing entries */
}
- return ret;
+ return ret < 0 ? ret : deleted;
}
static int cdb_match(knot_db_t *db, knot_db_val_t *key, knot_db_val_t keyval[][2], int maxcount)