===================================================================
--- src/filed/accurate.c (révision 7288)
+++ src/filed/accurate.c (copie de travail)
-@@ -36,7 +36,7 @@
- static int dbglvl=200;
+@@ -32,193 +32,295 @@
- typedef struct PrivateCurFile {
--#ifndef USE_TCADB
-+#ifdef USE_HTABLE
- hlink link;
- #endif
- char *fname; /* not stored with tchdb mode */
-@@ -45,9 +45,9 @@
- bool seen;
- } CurFile;
+ #include "bacula.h"
+ #include "filed.h"
++#include "lib/htable.h"
++static int dbglvl=500;
-+
- #ifdef USE_TCADB
+-static int dbglvl=200;
++#ifdef USE_DB
++#include <db.h>
+
+-typedef struct PrivateCurFile {
+-#ifndef USE_TCADB
+- hlink link;
+-#endif
+- char *fname; /* not stored with tchdb mode */
+- time_t ctime;
+- time_t mtime;
+- bool seen;
+-} CurFile;
+-
+-#ifdef USE_TCADB
-static void realfree(void *p); /* used by tokyo code */
-
-+static void realfree(void *p); /* used by tokyo/db code */
/*
- * Update hash element seen=1
+- * Update hash element seen=1
++ * This backend uses DB Berkeley
*/
-@@ -190,10 +190,152 @@
- return true;
- }
+-static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
++class AccurateBackendDB : public AccurateBackend
+ {
+- bool ret=true;
++public:
++ ~AccurateBackendDB() { destroy(); }
++ bool init(JCR *jcr, int nb_elt);
++ void destroy();
--#else /* HTABLE mode */
-+#endif /* USE_TCADB */
-+#ifdef USE_DB
+- elt->seen = 1;
+- if (!tcadbput(jcr->file_list,
+- elt->fname, strlen(elt->fname)+1,
+- elt, sizeof(CurFile)))
+- { /* TODO: disabling accurate mode ? */
+- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk\n"));
+- ret = false;
++ bool insert(JCR *jcr, char *key, CurFile *item);
++ bool lookup(JCR *jcr, char *key, CurFile *item);
++
++ bool mark_as_seen(JCR *jcr, char *key, CurFile *item);
++
++ CurFile *first(CurFile *elt);
++ CurFile *next();
++ void finish();
++private:
++ DB *db; /* DB object */
++ DBC *cursorp; /* DB cursor */
++ DBT dbkey;
++ DBT dbdata;
++ POOLMEM *hash_name; /* file name for hash */
++};
++
++void AccurateBackendDB::destroy()
++{
++ /* cleanup walk cursor if any */
++ if (cursorp) {
++ cursorp->c_close(cursorp);
++ cursorp = NULL;
+ }
+-
+- return ret;
++ if (db) {
++ db->close(db, DB_NOSYNC);
++ db = NULL;
++ }
++ if (hash_name) {
++ unlink(hash_name); /* remove the hash on disk */
++ free_pool_memory(hash_name);
++ hash_name = NULL;
++ }
+ }
-+/*
-+ * Update hash element seen=1
-+ */
- static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
+-static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
++bool AccurateBackendDB::init(JCR *jcr, int nb_elt)
{
-+ bool ret=true;
-+ DBT dbkey, dbdata;
+- bool found=false;
+- ret->seen = 0;
+- int size;
+- CurFile *elt;
++ int ret;
++
++ Dmsg0(dbglvl, "init DB accurate backend\n");
+
+- elt = (CurFile*)tcadbget(jcr->file_list,
+- fname, strlen(fname)+1, &size);
+- if (elt)
++ if ((ret = db_create(&db, NULL, 0)) != 0) {
++ Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk ERR=%i\n"), ret);
++ return 0;
++ }
+
-+ elt->seen = 1;
++ db->set_errfile(db, stderr);
++ db->set_errpfx(db, "hash");
+
-+ dbkey.data = elt->fname;
-+ dbkey.size = strlen(elt->fname)+1;
-+ dbdata.data = elt;
++ if ((ret = db->set_cachesize(db, 0, 32 * 1024 * 1024, 0)) != 0) {
++ Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk cache size ERR=%i\n"), ret);
++ db->close(db, DB_NOSYNC);
++ db=NULL;
++ }
++
++ hash_name = get_pool_memory(PM_MESSAGE);
++ make_unique_filename(&hash_name, jcr->JobId, "accurate");
++
++ if ((ret = db->open(db,
++ NULL, hash_name, NULL,
++ DB_BTREE, DB_CREATE, 0600)) != 0)
+ {
+- /* TODO: don't malloc/free results */
+- found = true;
+- elt->fname = fname;
+- memcpy(ret, elt, sizeof(CurFile));
+- realfree(elt);
+-// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
++ db->close(db, DB_NOSYNC);
++ db=NULL;
++ free_pool_memory(hash_name);
++ hash_name = NULL;
++ Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk ERR=%i\n"), ret);
++ return 0;
+ }
+- return found;
++
++ return db != NULL;
+ }
+
+-/* Create tokyo dbm hash file
+- * If something goes wrong, we cancel accurate mode.
+- */
+-static bool accurate_init(JCR *jcr, int nbfile)
++/* Just update the element->seen to know if we have seen it */
++bool AccurateBackendDB::mark_as_seen(JCR *jcr, char *key, CurFile *item)
+ {
+- jcr->file_list = tcadbnew();
+-//
+-// tchdbsetcache(jcr->file_list, 300000);
+-// tchdbtune(jcr->file_list,
+-// nbfile, /* nb bucket 0.5n to 4n */
+-// 6, /* size of element 2^x */
+-// 16,
+-// 0); /* options like compression */
+-//
+- jcr->hash_name = get_pool_memory(PM_MESSAGE);
+- POOLMEM *temp = get_pool_memory(PM_MESSAGE);
++ item->seen = 1;
++ return insert(jcr, key, item);
++}
+
+- if (nbfile > 500000) {
+- make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
+- pm_strcat(jcr->hash_name, ".tcb");
+- Mmsg(temp, "%s#bnum=%i#mode=e#opts=l",
+- jcr->hash_name, nbfile*4);
+- Dmsg1(dbglvl, "Doing accurate hash on disk %s\n", jcr->hash_name);
+- } else {
+- Dmsg0(dbglvl, "Doing accurate hash on memory\n");
+- pm_strcpy(jcr->hash_name, "*");
+- pm_strcpy(temp, "*");
++/* insert/replace */
++bool AccurateBackendDB::insert(JCR *jcr, char *key, CurFile *item)
++{
++ int ret;
++ memset(&dbkey, 0, sizeof(DBT));
++ memset(&dbdata, 0, sizeof(DBT));
++ dbkey.data = key;
++ dbkey.size = strlen(key)+1;
++ dbdata.data = item;
+ dbdata.size = sizeof(CurFile);
-+ if ((ret = jcr->file_list->put(jcr->file_list, NULL, &dbkey, &dbdata, 0))) {
++ if ((ret = db->put(db, NULL, &dbkey, &dbdata, 0))) {
+ Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%i\n"), ret);
-+ return 0;
-+ }
-+ return 1;
++ return false;
+ }
++ return true;
+}
+
-+static bool accurate_lookup(JCR *jcr, char *fname, CurFile *elt)
++bool AccurateBackendDB::lookup(JCR *jcr, char *key, CurFile *item)
+{
+ int ret=false;
-+ elt->seen = 0;
-+ DBT dbkey, dbdata;
++
+ /* Zero out the DBTs before using them. */
+ memset(&dbkey, 0, sizeof(DBT));
+ memset(&dbdata, 0, sizeof(DBT));
+
-+ dbkey.data = fname;
-+ dbkey.size = strlen(fname)+1;
-+
-+ dbdata.data = elt;
++ dbkey.data = key;
++ dbkey.size = strlen(key)+1;
+
+- if(!tcadbopen(jcr->file_list, jcr->hash_name)){
+- Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk\n"));
+- Jmsg(jcr, M_INFO, 1, _("Disabling accurate mode\n"));
+- tcadbdel(jcr->file_list);
+- jcr->file_list = NULL;
+- jcr->accurate = false;
++ dbdata.data = item;
+ dbdata.ulen = sizeof(CurFile);
+ dbdata.flags = DB_DBT_USERMEM;
+
-+ if (jcr->file_list->get(jcr->file_list, NULL, &dbkey, &dbdata, 0) == 0) {
++ if (db->get(db, NULL, &dbkey, &dbdata, 0) == 0) {
+ ret=true;
-+ }
-+ elt->fname = fname;
+ }
+- free_pool_memory(temp);
+- return jcr->file_list != NULL;
++ item->fname = key;
+ return ret;
+ }
+
+-/* This function is called at the end of backup
+- * We walk over all hash disk element, and we check
+- * for elt.seen.
++/*
++ * We use user memory to copy data
+ */
+-bool accurate_send_deleted_list(JCR *jcr)
++CurFile *AccurateBackendDB::first(CurFile *elt)
+ {
+- char *key;
++ /* Zero out the DBTs before using them. */
++ memset(&dbkey, 0, sizeof(DBT));
++ memset(&dbdata, 0, sizeof(DBT));
++ dbdata.data = elt;
++ dbdata.ulen = sizeof(CurFile);
++ dbdata.flags = DB_DBT_USERMEM;
++ db->cursor(db, NULL, &cursorp, 0);
++ return next();
+}
+
-+/* Create tokyo dbm hash file
-+ * If something goes wrong, we cancel accurate mode.
++CurFile *AccurateBackendDB::next()
++{
+ CurFile *elt;
+- int size;
+- FF_PKT *ff_pkt;
+- int stream = STREAM_UNIX_ATTRIBUTES;
+-
+- if (!jcr->accurate || jcr->JobLevel == L_FULL) {
+- goto bail_out;
++ if (cursorp->c_get(cursorp, &dbkey, &dbdata, DB_NEXT) == 0) {
++ /* update fname field with fresh data */
++ elt = (CurFile *)dbdata.data;
++ elt->fname = (char *)dbkey.data;
++ return elt;
++ } else {
++ return NULL;
+ }
++}
+
+- if (jcr->file_list == NULL) {
+- goto bail_out;
++void AccurateBackendDB::finish()
++{
++ if (cursorp) {
++ cursorp->c_close(cursorp);
++ cursorp = NULL;
+ }
++}
+
+- ff_pkt = init_find_files();
+- ff_pkt->type = FT_DELETED;
++#endif /* USE_DB */
+
+- /* traverse records */
+- tcadbiterinit(jcr->file_list);
+- while((key = tcadbiternext2(jcr->file_list)) != NULL) {
+- elt = (CurFile *) tcadbget(jcr->file_list,
+- key, strlen(key)+1, &size);
+- if (elt)
+- {
+- if (!elt->seen) { /* already seen */
+- ff_pkt->fname = key;
+- ff_pkt->statp.st_mtime = elt->mtime;
+- ff_pkt->statp.st_ctime = elt->ctime;
+- encode_and_send_attributes(jcr, ff_pkt, stream);
+- }
+- realfree(elt);
+- }
+- realfree(key); /* tokyo cabinet have to use real free() */
+- }
++/****************************************************************/
+
+- term_find_files(ff_pkt);
+-bail_out:
+- /* TODO: clean htable when this function is not reached ? */
+- if (jcr->file_list) {
+- if(!tcadbclose(jcr->file_list)){
+- Jmsg(jcr, M_ERROR, 1, _("Can't close accurate hash disk\n"));
+- }
++/*
++ * This is the htable implementation for accurate mode
+ */
-+static bool accurate_init(JCR *jcr, int nbfile)
++class AccurateBackendHT : public AccurateBackend
+{
-+ int ret;
-+
-+ if ((ret = db_create(&jcr->file_list, NULL, 0)) != 0) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk ERR=%i\n"), ret);
-+ return 0;
-+ }
-+
-+ jcr->file_list->set_errfile(jcr->file_list, stderr);
-+ jcr->file_list->set_errpfx(jcr->file_list, "hash");
-+
-+ if ((ret = jcr->file_list->set_cachesize(jcr->file_list, 0, 32 * 1024 * 1024, 0)) != 0) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk cache size ERR=%i\n"), ret);
-+ }
++public:
++ ~AccurateBackendHT() { destroy(); }
++ bool init(JCR *jcr, int nb_elt);
++ void destroy();
+
+- /* delete the object */
+- tcadbdel(jcr->file_list);
+- if (!bstrcmp(jcr->hash_name, "*")) {
+- unlink(jcr->hash_name);
+- }
++ bool insert(JCR *jcr, char *key, CurFile *item);
++ bool lookup(JCR *jcr, char *key, CurFile *item);
+
+- free_pool_memory(jcr->hash_name);
+- jcr->hash_name = NULL;
+- jcr->file_list = NULL;
++ bool mark_as_seen(JCR *jcr, char *key, CurFile *item);
+
-+ jcr->hash_name = get_pool_memory(PM_MESSAGE);
-+ make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
++ CurFile *first(CurFile *elt);
++ CurFile *next();
++ void finish();
++private:
++ htable *db;
++};
+
-+ if ((ret = jcr->file_list->open(jcr->file_list,
-+ NULL, jcr->hash_name, NULL,
-+ DB_BTREE, DB_CREATE, 0600)) != 0)
-+ {
-+ jcr->file_list->close(jcr->file_list, DB_NOSYNC);
-+ jcr->file_list=NULL;
-+ free_pool_memory(jcr->hash_name);
-+ jcr->hash_name = NULL;
-+ Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk cache size ERR=%i\n"), ret);
-+ return 0;
-+ }
++typedef struct {
++ CurFile elt;
++ hlink link; /* need this for htable link */
++} HTCurFile;
+
-+ return jcr->file_list != NULL;
++void AccurateBackendHT::destroy()
++{
++ if (db) {
++ db->destroy();
++ free(db);
++ db = NULL;
+ }
+}
+
-+/* This function is called at the end of backup
-+ * We walk over all hash disk element, and we check
-+ * for elt.seen.
-+ */
-+bool accurate_send_deleted_list(JCR *jcr)
++bool AccurateBackendHT::init(JCR *jcr, int nb_elt)
+{
-+ CurFile elt;
-+ FF_PKT *ff_pkt;
-+ int stream = STREAM_UNIX_ATTRIBUTES;
-+ DBC *cursorp=NULL;
-+ DBT dbkey, dbdata;
-+ /* Zero out the DBTs before using them. */
-+ memset(&dbkey, 0, sizeof(DBT));
-+ memset(&dbdata, 0, sizeof(DBT));
-+ dbdata.data = &elt;
-+ dbdata.ulen = sizeof(CurFile);
-+ dbdata.flags = DB_DBT_USERMEM;
-+
-+ if (!jcr->accurate || jcr->JobLevel == L_FULL) {
-+ goto bail_out;
-+ }
-+
-+ if (jcr->file_list == NULL) {
-+ goto bail_out;
-+ }
++ Dmsg0(dbglvl, "init HT accurate backend\n");
+
-+ ff_pkt = init_find_files();
-+ ff_pkt->type = FT_DELETED;
++ HTCurFile *elt=NULL;
++ db = (htable *)malloc(sizeof(htable));
++ db->init(elt, &elt->link, nb_elt);
+ return true;
+ }
+
+-#else /* HTABLE mode */
++bool AccurateBackendHT::insert(JCR *jcr, char *key, CurFile *item)
++{
++ /* alloc CurFile + hlink + fname */
++ HTCurFile *htf = (HTCurFile *)db->hash_malloc(sizeof(HTCurFile)+strlen(key)+1);
++ memcpy(&htf->elt, item, sizeof(CurFile));
+
+-static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
++ /* store fname at the end of the struct */
++ htf->elt.fname = (char *) htf + sizeof(HTCurFile);
+
-+ /* traverse records */
-+ jcr->file_list->cursor(jcr->file_list, NULL, &cursorp, 0);
++ strcpy(htf->elt.fname, key);
++ db->insert(htf->elt.fname, htf);
++ return true;
++}
+
-+ while(cursorp->c_get(cursorp, &dbkey, &dbdata, DB_NEXT) == 0) {
-+ if (!elt.seen) { /* already seen */
-+ ff_pkt->fname = (char *) dbkey.data;
-+ ff_pkt->statp.st_mtime = elt.mtime;
-+ ff_pkt->statp.st_ctime = elt.ctime;
-+ encode_and_send_attributes(jcr, ff_pkt, stream);
-+ }
++bool AccurateBackendHT::mark_as_seen(JCR *jcr, char *key, CurFile *item)
+ {
+- CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
+- temp->seen = 1; /* records are in memory */
++ HTCurFile *temp = (HTCurFile *)db->lookup(key);
++ if (temp) {
++ temp->elt.seen = 1; /* update in memory */
+ }
-+ cursorp->c_close(cursorp);
+ return true;
+ }
+
+-static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
++bool AccurateBackendHT::lookup(JCR *jcr, char *key, CurFile *item)
+ {
+ bool found=false;
+- ret->seen = 0;
+
+- CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
++ HTCurFile *temp = (HTCurFile *)db->lookup(key);
+ if (temp) {
+- memcpy(ret, temp, sizeof(CurFile));
++ memcpy(item, &temp->elt, sizeof(CurFile));
+ found=true;
+-// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
+ }
+-
+ return found;
+ }
+
++CurFile *AccurateBackendHT::first(CurFile *elt)
++{
++ HTCurFile *temp = (HTCurFile *)db->first();
++ return &temp->elt;
++}
+
-+ term_find_files(ff_pkt);
-+bail_out:
++CurFile *AccurateBackendHT::next()
++{
++ HTCurFile *temp = (HTCurFile *)db->next();
++ return &temp->elt;
++}
+
-+ if (jcr->file_list) {
-+ jcr->file_list->close(jcr->file_list, DB_NOSYNC);
-+ if (!bstrcmp(jcr->hash_name, "*")) {
-+ unlink(jcr->hash_name);
-+ }
-+ free_pool_memory(jcr->hash_name);
-+ jcr->hash_name = NULL;
-+ jcr->file_list = NULL;
-+ }
-+ return true;
++void AccurateBackendHT::finish()
++{
+}
+
-+#endif /* USE_DB */
-+#ifdef USE_HTABLE
++/****************************************************************/
+
-+static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
-+{
- CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
- temp->seen = 1; /* records are in memory */
++/* Create hash file
++ * For less than 1M files, use htable in memory
++ */
+ static bool accurate_init(JCR *jcr, int nbfile)
+ {
+- CurFile *elt=NULL;
+- jcr->file_list = (htable *)malloc(sizeof(htable));
+- jcr->file_list->init(elt, &elt->link, nbfile);
++#ifdef USE_DB
++ if (nbfile > 1000000) {
++ jcr->file_list = New(AccurateBackendDB);
++ } else {
++ jcr->file_list = New(AccurateBackendHT);
++ }
++#else
++ jcr->file_list = New(AccurateBackendHT);
++#endif
++ jcr->file_list->init(jcr, nbfile);
++
+ return true;
+ }
+
+@@ -228,7 +330,8 @@
+ */
+ bool accurate_send_deleted_list(JCR *jcr)
+ {
+- CurFile *elt;
++ CurFile elt;
++ CurFile *item;
+ FF_PKT *ff_pkt;
+ int stream = STREAM_UNIX_ATTRIBUTES;
+
+@@ -242,31 +345,28 @@
+
+ ff_pkt = init_find_files();
+ ff_pkt->type = FT_DELETED;
+-
+- foreach_htable (elt, jcr->file_list) {
+- if (!elt->seen) { /* already seen */
+- Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", elt->fname, elt->seen);
+- ff_pkt->fname = elt->fname;
+- ff_pkt->statp.st_mtime = elt->mtime;
+- ff_pkt->statp.st_ctime = elt->ctime;
++
++ for (item = jcr->file_list->first(&elt); item ; item = jcr->file_list->next()) {
++ if (!item->seen) { /* already seen */
++ Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", item->fname, item->seen);
++ ff_pkt->fname = item->fname;
++ ff_pkt->statp.st_mtime = item->mtime;
++ ff_pkt->statp.st_ctime = item->ctime;
+ encode_and_send_attributes(jcr, ff_pkt, stream);
+ }
+-// free(elt->fname);
+ }
++ jcr->file_list->finish();
+
+ term_find_files(ff_pkt);
+ bail_out:
+ /* TODO: clean htable when this function is not reached ? */
+ if (jcr->file_list) {
+- jcr->file_list->destroy();
+- free(jcr->file_list);
++ delete jcr->file_list;
+ jcr->file_list = NULL;
+ }
return true;
-@@ -286,7 +428,21 @@
- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
+ }
+
+-#endif /* common code */
+-
+ static bool accurate_add_file(JCR *jcr, char *fname, char *lstat)
+ {
+ bool ret = true;
+@@ -278,25 +378,12 @@
+ elt.mtime = statp.st_mtime;
+ elt.seen = 0;
+
+-#ifdef USE_TCADB
+- if (!tcadbput(jcr->file_list,
+- fname, strlen(fname)+1,
+- &elt, sizeof(CurFile)))
+- {
+- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
++ if (!jcr->file_list->insert(jcr, fname, &elt)) {
++ Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash ERR=%s\n"));
ret = false;
}
-#else /* HTABLE */
-+#endif
-+#ifdef USE_DB
-+ DBT dbkey, dbdata;
-+ memset(&dbkey, 0, sizeof(DBT));
-+ memset(&dbdata, 0, sizeof(DBT));
-+ dbkey.data = fname;
-+ dbkey.size = strlen(fname)+1;
-+ dbdata.data = &elt;
-+ dbdata.size = sizeof(CurFile);
-+ if ((ret = jcr->file_list->put(jcr->file_list, NULL, &dbkey, &dbdata, 0))) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%i\n"), ret);
-+ return false;
-+ }
-+#endif
-+#ifdef USE_HTABLE
- CurFile *item;
- /* we store CurFile, fname and ctime/mtime in the same chunk */
- item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
-@@ -296,7 +452,7 @@
- jcr->file_list->insert(item->fname, item);
- #endif
+- CurFile *item;
+- /* we store CurFile, fname and ctime/mtime in the same chunk */
+- item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
+- memcpy(item, &elt, sizeof(CurFile));
+- item->fname = (char *)item+sizeof(CurFile);
+- strcpy(item->fname, fname);
+- jcr->file_list->insert(item->fname, item);
+-#endif
-// Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
-+ //Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
++ Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
return ret;
}
+@@ -324,7 +411,7 @@
+ fname = ff_pkt->fname;
+ }
+
+- if (!accurate_lookup(jcr, fname, &elt)) {
++ if (!jcr->file_list->lookup(jcr, fname, &elt)) {
+ Dmsg1(dbglvl, "accurate %s (not found)\n", fname);
+ stat = true;
+ goto bail_out;
+@@ -343,7 +430,7 @@
+ stat = true;
+ }
+
+- accurate_mark_file_as_seen(jcr, &elt);
++ jcr->file_list->mark_as_seen(jcr, fname, &elt);
+ Dmsg2(dbglvl, "accurate %s = %i\n", fname, stat);
+
+ bail_out:
+@@ -379,7 +466,7 @@
+ while (dir->recv() >= 0) {
+ len = strlen(dir->msg) + 1;
+ if (len < dir->msglen) {
+- accurate_add_file(jcr, dir->msg, dir->msg + len);
++ accurate_add_file(jcr, dir->msg, dir->msg + len);
+ }
+ }
+
+@@ -398,17 +485,3 @@
+
+ return true;
+ }
+-
+-#ifdef USE_TCADB
+-
+-/*
+- * Tokyo Cabinet library doesn't use smartalloc by default
+- * results need to be released with real free()
+- */
+-#undef free
+-void realfree(void *p)
+-{
+- free(p);
+-}
+-
+-#endif
Index: src/filed/filed.h
===================================================================
--- src/filed/filed.h (révision 7288)
+++ src/filed/filed.h (copie de travail)
-@@ -37,7 +37,11 @@
+@@ -35,11 +35,35 @@
+
+
#define FILE_DAEMON 1
- #ifdef USE_TCADB /* hash disk based */
- # include <tcadb.h>
+-#ifdef USE_TCADB /* hash disk based */
+-# include <tcadb.h>
-#else
-+#endif
-+#ifdef USE_DB
-+# include <db.h>
-+#endif
-+#ifdef USE_HTABLE
- # include "lib/htable.h"
- #endif
+-# include "lib/htable.h"
+-#endif
++
++/*
++ * Used to store accurate information
++ */
++typedef struct {
++ char *fname;
++ time_t ctime;
++ time_t mtime;
++ bool seen;
++} CurFile;
++
++/*
++ * Virtual class for accurate backend (libdb or htable)
++ */
++class AccurateBackend: public SMARTALLOC
++{
++public:
++ AccurateBackend() : SMARTALLOC() {}
++ virtual ~AccurateBackend() {}
++ virtual bool init(JCR *jcr, int nb_elt) = 0;
++ virtual bool insert(JCR *jcr, char *key, CurFile *item) = 0;
++ virtual bool lookup(JCR *jcr, char *key, CurFile *item) = 0;
++ virtual bool mark_as_seen(JCR *jcr, char *key, CurFile *item) = 0;
++ virtual CurFile *first(CurFile *elt) = 0;
++ virtual CurFile *next() = 0;
++ virtual void finish() = 0;
++ virtual void destroy() {}
++};
++
#include "filed_conf.h"
+ #include "fd_plugins.h"
+ #include "findlib/find.h"
Index: src/baconfig.h
===================================================================
--- src/baconfig.h (révision 7288)
#ifdef ENABLE_NLS
#include <libintl.h>
-Index: src/win32/build-depkgs-mingw32
-===================================================================
---- src/win32/build-depkgs-mingw32 (révision 7288)
-+++ src/win32/build-depkgs-mingw32 (copie de travail)
-@@ -519,7 +519,7 @@
- process_cmd_utils
- process_mkisofs
- process_dvd_rw_tools
-- process_qt4
-+# process_qt4
- else
- for dependency in "$@"
- do
Index: src/jcr.h
===================================================================
--- src/jcr.h (révision 7288)
+++ src/jcr.h (copie de travail)
-@@ -344,7 +344,12 @@
- #ifdef USE_TCADB
- TCADB *file_list; /* Previous file list (accurate mode) */
- POOLMEM *hash_name;
+@@ -341,12 +341,7 @@
+ CRYPTO_CTX crypto; /* Crypto ctx */
+ DIRRES* director; /* Director resource */
+ bool VSS; /* VSS used by FD */
+-#ifdef USE_TCADB
+- TCADB *file_list; /* Previous file list (accurate mode) */
+- POOLMEM *hash_name;
-#else
-+#endif
-+#ifdef USE_DB
-+ DB *file_list;
-+ POOLMEM *hash_name;
-+#endif
-+#ifdef USE_HTABLE
- htable *file_list; /* Previous file list (accurate mode) */
- #endif
+- htable *file_list; /* Previous file list (accurate mode) */
+-#endif
++ AccurateBackend *file_list; /* Accurate backend store */
#endif /* FILE_DAEMON */
+
+