Now it should keep working if the file has been replaced.
#include "db.h"
#include "lib/cache/cdb_lmdb.h"
-#include <lib/cache/impl.h>
+#include "lib/cache/impl.h"
//#include <lib/defines.h>
#include <ctype.h> //DEBUG
return 0;
}
+int kr_gc_cache_check_health(struct kr_cache *kres_db, knot_db_t ** libknot_db)
+{
+ int ret = kr_cdb_lmdb()->check_health(kres_db->db, &kres_db->stats);
+ if (ret == 0) {
+ return 0;
+ } else if (ret != 1) {
+ kr_gc_cache_close(kres_db, *libknot_db);
+ return ret;
+ }
+ /* Cache was reopen. */
+ free(*libknot_db);
+ *libknot_db = knot_db_t_kres2libknot(kres_db->db);
+ if (*libknot_db == NULL) {
+ printf("Out of memory.\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db)
{
free(knot_db);
int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
knot_db_t ** libknot_db);
+int kr_gc_cache_check_health(struct kr_cache *kres_db, knot_db_t ** libknot_db);
+
void kr_gc_cache_close(struct kr_cache *kres_db, knot_db_t * knot_db);
typedef int (*kr_gc_iter_callback)(const knot_db_val_t * key,
int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
{
assert(cfg && state);
+ int ret;
if (!*state) { // Cache not open -> do that.
*state = calloc(1, sizeof(**state));
if (!*state) {
return KNOT_ENOMEM;
}
- int ret = kr_gc_cache_open(cfg->cache_path, &(*state)->kres_db,
+ ret = kr_gc_cache_open(cfg->cache_path, &(*state)->kres_db,
&(*state)->db);
- if (ret) {
- free(*state);
- *state = NULL;
- return ret;
- }
+ } else { // To be sure, we guard against the file getting replaced.
+ ret = kr_gc_cache_check_health(&(*state)->kres_db, &(*state)->db);
+ }
+ if (ret) {
+ free(*state);
+ *state = NULL;
+ return ret;
}
knot_db_t *const db = (*state)->db; // frequently used shortcut
gc_timer_start(&timer_analyze);
ctx_compute_categories_t cats = { { 0 }
};
- int ret = kr_gc_cache_iter(db, cb_compute_categories, &cats);
+ ret = kr_gc_cache_iter(db, cb_compute_categories, &cats);
if (ret != KNOT_EOK) {
kr_cache_gc_free_state(state);
return ret;
#include <stdlib.h>
#include <unistd.h>
-#include <lib/defines.h>
+#include "lib/defines.h"
+#include "lib/utils.h"
#include <libknot/libknot.h>
#include "kresconfig.h"
return 1;
}
+#ifdef DEBUG
+ kr_verbose_set(true); // used inside cache operations
+#endif
+
int exit_code = 0;
kr_cache_gc_state_t *gc_state = NULL;
do {