--- /dev/null
+Index: src/filed/accurate.c
+===================================================================
+--- src/filed/accurate.c (revision 7619)
++++ src/filed/accurate.c (working copy)
+@@ -36,25 +36,17 @@
+ static int dbglvl=200;
+
+ typedef struct PrivateCurFile {
+- rblink link;
++ hlink link;
+ char *fname;
+ time_t ctime;
+ time_t mtime;
+ bool seen;
+ } CurFile;
+
+-static int my_cmp(void *item1, void *item2)
+-{
+- CurFile *elt1, *elt2;
+- elt1 = (CurFile *) item1;
+- elt2 = (CurFile *) item2;
+- return strcmp(elt1->fname, elt2->fname);
+-}
+-
+ static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
+ {
+ /* TODO: just use elt->seen = 1 */
+- CurFile *temp = (CurFile *)jcr->file_list->search(elt, my_cmp);
++ CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
+ if (temp) {
+ temp->seen = 1; /* records are in memory */
+ }
+@@ -66,9 +58,7 @@
+ bool found=false;
+ ret->seen = 0;
+
+- CurFile search;
+- search.fname = fname;
+- CurFile *temp = (CurFile *)jcr->file_list->search(&search, my_cmp);
++ CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
+ if (temp) {
+ memcpy(ret, temp, sizeof(CurFile));
+ found=true;
+@@ -81,7 +71,8 @@
+ static bool accurate_init(JCR *jcr, int nbfile)
+ {
+ CurFile *elt = NULL;
+- jcr->file_list = New(rblist(elt, &elt->link));
++ jcr->file_list = (htable *)malloc(sizeof(htable));
++ jcr->file_list->init(elt, &elt->link, nbfile);
+ return true;
+ }
+
+@@ -106,7 +97,7 @@
+ ff_pkt = init_find_files();
+ ff_pkt->type = FT_DELETED;
+
+- foreach_rblist(elt, jcr->file_list) {
++ 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;
+@@ -121,7 +112,8 @@
+ bail_out:
+ /* TODO: clean htable when this function is not reached ? */
+ if (jcr->file_list) {
+- delete jcr->file_list;
++ jcr->file_list->destroy();
++ free(jcr->file_list);
+ jcr->file_list = NULL;
+ }
+ return true;
+@@ -140,11 +132,11 @@
+
+ CurFile *item;
+ /* we store CurFile, fname and ctime/mtime in the same chunk */
+- item = (CurFile *)malloc(sizeof(CurFile)+strlen(fname)+1);
++ 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, my_cmp);
++ jcr->file_list->insert(item->fname, item);
+
+ // Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
+ return ret;
+Index: src/jcr.h
+===================================================================
+--- src/jcr.h (revision 7619)
++++ src/jcr.h (working copy)
+@@ -350,7 +350,7 @@
+ CRYPTO_CTX crypto; /* Crypto ctx */
+ DIRRES* director; /* Director resource */
+ bool VSS; /* VSS used by FD */
+- rblist *file_list; /* Previous file list (accurate mode) */
++ htable *file_list; /* Previous file list (accurate mode) */
+ #endif /* FILE_DAEMON */
+
+
--- /dev/null
+Index: src/filed/accurate.c
+===================================================================
+--- src/filed/accurate.c (revision 7617)
++++ src/filed/accurate.c (working copy)
+@@ -33,182 +33,46 @@
+ #include "bacula.h"
+ #include "filed.h"
+
+-static int dbglvl=200;
++static int dbglvl=2;
+
+ typedef struct PrivateCurFile {
+-#ifndef USE_TCADB
+- hlink link;
+-#endif
+- char *fname; /* not stored with tchdb mode */
++ rblink link;
++ char *fname;
+ time_t ctime;
+ time_t mtime;
+ bool seen;
+ } CurFile;
+
+-#ifdef USE_TCADB
+-static void realfree(void *p); /* used by tokyo code */
+-
+-/*
+- * Update hash element seen=1
+- */
+-static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
++static int my_cmp(void *item1, void *item2)
+ {
+- bool ret=true;
+-
+- 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;
+- }
+-
+- return ret;
++ CurFile *elt1, *elt2;
++ elt1 = (CurFile *) item1;
++ elt2 = (CurFile *) item2;
++ return strcmp(elt1->fname, elt2->fname);
+ }
+
+-static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
++static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
+ {
+- bool found=false;
+- ret->seen = 0;
+- int size;
+- CurFile *elt;
+-
+- elt = (CurFile*)tcadbget(jcr->file_list,
+- fname, strlen(fname)+1, &size);
+- if (elt)
+- {
+- /* 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);
++ /* TODO: just use elt->seen = 1 */
++ CurFile *temp = (CurFile *)jcr->file_list->search(elt, my_cmp);
++ if (temp) {
++ temp->seen = 1; /* records are in memory */
+ }
+- return found;
+-}
+-
+-/* Create tokyo dbm hash file
+- * If something goes wrong, we cancel accurate mode.
+- */
+-static bool accurate_init(JCR *jcr, int nbfile)
+-{
+- 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);
+-
+- 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, "*");
+- }
+-
+- 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;
+- }
+- free_pool_memory(temp);
+- return jcr->file_list != 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)
+-{
+- char *key;
+- CurFile *elt;
+- int size;
+- FF_PKT *ff_pkt;
+- int stream = STREAM_UNIX_ATTRIBUTES;
+-
+- if (!jcr->accurate || jcr->get_JobLevel() == L_FULL) {
+- goto bail_out;
+- }
+-
+- if (jcr->file_list == NULL) {
+- goto bail_out;
+- }
+-
+- ff_pkt = init_find_files();
+- ff_pkt->type = FT_DELETED;
+-
+- /* 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"));
+- }
+-
+- /* delete the object */
+- tcadbdel(jcr->file_list);
+- 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;
+ }
+
+-#else /* HTABLE mode */
+-
+-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 */
+- return true;
+-}
+-
+ static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
+ {
+ bool found=false;
+ ret->seen = 0;
+
+- CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
++ CurFile search;
++ search.fname = fname;
++ CurFile *temp = (CurFile *)jcr->file_list->search(&search, my_cmp);
+ if (temp) {
+ memcpy(ret, temp, sizeof(CurFile));
+ found=true;
+-// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
++ Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
+ }
+
+ return found;
+@@ -217,8 +81,7 @@
+ 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);
++ jcr->file_list = New(rblist(elt, &elt->link));
+ return true;
+ }
+
+@@ -243,7 +106,7 @@
+ ff_pkt = init_find_files();
+ ff_pkt->type = FT_DELETED;
+
+- foreach_htable(elt, jcr->file_list) {
++ foreach_rblist(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;
+@@ -258,15 +121,12 @@
+ 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;
+ }
+
+-#endif /* common code */
+-
+ static bool accurate_add_file(JCR *jcr, char *fname, char *lstat)
+ {
+ bool ret = true;
+@@ -278,25 +138,15 @@
+ 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"));
+- ret = false;
+- }
+-#else /* 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);
++ item = (CurFile *)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
++ jcr->file_list->insert(item, my_cmp);
+
+-// Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
++ Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
+ return ret;
+ }
+
+@@ -399,17 +249,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/jcr.h
+===================================================================
+--- src/jcr.h (revision 7618)
++++ src/jcr.h (working copy)
+@@ -350,12 +350,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
+- htable *file_list; /* Previous file list (accurate mode) */
+-#endif
++ rblist *file_list; /* Previous file list (accurate mode) */
+ #endif /* FILE_DAEMON */
+
+