|
|
#include "fuse_node.h"
#include "khash.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdio.h> // for debugging
#define UNKNOWN_INO UINT64_MAX
#define ROOT_NODE_ID 0
#define ROOT_NODE_NAME "/"
typedef struct node_idname_t node_idname_t; struct node_idname_t { uint64_t id; const char *name; };
static khint_t idname_hash_func(const node_idname_t idname); static int idname_hash_equal(const node_idname_t idname0, const node_idname_t idname1);
KHASH_INIT(node,node_idname_t,fuse_node_t*,1,idname_hash_func,idname_hash_equal);
typedef struct fuse_node_hashtable_t fuse_node_hashtable_t; struct fuse_node_hashtable_t { kh_node_t *ht; uint64_t id; uint64_t generation; };
static inline khint_t idname_hash_func(const node_idname_t idname_) { if(idname_.name == NULL) return idname_.id; return (idname_.id ^ kh_str_hash_func(idname_.name)); }
static inline int idname_hash_equal(const node_idname_t idname0_, const node_idname_t idname1_) { return ((idname0_.id == idname1_.id) && ((idname0_.name == idname1_.name) || (strcmp(idname0_.name,idname1_.name) == 0))); }
static inline fuse_node_t* fuse_node_alloc(const uint64_t id_, const char *name_) { fuse_node_t *node;
node = (fuse_node_t*)calloc(1,sizeof(fuse_node_t));
node->id = id_; node->name = strdup(name_); node->ref_count = 1; node->lookup_count = 1;
return node; }
static inline void fuse_node_free(fuse_node_t *node_) { free(node_->name); free(node_); }
static inline uint64_t rand64() { uint64_t rv;
rv = rand(); rv <<= 32; rv |= rand();
return rv; }
static inline void node_hashtable_gen_unique_id(fuse_node_hashtable_t *ht_) { do { ht_->id++; if(ht_->id == 0) ht_->generation++; } while((ht_->id == 0) || (ht_->id == UNKNOWN_INO)); }
static inline void node_hashtable_put_root(fuse_node_hashtable_t *ht_) { int rv; khint_t k; fuse_node_t *root_node; const node_idname_t idname0 = {ROOT_NODE_ID,""}; const node_idname_t idname1 = {ROOT_NODE_ID,ROOT_NODE_NAME};
root_node = fuse_node_alloc(ROOT_NODE_ID,ROOT_NODE_NAME);
k = kh_put_node(ht_->ht,idname0,&rv); kh_value(ht_->ht,k) = root_node;
k = kh_put_node(ht_->ht,idname1,&rv); kh_value(ht_->ht,k) = root_node; }
static inline void node_hashtable_set_id_gen(fuse_node_hashtable_t *ht_, fuse_node_t *node_) { node_hashtable_gen_unique_id(ht_); node_->id = ht_->id; node_->generation = ht_->generation; }
fuse_node_hashtable_t* fuse_node_hashtable_init() { fuse_node_hashtable_t *ht;
ht = (fuse_node_hashtable_t*)calloc(sizeof(fuse_node_hashtable_t),1); if(ht == NULL) return NULL;
ht->ht = kh_init_node(); if(ht->ht == NULL) { free(ht); return NULL; }
srand(time(NULL)); ht->id = 0; ht->generation = rand64();
node_hashtable_put_root(ht);
return ht; }
fuse_node_t* fuse_node_hashtable_put(fuse_node_hashtable_t *ht_, const uint64_t parent_id_, const uint64_t child_id_, const char *child_name_) { int rv; khint_t k; fuse_node_t *child_node; const node_idname_t p_idname = {parent_id_,""}; const node_idname_t c0_idname = {child_id_,child_name_}; const node_idname_t c1_idname = {parent_id_,child_name_};
child_node = fuse_node_alloc(child_id_,child_name_);
k = kh_get_node(ht_->ht,p_idname); child_node->parent = kh_value(ht_->ht,k); child_node->parent->ref_count++;
k = kh_put_node(ht_->ht,c0_idname,&rv); kh_value(ht_->ht,k) = child_node;
k = kh_put_node(ht_->ht,c1_idname,&rv); kh_value(ht_->ht,k) = child_node;
return child_node; }
fuse_node_t* fuse_node_hashtable_get(fuse_node_hashtable_t *ht_, const uint64_t id_) { return fuse_node_hashtable_get_child(ht_,id_,""); }
fuse_node_t* fuse_node_hashtable_get_child(fuse_node_hashtable_t *ht_, const uint64_t parent_id_, const char *child_name_) { khint_t k; fuse_node_t *node; const node_idname_t idname = {parent_id_,child_name_};
k = kh_get_node(ht_->ht,idname); node = ((k != kh_end(ht_->ht)) ? kh_value(ht_->ht,k) : NULL);
return node; }
void fuse_node_hashtable_del(fuse_node_hashtable_t *ht_, fuse_node_t *node_) {
}
|