hashtbl: do not expose h_entry at all

This commit is contained in:
josch
2014-09-28 07:39:13 +02:00
parent 690091721a
commit 43c0b09f70
3 changed files with 131 additions and 94 deletions

View File

@@ -82,9 +82,10 @@ struct h_entry {
uint64_t ctime; uint64_t ctime;
/* the containing folder */ /* the containing folder */
union { union {
/* during runtime this is a pointer to the containing h_entry */ /* during runtime this is a pointer to the containing h_entry struct */
h_entry *parent; struct h_entry *parent;
/* when storing on disk, this is the offset of the stored h_entry */ /* when storing on disk, this is the offset of the stored h_entry
* struct */
uint64_t parent_offs; uint64_t parent_offs;
}; };
@@ -100,7 +101,7 @@ struct h_entry {
* This member could also be an array of keys which would not require * This member could also be an array of keys which would not require
* lookups on updating but we expect more reads than writes so we * lookups on updating but we expect more reads than writes so we
* sacrifice slower updates for faster lookups */ * sacrifice slower updates for faster lookups */
h_entry **children; struct h_entry **children;
/****************** /******************
* only for files * * only for files *
@@ -117,9 +118,10 @@ struct h_entry {
}; };
/* /*
* Each bucket is an array of pointers instead of an array of h_entry so that * Each bucket is an array of pointers instead of an array of h_entry structs
* the array can be changed without the memory location of the h_entry * so that the array can be changed without the memory location of the h_entry
* changing because the children of each h_entry point to those locations * struct changing because the children of each h_entry struct point to those
* locations
* *
* This also allows us to implement each bucket as a sorted list in the * This also allows us to implement each bucket as a sorted list in the
* future. Queries could then be done using bisection (O(log(n))) instead of * future. Queries could then be done using bisection (O(log(n))) instead of
@@ -130,8 +132,8 @@ struct h_entry {
struct folder_tree { struct folder_tree {
uint64_t revision; uint64_t revision;
uint64_t bucket_lens[NUM_BUCKETS]; uint64_t bucket_lens[NUM_BUCKETS];
h_entry **buckets[NUM_BUCKETS]; struct h_entry **buckets[NUM_BUCKETS];
h_entry root; struct h_entry root;
}; };
/* persistant storage file layout: /* persistant storage file layout:
@@ -141,20 +143,22 @@ struct folder_tree {
* byte 2: 0x53 -> ASCII S --> MFS == MediaFire Storage * byte 2: 0x53 -> ASCII S --> MFS == MediaFire Storage
* byte 3: 0x00 -> version information * byte 3: 0x00 -> version information
* bytes 4-11 -> last seen device revision * bytes 4-11 -> last seen device revision
* bytes 12-19 -> number of h_entry objects including root (num_hts) * bytes 12-19 -> number of h_entry structs including root (num_hts)
* bytes 20... -> h_entry objects, the first one being root * bytes 20... -> h_entry structs, the first one being root
* *
* the children pointer member of the h_entry object is useless when stored, * the children pointer member of the h_entry struct is useless when stored,
* should be set to zero and not used when reading the file * should be set to zero and not used when reading the file
*/ */
int folder_tree_store(folder_tree * tree, FILE * stream) int folder_tree_store(folder_tree * tree, FILE * stream)
{ {
/* to allow a quick mapping from keys to their offsets in the array that /* to allow a quick mapping from keys to their offsets in the array that
* will be stored, we create a hashtable of the same structure as the * will be stored, we create a hashtable of the same structure as the
* folder_tree but instead of storing pointers to h_entries in the buckets * folder_tree but instead of storing pointers to h_entries in the buckets
* we store their integer offset. This way, when one known in which bucket * we store their integer offset. This way, when one known in which bucket
* and in which position in a bucket a h_entry is, one can retrieve the * and in which position in a bucket a h_entry struct is, one can retrieve
* associated integer offset. */ * the associated integer offset. */
uint64_t **integer_buckets; uint64_t **integer_buckets;
uint64_t i, uint64_t i,
@@ -162,7 +166,7 @@ int folder_tree_store(folder_tree * tree, FILE * stream)
k, k,
num_hts; num_hts;
size_t ret; size_t ret;
h_entry *tmp_parent; struct h_entry *tmp_parent;
int bucket_id; int bucket_id;
bool found; bool found;
@@ -208,7 +212,7 @@ int folder_tree_store(folder_tree * tree, FILE * stream)
} }
/* write the root */ /* write the root */
ret = fwrite(&(tree->root), sizeof(h_entry), 1, stream); ret = fwrite(&(tree->root), sizeof(struct h_entry), 1, stream);
if (ret != 1) { if (ret != 1) {
fprintf(stderr, "cannot fwrite\n"); fprintf(stderr, "cannot fwrite\n");
return -1; return -1;
@@ -242,7 +246,8 @@ int folder_tree_store(folder_tree * tree, FILE * stream)
} }
/* write out modified record */ /* write out modified record */
ret = fwrite(tree->buckets[i][j], sizeof(h_entry), 1, stream); ret =
fwrite(tree->buckets[i][j], sizeof(struct h_entry), 1, stream);
if (ret != 1) { if (ret != 1) {
fprintf(stderr, "cannot fwrite\n"); fprintf(stderr, "cannot fwrite\n");
return -1; return -1;
@@ -270,9 +275,9 @@ folder_tree *folder_tree_load(FILE * stream)
size_t ret; size_t ret;
uint64_t num_hts; uint64_t num_hts;
uint64_t i; uint64_t i;
h_entry **ordered_entries; struct h_entry **ordered_entries;
h_entry *tmp_entry; struct h_entry *tmp_entry;
h_entry *parent; struct h_entry *parent;
int bucket_id; int bucket_id;
/* read and check the first four bytes */ /* read and check the first four bytes */
@@ -315,11 +320,12 @@ folder_tree *folder_tree_load(FILE * stream)
tree->root.children = NULL; tree->root.children = NULL;
/* to effectively map integer offsets to addresses we load the file into /* to effectively map integer offsets to addresses we load the file into
* an array of pointers to h_entry objects and free that array after we're * an array of pointers to h_entry structs and free that array after we're
* done with setting up the hashtable */ * done with setting up the hashtable */
/* populate the array of children */ /* populate the array of children */
ordered_entries = (h_entry **) malloc(num_hts * sizeof(h_entry *)); ordered_entries =
(struct h_entry **)malloc(num_hts * sizeof(struct h_entry *));
/* the first entry in this array points to the memory allocated for the /* the first entry in this array points to the memory allocated for the
* root */ * root */
@@ -327,8 +333,8 @@ folder_tree *folder_tree_load(FILE * stream)
/* read the remaining entries one by one */ /* read the remaining entries one by one */
for (i = 1; i < num_hts; i++) { for (i = 1; i < num_hts; i++) {
tmp_entry = (h_entry *) malloc(sizeof(h_entry)); tmp_entry = (struct h_entry *)malloc(sizeof(struct h_entry));
ret = fread(tmp_entry, sizeof(h_entry), 1, stream); ret = fread(tmp_entry, sizeof(struct h_entry), 1, stream);
if (ret != 1) { if (ret != 1) {
fprintf(stderr, "cannot fread\n"); fprintf(stderr, "cannot fread\n");
return NULL; return NULL;
@@ -351,8 +357,9 @@ folder_tree *folder_tree_load(FILE * stream)
/* use the parent information to populate the array of children */ /* use the parent information to populate the array of children */
parent->num_children++; parent->num_children++;
parent->children = parent->children =
(h_entry **) realloc(parent->children, (struct h_entry **)realloc(parent->children,
parent->num_children * sizeof(h_entry *)); parent->num_children *
sizeof(struct h_entry *));
if (parent->children == NULL) { if (parent->children == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -363,9 +370,9 @@ folder_tree *folder_tree_load(FILE * stream)
bucket_id = HASH_OF_KEY(ordered_entries[i]->key); bucket_id = HASH_OF_KEY(ordered_entries[i]->key);
tree->bucket_lens[bucket_id]++; tree->bucket_lens[bucket_id]++;
tree->buckets[bucket_id] = tree->buckets[bucket_id] =
(h_entry **) realloc(tree->buckets[bucket_id], (struct h_entry **)realloc(tree->buckets[bucket_id],
tree->bucket_lens[bucket_id] * tree->bucket_lens[bucket_id] *
sizeof(h_entry *)); sizeof(struct h_entry *));
if (tree->buckets[bucket_id] == NULL) { if (tree->buckets[bucket_id] == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -414,13 +421,14 @@ void folder_tree_destroy(folder_tree * tree)
} }
/* /*
* given a folderkey, lookup the h_entry of it in the tree * given a folderkey, lookup the h_entry struct of it in the hashtable
* *
* if key is NULL, then a pointer to the root is returned * if key is NULL, then a pointer to the root is returned
* *
* if no matching h_entry is found, NULL is returned * if no matching h_entry struct is found, NULL is returned
*/ */
static h_entry *folder_tree_lookup_key(folder_tree * tree, const char *key) static struct h_entry *folder_tree_lookup_key(folder_tree * tree,
const char *key)
{ {
int bucket_id; int bucket_id;
uint64_t i; uint64_t i;
@@ -437,22 +445,23 @@ static h_entry *folder_tree_lookup_key(folder_tree * tree, const char *key)
} }
} }
fprintf(stderr, "cannot find h_entry for key %s\n", key); fprintf(stderr, "cannot find h_entry struct for key %s\n", key);
return NULL; return NULL;
} }
/* /*
* given a path, return the h_entry of the last component * given a path, return the h_entry struct of the last component
* *
* the path must start with a slash * the path must start with a slash
*/ */
static h_entry *folder_tree_lookup_path(folder_tree * tree, const char *path) static struct h_entry *folder_tree_lookup_path(folder_tree * tree,
const char *path)
{ {
char *tmp_path; char *tmp_path;
char *new_path; char *new_path;
char *slash_pos; char *slash_pos;
h_entry *curr_dir; struct h_entry *curr_dir;
h_entry *result; struct h_entry *result;
uint64_t i; uint64_t i;
bool success; bool success;
@@ -531,10 +540,22 @@ static h_entry *folder_tree_lookup_path(folder_tree * tree, const char *path)
return result; return result;
} }
/*
* given a path, check if it exists in the hashtable
*/
bool folder_tree_path_exists(folder_tree * tree, const char *path)
{
struct h_entry *result;
result = folder_tree_lookup_path(tree, path);
return path != NULL;
}
int folder_tree_getattr(folder_tree * tree, const char *path, int folder_tree_getattr(folder_tree * tree, const char *path,
struct stat *stbuf) struct stat *stbuf)
{ {
h_entry *entry; struct h_entry *entry;
entry = folder_tree_lookup_path(tree, path); entry = folder_tree_lookup_path(tree, path);
@@ -566,7 +587,7 @@ int folder_tree_getattr(folder_tree * tree, const char *path,
int folder_tree_readdir(folder_tree * tree, const char *path, void *buf, int folder_tree_readdir(folder_tree * tree, const char *path, void *buf,
fuse_fill_dir_t filldir) fuse_fill_dir_t filldir)
{ {
h_entry *entry; struct h_entry *entry;
uint64_t i; uint64_t i;
entry = folder_tree_lookup_path(tree, path); entry = folder_tree_lookup_path(tree, path);
@@ -586,7 +607,7 @@ int folder_tree_readdir(folder_tree * tree, const char *path, void *buf,
return 0; return 0;
} }
static bool folder_tree_is_root(h_entry * entry) static bool folder_tree_is_root(struct h_entry *entry)
{ {
if (entry == NULL) { if (entry == NULL) {
fprintf(stderr, "entry is NULL\n"); fprintf(stderr, "entry is NULL\n");
@@ -603,12 +624,13 @@ static bool folder_tree_is_root(h_entry * entry)
* memory if necessary and adjust the children arrays of the former and new * memory if necessary and adjust the children arrays of the former and new
* parent to accommodate for the change * parent to accommodate for the change
*/ */
static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key, static struct h_entry *folder_tree_allocate_entry(folder_tree * tree,
h_entry * new_parent) const char *key,
struct h_entry *new_parent)
{ {
h_entry *entry; struct h_entry *entry;
int bucket_id; int bucket_id;
h_entry *old_parent; struct h_entry *old_parent;
uint64_t i; uint64_t i;
bool found; bool found;
@@ -628,12 +650,12 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
fprintf(stderr, fprintf(stderr,
"key is NULL but this is fine, we just create it now\n"); "key is NULL but this is fine, we just create it now\n");
/* entry was not found, so append it to the end of the bucket */ /* entry was not found, so append it to the end of the bucket */
entry = (h_entry *) calloc(1, sizeof(h_entry)); entry = (struct h_entry *)calloc(1, sizeof(struct h_entry));
bucket_id = HASH_OF_KEY(key); bucket_id = HASH_OF_KEY(key);
tree->bucket_lens[bucket_id]++; tree->bucket_lens[bucket_id]++;
tree->buckets[bucket_id] = tree->buckets[bucket_id] =
realloc(tree->buckets[bucket_id], realloc(tree->buckets[bucket_id],
sizeof(h_entry *) * tree->bucket_lens[bucket_id]); sizeof(struct h_entry *) * tree->bucket_lens[bucket_id]);
if (tree->buckets[bucket_id] == NULL) { if (tree->buckets[bucket_id] == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -648,8 +670,9 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
*/ */
new_parent->num_children++; new_parent->num_children++;
new_parent->children = new_parent->children =
(h_entry **) realloc(new_parent->children, (struct h_entry **)realloc(new_parent->children,
new_parent->num_children * sizeof(h_entry *)); new_parent->num_children *
sizeof(struct h_entry *));
if (new_parent->children == NULL) { if (new_parent->children == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -677,8 +700,8 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
if (old_parent->children[i] == entry) { if (old_parent->children[i] == entry) {
/* move the entries on the right one place to the left */ /* move the entries on the right one place to the left */
memmove(old_parent->children[i], old_parent->children[i + 1], memmove(old_parent->children[i], old_parent->children[i + 1],
sizeof(h_entry *) * (old_parent->num_children - i - sizeof(struct h_entry *) * (old_parent->num_children -
1)); i - 1));
old_parent->num_children--; old_parent->num_children--;
/* change the children size */ /* change the children size */
if (old_parent->num_children) { if (old_parent->num_children) {
@@ -686,9 +709,9 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
old_parent->children = NULL; old_parent->children = NULL;
} else { } else {
old_parent->children = old_parent->children =
(h_entry **) realloc(old_parent->children, (struct h_entry **)realloc(old_parent->children,
old_parent->num_children * old_parent->num_children *
sizeof(h_entry *)); sizeof(struct h_entry *));
if (old_parent->children == NULL) { if (old_parent->children == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -722,8 +745,9 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
if (!found) { if (!found) {
new_parent->num_children++; new_parent->num_children++;
new_parent->children = new_parent->children =
(h_entry **) realloc(new_parent->children, (struct h_entry **)realloc(new_parent->children,
new_parent->num_children * sizeof(h_entry *)); new_parent->num_children *
sizeof(struct h_entry *));
if (new_parent->children == 0) { if (new_parent->children == 0) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return NULL; return NULL;
@@ -738,10 +762,10 @@ static h_entry *folder_tree_allocate_entry(folder_tree * tree, const char *key,
* When adding an existing key, the old key is overwritten. * When adding an existing key, the old key is overwritten.
* Return the inserted or updated key * Return the inserted or updated key
*/ */
static h_entry *folder_tree_add_file(folder_tree * tree, mffile * file, static struct h_entry *folder_tree_add_file(folder_tree * tree, mffile * file,
h_entry * parent) struct h_entry *parent)
{ {
h_entry *entry; struct h_entry *entry;
const char *key; const char *key;
if (tree == NULL) { if (tree == NULL) {
@@ -770,22 +794,23 @@ static h_entry *folder_tree_add_file(folder_tree * tree, mffile * file,
entry->ctime = file_get_created(file); entry->ctime = file_get_created(file);
entry->fsize = file_get_size(file); entry->fsize = file_get_size(file);
/* mark this h_entry as a file if its atime is not set yet */ /* mark this h_entry struct as a file if its atime is not set yet */
if (entry->atime == 0) if (entry->atime == 0)
entry->atime = 1; entry->atime = 1;
return entry; return entry;
} }
/* given an mffolder, add its information to a new h_entry, or update an /* given an mffolder, add its information to a new h_entry struct, or update an
* existing h_entry in the hashtable * existing h_entry struct in the hashtable
* *
* returns the added or updated h_entry * returns a pointer to the added or updated h_entry struct
*/ */
static h_entry *folder_tree_add_folder(folder_tree * tree, mffolder * folder, static struct h_entry *folder_tree_add_folder(folder_tree * tree,
h_entry * parent) mffolder * folder,
struct h_entry *parent)
{ {
h_entry *entry; struct h_entry *entry;
const char *key; const char *key;
const char *name; const char *name;
@@ -853,7 +878,8 @@ static void folder_tree_remove(folder_tree * tree, const char *key)
free(tree->buckets[bucket_id][i]); free(tree->buckets[bucket_id][i]);
/* move the items on the right one place to the left */ /* move the items on the right one place to the left */
memmove(tree->buckets[bucket_id][i], tree->buckets[bucket_id][i + 1], memmove(tree->buckets[bucket_id][i], tree->buckets[bucket_id][i + 1],
sizeof(h_entry *) * (tree->bucket_lens[bucket_id] - i - 1)); sizeof(struct h_entry *) * (tree->bucket_lens[bucket_id] - i -
1));
/* change bucket size */ /* change bucket size */
tree->bucket_lens[bucket_id]--; tree->bucket_lens[bucket_id]--;
if (tree->bucket_lens[bucket_id] == 0) { if (tree->bucket_lens[bucket_id] == 0) {
@@ -862,7 +888,7 @@ static void folder_tree_remove(folder_tree * tree, const char *key)
} else { } else {
tree->buckets[bucket_id] = tree->buckets[bucket_id] =
realloc(tree->buckets[bucket_id], realloc(tree->buckets[bucket_id],
sizeof(h_entry) * tree->bucket_lens[bucket_id]); sizeof(struct h_entry) * tree->bucket_lens[bucket_id]);
if (tree->buckets[bucket_id] == NULL) { if (tree->buckets[bucket_id] == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return; return;
@@ -872,17 +898,19 @@ static void folder_tree_remove(folder_tree * tree, const char *key)
} }
/* /*
* check if a h_entry is the parent of another * check if a h_entry struct is the parent of another
* *
* this checks only pointer equivalence and does not compare the key for * this checks only pointer equivalence and does not compare the key for
* better performance * better performance
* *
* thus, this function relies on the fact that only one h_entry per key exists * thus, this function relies on the fact that only one h_entry struct per key
* exists
* *
* This function does not use the parent member of the child. If you want to * This function does not use the parent member of the child. If you want to
* rely on that, then use it directly. * rely on that, then use it directly.
*/ */
static bool folder_tree_is_parent_of(h_entry * parent, h_entry * child) static bool folder_tree_is_parent_of(struct h_entry *parent,
struct h_entry *child)
{ {
uint64_t i; uint64_t i;
bool found; bool found;
@@ -899,19 +927,19 @@ static bool folder_tree_is_parent_of(h_entry * parent, h_entry * child)
} }
/* /*
* given a h_entry, this function gets the remote content of that folder and * given a h_entry struct of a folder, this function gets the remote content
* fills its children * of that folder and fills its children
* *
* it then recurses for each child that is a directory and does the same in a * it then recurses for each child that is a directory and does the same in a
* full remote directory walk * full remote directory walk
*/ */
static int folder_tree_rebuild_helper(folder_tree * tree, mfconn * conn, static int folder_tree_rebuild_helper(folder_tree * tree, mfconn * conn,
h_entry * curr_entry, bool recurse) struct h_entry *curr_entry, bool recurse)
{ {
int retval; int retval;
mffolder **folder_result; mffolder **folder_result;
mffile **file_result; mffile **file_result;
h_entry *entry; struct h_entry *entry;
int i; int i;
const char *key; const char *key;
bool found; bool found;
@@ -956,9 +984,9 @@ static int folder_tree_rebuild_helper(folder_tree * tree, mfconn * conn,
if (folder_tree_lookup_key(tree, key) != NULL) { if (folder_tree_lookup_key(tree, key) != NULL) {
curr_entry->num_children++; curr_entry->num_children++;
curr_entry->children = curr_entry->children =
(h_entry **) realloc(curr_entry->children, (struct h_entry **)realloc(curr_entry->children,
curr_entry->num_children * curr_entry->num_children *
sizeof(h_entry *)); sizeof(struct h_entry *));
if (curr_entry->children == NULL) { if (curr_entry->children == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return -1; return -1;
@@ -1011,9 +1039,9 @@ static int folder_tree_rebuild_helper(folder_tree * tree, mfconn * conn,
if (folder_tree_lookup_key(tree, key) != NULL) { if (folder_tree_lookup_key(tree, key) != NULL) {
curr_entry->num_children++; curr_entry->num_children++;
curr_entry->children = curr_entry->children =
(h_entry **) realloc(curr_entry->children, (struct h_entry **)realloc(curr_entry->children,
curr_entry->num_children * curr_entry->num_children *
sizeof(h_entry *)); sizeof(struct h_entry *));
if (curr_entry->children == NULL) { if (curr_entry->children == NULL) {
fprintf(stderr, "realloc failed\n"); fprintf(stderr, "realloc failed\n");
return -1; return -1;
@@ -1045,7 +1073,7 @@ static int folder_tree_update_file_info(folder_tree * tree, mfconn * conn,
{ {
mffile *file; mffile *file;
int retval; int retval;
h_entry *parent; struct h_entry *parent;
file = file_alloc(); file = file_alloc();
@@ -1075,15 +1103,16 @@ static int folder_tree_update_file_info(folder_tree * tree, mfconn * conn,
/* /*
* update the fields of a folder without checking its children * update the fields of a folder without checking its children
* *
* we identify the folder to update by its key instead of its h_entry because * we identify the folder to update by its key instead of its h_entry struct
* this function is to fill the h_entry in the first place * pointer because this function is to fill the h_entry struct in the first
* place
*/ */
static int folder_tree_update_folder_info(folder_tree * tree, mfconn * conn, static int folder_tree_update_folder_info(folder_tree * tree, mfconn * conn,
char *key) char *key)
{ {
mffolder *folder; mffolder *folder;
int retval; int retval;
h_entry *parent; struct h_entry *parent;
if (key != NULL && strcmp(key, "trash")) { if (key != NULL && strcmp(key, "trash")) {
fprintf(stderr, "cannot get folder info of trash\n"); fprintf(stderr, "cannot get folder info of trash\n");
@@ -1126,7 +1155,7 @@ void folder_tree_update(folder_tree * tree, mfconn * conn)
uint64_t i; uint64_t i;
struct mfconn_device_change *changes; struct mfconn_device_change *changes;
int retval; int retval;
h_entry *tmp_entry; struct h_entry *tmp_entry;
mfconn_api_device_get_status(conn, &revision_remote); mfconn_api_device_get_status(conn, &revision_remote);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
@@ -1223,17 +1252,18 @@ void folder_tree_update(folder_tree * tree, mfconn * conn)
* situation should be rectified once the next device/get_changes is done. * situation should be rectified once the next device/get_changes is done.
* *
* Just remember that due to this it can happen that the revision of the * Just remember that due to this it can happen that the revision of the
* local tree is less than the highest revision of a h_entry it stores. * local tree is less than the highest revision of a h_entry struct it
* stores.
*/ */
/* now fix up any possible errors */ /* now fix up any possible errors */
/* clean the resulting folder_tree of any dangling objects */ /* clean the resulting folder_tree of any dangling objects */
fprintf(stderr, "tree before cleaning:\n"); fprintf(stderr, "tree before cleaning:\n");
folder_tree_debug(tree, NULL, 0); folder_tree_debug(tree);
folder_tree_housekeep(tree, conn); folder_tree_housekeep(tree, conn);
fprintf(stderr, "tree after cleaning:\n"); fprintf(stderr, "tree after cleaning:\n");
folder_tree_debug(tree, NULL, 0); folder_tree_debug(tree);
} }
/* /*
@@ -1380,7 +1410,8 @@ void folder_tree_housekeep(folder_tree * tree, mfconn * conn)
*/ */
} }
void folder_tree_debug(folder_tree * tree, h_entry * ent, int depth) void folder_tree_debug_helper(folder_tree * tree, struct h_entry *ent,
int depth)
{ {
uint64_t i; uint64_t i;
@@ -1394,7 +1425,7 @@ void folder_tree_debug(folder_tree * tree, h_entry * ent, int depth)
fprintf(stderr, "%*s d:%s k:%s p:%s\n", depth + 1, " ", fprintf(stderr, "%*s d:%s k:%s p:%s\n", depth + 1, " ",
ent->children[i]->name, ent->children[i]->key, ent->children[i]->name, ent->children[i]->key,
ent->children[i]->parent->key); ent->children[i]->parent->key);
folder_tree_debug(tree, ent->children[i], depth + 1); folder_tree_debug_helper(tree, ent->children[i], depth + 1);
} else { } else {
/* file */ /* file */
fprintf(stderr, "%*s f:%s k:%s p:%s\n", depth + 1, " ", fprintf(stderr, "%*s f:%s k:%s p:%s\n", depth + 1, " ",
@@ -1403,3 +1434,8 @@ void folder_tree_debug(folder_tree * tree, h_entry * ent, int depth)
} }
} }
} }
void folder_tree_debug(folder_tree * tree)
{
folder_tree_debug_helper(tree, NULL, 0);
}

View File

@@ -21,11 +21,11 @@
#include <fuse/fuse.h> #include <fuse/fuse.h>
#include <stdio.h> #include <stdio.h>
#include <stdbool.h>
#include "../mfapi/mfconn.h" #include "../mfapi/mfconn.h"
typedef struct folder_tree folder_tree; typedef struct folder_tree folder_tree;
typedef struct h_entry h_entry;
folder_tree *folder_tree_create(void); folder_tree *folder_tree_create(void);
@@ -35,8 +35,7 @@ int folder_tree_rebuild(folder_tree * tree, mfconn * conn);
void folder_tree_housekeep(folder_tree * tree, mfconn * conn); void folder_tree_housekeep(folder_tree * tree, mfconn * conn);
void folder_tree_debug(folder_tree * tree, h_entry * ent, void folder_tree_debug(folder_tree * tree);
int depth);
int folder_tree_getattr(folder_tree * tree, const char *path, int folder_tree_getattr(folder_tree * tree, const char *path,
struct stat *stbuf); struct stat *stbuf);
@@ -50,4 +49,6 @@ int folder_tree_store(folder_tree * tree, FILE * stream);
folder_tree *folder_tree_load(FILE * stream); folder_tree *folder_tree_load(FILE * stream);
bool folder_tree_path_exists(folder_tree * tree, const char *path);
#endif #endif

View File

@@ -219,7 +219,7 @@ int main(int argc, char *argv[])
//folder_tree_housekeep(tree); //folder_tree_housekeep(tree);
folder_tree_debug(tree, NULL, 0); folder_tree_debug(tree);
return fuse_main(args.argc, args.argv, &mediafirefs_oper, NULL); return fuse_main(args.argc, args.argv, &mediafirefs_oper, NULL);
} }