You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
4.5 KiB

  1. #include "fuse_node.h"
  2. #include "khash.h"
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include <stdio.h> // for debugging
  7. #define UNKNOWN_INO UINT64_MAX
  8. #define ROOT_NODE_ID 0
  9. #define ROOT_NODE_NAME "/"
  10. typedef struct node_idname_t node_idname_t;
  11. struct node_idname_t
  12. {
  13. uint64_t id;
  14. const char *name;
  15. };
  16. static khint_t idname_hash_func(const node_idname_t idname);
  17. static int idname_hash_equal(const node_idname_t idname0, const node_idname_t idname1);
  18. KHASH_INIT(node,node_idname_t,fuse_node_t*,1,idname_hash_func,idname_hash_equal);
  19. typedef struct fuse_node_hashtable_t fuse_node_hashtable_t;
  20. struct fuse_node_hashtable_t
  21. {
  22. kh_node_t *ht;
  23. uint64_t id;
  24. uint64_t generation;
  25. };
  26. static
  27. inline
  28. khint_t
  29. idname_hash_func(const node_idname_t idname_)
  30. {
  31. if(idname_.name == NULL)
  32. return idname_.id;
  33. return (idname_.id ^ kh_str_hash_func(idname_.name));
  34. }
  35. static
  36. inline
  37. int
  38. idname_hash_equal(const node_idname_t idname0_,
  39. const node_idname_t idname1_)
  40. {
  41. return ((idname0_.id == idname1_.id) &&
  42. ((idname0_.name == idname1_.name) ||
  43. (strcmp(idname0_.name,idname1_.name) == 0)));
  44. }
  45. static
  46. inline
  47. fuse_node_t*
  48. fuse_node_alloc(const uint64_t id_,
  49. const char *name_)
  50. {
  51. fuse_node_t *node;
  52. node = (fuse_node_t*)calloc(1,sizeof(fuse_node_t));
  53. node->id = id_;
  54. node->name = strdup(name_);
  55. node->ref_count = 1;
  56. node->lookup_count = 1;
  57. return node;
  58. }
  59. static
  60. inline
  61. void
  62. fuse_node_free(fuse_node_t *node_)
  63. {
  64. free(node_->name);
  65. free(node_);
  66. }
  67. static
  68. inline
  69. uint64_t
  70. rand64()
  71. {
  72. uint64_t rv;
  73. rv = rand();
  74. rv <<= 32;
  75. rv |= rand();
  76. return rv;
  77. }
  78. static
  79. inline
  80. void
  81. node_hashtable_gen_unique_id(fuse_node_hashtable_t *ht_)
  82. {
  83. do
  84. {
  85. ht_->id++;
  86. if(ht_->id == 0)
  87. ht_->generation++;
  88. }
  89. while((ht_->id == 0) || (ht_->id == UNKNOWN_INO));
  90. }
  91. static
  92. inline
  93. void
  94. node_hashtable_put_root(fuse_node_hashtable_t *ht_)
  95. {
  96. int rv;
  97. khint_t k;
  98. fuse_node_t *root_node;
  99. const node_idname_t idname0 = {ROOT_NODE_ID,""};
  100. const node_idname_t idname1 = {ROOT_NODE_ID,ROOT_NODE_NAME};
  101. root_node = fuse_node_alloc(ROOT_NODE_ID,ROOT_NODE_NAME);
  102. k = kh_put_node(ht_->ht,idname0,&rv);
  103. kh_value(ht_->ht,k) = root_node;
  104. k = kh_put_node(ht_->ht,idname1,&rv);
  105. kh_value(ht_->ht,k) = root_node;
  106. }
  107. static
  108. inline
  109. void
  110. node_hashtable_set_id_gen(fuse_node_hashtable_t *ht_,
  111. fuse_node_t *node_)
  112. {
  113. node_hashtable_gen_unique_id(ht_);
  114. node_->id = ht_->id;
  115. node_->generation = ht_->generation;
  116. }
  117. fuse_node_hashtable_t*
  118. fuse_node_hashtable_init()
  119. {
  120. fuse_node_hashtable_t *ht;
  121. ht = (fuse_node_hashtable_t*)calloc(sizeof(fuse_node_hashtable_t),1);
  122. if(ht == NULL)
  123. return NULL;
  124. ht->ht = kh_init_node();
  125. if(ht->ht == NULL)
  126. {
  127. free(ht);
  128. return NULL;
  129. }
  130. srand(time(NULL));
  131. ht->id = 0;
  132. ht->generation = rand64();
  133. node_hashtable_put_root(ht);
  134. return ht;
  135. }
  136. fuse_node_t*
  137. fuse_node_hashtable_put(fuse_node_hashtable_t *ht_,
  138. const uint64_t parent_id_,
  139. const uint64_t child_id_,
  140. const char *child_name_)
  141. {
  142. int rv;
  143. khint_t k;
  144. fuse_node_t *child_node;
  145. const node_idname_t p_idname = {parent_id_,""};
  146. const node_idname_t c0_idname = {child_id_,child_name_};
  147. const node_idname_t c1_idname = {parent_id_,child_name_};
  148. child_node = fuse_node_alloc(child_id_,child_name_);
  149. k = kh_get_node(ht_->ht,p_idname);
  150. child_node->parent = kh_value(ht_->ht,k);
  151. child_node->parent->ref_count++;
  152. k = kh_put_node(ht_->ht,c0_idname,&rv);
  153. kh_value(ht_->ht,k) = child_node;
  154. k = kh_put_node(ht_->ht,c1_idname,&rv);
  155. kh_value(ht_->ht,k) = child_node;
  156. return child_node;
  157. }
  158. fuse_node_t*
  159. fuse_node_hashtable_get(fuse_node_hashtable_t *ht_,
  160. const uint64_t id_)
  161. {
  162. return fuse_node_hashtable_get_child(ht_,id_,"");
  163. }
  164. fuse_node_t*
  165. fuse_node_hashtable_get_child(fuse_node_hashtable_t *ht_,
  166. const uint64_t parent_id_,
  167. const char *child_name_)
  168. {
  169. khint_t k;
  170. fuse_node_t *node;
  171. const node_idname_t idname = {parent_id_,child_name_};
  172. k = kh_get_node(ht_->ht,idname);
  173. node = ((k != kh_end(ht_->ht)) ?
  174. kh_value(ht_->ht,k) :
  175. NULL);
  176. return node;
  177. }
  178. void
  179. fuse_node_hashtable_del(fuse_node_hashtable_t *ht_,
  180. fuse_node_t *node_)
  181. {
  182. }