hashset.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. /*
  2. *
  3. * Copyright (c) 2011, Jue Ruan <ruanjue@gmail.com>
  4. *
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef __HASH_SET_RJ
  20. #define __HASH_SET_RJ
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdint.h>
  25. #include <math.h>
  26. #include "mem_share.h"
  27. #include "bitvec.h"
  28. static const uint64_t sys_prime_list[61] = {
  29. 0x7LLU, 0xfLLU, 0x1fLLU, 0x43LLU, 0x89LLU,
  30. 0x115LLU, 0x22dLLU, 0x45dLLU, 0x8bdLLU, 0x1181LLU,
  31. 0x2303LLU, 0x4609LLU, 0x8c17LLU, 0x1183dLLU, 0x2307bLLU,
  32. 0x460fdLLU, 0x8c201LLU, 0x118411LLU, 0x230833LLU, 0x461069LLU,
  33. 0x8c20e1LLU, 0x11841cbLLU, 0x2308397LLU, 0x461075bLLU, 0x8c20ecbLLU,
  34. 0x11841da5LLU, 0x23083b61LLU, 0x461076c7LLU, 0x8c20ed91LLU, 0x11841db31LLU,
  35. 0x23083b673LLU, 0x461076d1bLLU, 0x8c20eda41LLU, 0x11841db48dLLU, 0x23083b6937LLU,
  36. 0x461076d27fLLU, 0x8c20eda50dLLU, 0x11841db4a59LLU, 0x23083b694ebLLU, 0x461076d29f1LLU,
  37. 0x8c20eda5441LLU, 0x11841db4a887LLU, 0x23083b69511fLLU, 0x461076d2a2c1LLU, 0x8c20eda54591LLU,
  38. 0x11841db4a8b55LLU, 0x23083b69516c1LLU, 0x461076d2a2da5LLU, 0x8c20eda545b55LLU, 0x11841db4a8b6b5LLU,
  39. 0x23083b69516d91LLU, 0x461076d2a2db3bLLU, 0x8c20eda545b69dLLU, 0x11841db4a8b6d5dLLU, 0x23083b69516daf5LLU,
  40. 0x461076d2a2db5edLLU, 0x8c20eda545b6c5fLLU, 0x11841db4a8b6d8ebLLU, 0x23083b69516db1ffLLU, 0x461076d2a2db643fLLU,
  41. 0x8c20eda545b6c8f3LLU
  42. };
  43. static inline uint64_t _rj_hashset_find_prime(uint64_t n){
  44. uint32_t i;
  45. i = 0;
  46. while(i < 60 && n > sys_prime_list[i]) i ++;
  47. return sys_prime_list[i];
  48. }
  49. #define init_hashset_macro(hash_type, hash_ele_type) \
  50. typedef struct { hash_ele_type *array; BitVec *ones, *dels; size_t e_size; size_t ocp; size_t size; size_t count; size_t max; float load_factor; size_t iter_ptr; void *userdata; } hash_type; \
  51. static inline size_t hash_type##_obj_desc_cnt(void *obj, int idx){ \
  52. hash_type *set; \
  53. set = (hash_type*)obj; \
  54. if(set->dels){ \
  55. switch(idx){ \
  56. case 0: return ((hash_type*)obj)->size * sizeof(hash_ele_type); \
  57. default: return 1; \
  58. } \
  59. } else { \
  60. switch(idx){ \
  61. case 0: return ((hash_type*)obj)->count * sizeof(hash_ele_type); \
  62. case 1: return 1; \
  63. default: return 0; \
  64. } \
  65. } \
  66. } \
  67. static const obj_desc_t hash_type##_obj_desc = {TOSTR(_hashset_##hash_type), sizeof(hash_type), 3, {1, 1, 1}, {offsetof(hash_type, array), offsetof(hash_type, ones), offsetof(hash_type, dels)}, {(obj_desc_t*)&OBJ_DESC_DATA, (obj_desc_t*)&bitvec_obj_desc, (obj_desc_t*)&bitvec_obj_desc}, hash_type##_obj_desc_cnt, NULL}; \
  68. static inline int hash_type##_is_prime(uint64_t num){ \
  69. uint64_t i, max; \
  70. if(num < 4) return 1; \
  71. if(num % 2 == 0) return 0; \
  72. max = (uint64_t)sqrt((double)num); \
  73. for(i=3;i<max;i+=2){ if(num % i == 0) return 0; } \
  74. return 1; \
  75. } \
  76. static inline uint64_t hash_type##_find_next_prime(uint64_t num){ \
  77. if(num % 2 == 0) num ++; \
  78. while(1){ if(hash_type##_is_prime(num)) return num; num += 2; } \
  79. } \
  80. static inline hash_type* init2_##hash_type(uint32_t size, float factor){ \
  81. hash_type *set; \
  82. set = (hash_type*)calloc(1, sizeof(hash_type)); \
  83. set->e_size = sizeof(hash_ele_type); \
  84. set->size = _rj_hashset_find_prime(size); \
  85. set->count = 0; \
  86. set->ocp = 0; \
  87. set->load_factor = factor; \
  88. set->max = set->size * set->load_factor; \
  89. set->iter_ptr = 0; \
  90. set->array = calloc(set->size, set->e_size); \
  91. set->ones = init_bitvec(set->size); \
  92. set->dels = init_bitvec(set->size); \
  93. set->userdata = NULL; \
  94. return set; \
  95. } \
  96. static inline void set_userdata_##hash_type(hash_type *set, void *userdata){ set->userdata = userdata; } \
  97. static inline hash_type* init_##hash_type(uint32_t size){ return init2_##hash_type(size, 0.67f); }
  98. #define get_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal, hash_val_type, hash_ele2val) \
  99. static inline hash_ele_type* get_##hash_type(hash_type *set, hash_key_type key){\
  100. hash_ele_type *e; \
  101. size_t hc, hi; \
  102. hc = hash_key_code(key) % set->size; \
  103. if(set->dels){ \
  104. while(1){ \
  105. if(get_bitvec(set->ones, hc) == 0){ \
  106. return NULL; \
  107. } else if(get_bitvec(set->dels, hc)){ \
  108. } else { \
  109. e = ((hash_ele_type*)set->array) + hc; \
  110. if(hash_key_equal((key), (*e))) return e; \
  111. } \
  112. hc = (hc + 1) % set->size; \
  113. } \
  114. } else { \
  115. hi = MAX_U8; \
  116. while(1){ \
  117. if(get_bitvec(set->ones, hc)){ \
  118. if(hi == MAX_U8){ \
  119. hi = rank_bitvec(set->ones, hc); \
  120. } \
  121. e = ((hash_ele_type*)set->array) + hi; \
  122. if(hash_key_equal((key), (*e))) return e; \
  123. } else { \
  124. return NULL; \
  125. } \
  126. hc ++; \
  127. hi ++; \
  128. } \
  129. } \
  130. return NULL; \
  131. } \
  132. static inline size_t offset_##hash_type(hash_type *set, hash_ele_type *ptr){ \
  133. return ptr - set->array; \
  134. } \
  135. static inline hash_ele_type* ref_##hash_type(hash_type *set, size_t off){ return set->array + off; } \
  136. static inline hash_val_type getval_##hash_type(hash_type *set, hash_key_type key){ \
  137. hash_ele_type *e; \
  138. e = get_##hash_type(set, key); \
  139. return hash_ele2val(e); \
  140. }
  141. #define prepare_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal) \
  142. static inline void encap_##hash_type(hash_type *set, size_t num); \
  143. static inline hash_ele_type* prepare_##hash_type(hash_type *set, hash_key_type key, int *exists){\
  144. hash_ele_type *e; \
  145. size_t hc, d; \
  146. if(set->dels == NULL){ *exists = 0; return NULL; } \
  147. encap_##hash_type(set, 1); \
  148. hc = hash_key_code((key)) % set->size; \
  149. d = set->size; \
  150. while(1){ \
  151. if(get_bitvec(set->ones, hc) == 0){ \
  152. if(d == set->size){ \
  153. one_bitvec(set->ones, hc); \
  154. set->ocp ++; \
  155. } else { \
  156. hc = d; \
  157. zero_bitvec(set->dels, hc); \
  158. } \
  159. if(exists) *exists = 0; \
  160. set->count ++; \
  161. e = ((hash_ele_type*)set->array) + hc; \
  162. return e; \
  163. } else if(get_bitvec(set->dels, hc)){ \
  164. if(d == set->size) d = hc; \
  165. } else { \
  166. e = ((hash_ele_type*)set->array) + hc; \
  167. if(hash_key_equal((key), (*e))){ \
  168. if(exists) *exists = 1; \
  169. return e; \
  170. } \
  171. } \
  172. hc = (hc + 1) % set->size; \
  173. } \
  174. return NULL; \
  175. }
  176. #define exists_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal) \
  177. static inline int exists_##hash_type(hash_type *set, hash_key_type key){ \
  178. return get_##hash_type(set, key) != NULL; \
  179. }
  180. #define add_hashset_macro(hash_type, hash_ele_type, hash_code_macro, hash_equal_macro) \
  181. static inline hash_ele_type* add_##hash_type(hash_type *set, hash_ele_type ele){ \
  182. hash_ele_type *e; \
  183. size_t d, hc; \
  184. if(set->dels == NULL) return NULL; \
  185. hc = hash_code_macro(ele) % set->size; \
  186. d = set->size; \
  187. do { \
  188. if(get_bitvec(set->ones, hc) == 0){ \
  189. if(d == set->size){ \
  190. one_bitvec(set->ones, hc); \
  191. set->ocp ++; \
  192. } else { \
  193. hc = d; \
  194. zero_bitvec(set->dels, hc); \
  195. } \
  196. set->count ++; \
  197. e = ((hash_ele_type*)set->array) + hc; \
  198. *e = ele; \
  199. return e; \
  200. } else if(get_bitvec(set->dels, hc)){ \
  201. if(d == set->size) d = hc; \
  202. } else { \
  203. e = ((hash_ele_type*)set->array) + hc; \
  204. if(hash_equal_macro((ele), (*e))){ \
  205. *e = ele; \
  206. return e; \
  207. } \
  208. } \
  209. hc = (hc + 1) % set->size; \
  210. } while(1); \
  211. return NULL; \
  212. }
  213. #define put_hashset_macro(hash_type, hash_ele_type) \
  214. static inline hash_ele_type* put_##hash_type(hash_type *set, hash_ele_type ele){ \
  215. encap_##hash_type(set, 1); \
  216. return add_##hash_type(set, ele); \
  217. }
  218. #define remove_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal) \
  219. static inline int delete_##hash_type(hash_type *set, hash_ele_type *ele){ \
  220. size_t hc; \
  221. if(set->dels == NULL) return 0; \
  222. hc = offset_##hash_type(set, ele); \
  223. if(get_bitvec(set->ones, (hc + 1) % set->size) == 0){ \
  224. zero_bitvec(set->ones, hc); \
  225. set->ocp --; \
  226. } else { \
  227. one_bitvec(set->dels, hc); \
  228. } \
  229. set->count --; \
  230. return 1; \
  231. } \
  232. \
  233. static inline int remove_##hash_type(hash_type *set, hash_key_type key){ \
  234. hash_ele_type *e; \
  235. size_t hc; \
  236. if(set->dels == NULL) return 0; \
  237. hc = hash_key_code(key) % set->size; \
  238. while(1){ \
  239. if(get_bitvec(set->ones, hc) == 0){ \
  240. return 0; \
  241. } else if(get_bitvec(set->dels, hc)){ \
  242. } else { \
  243. e = ((hash_ele_type*)set->array) + hc; \
  244. if(hash_key_equal((key), (*e))){ \
  245. if(get_bitvec(set->ones, (hc + 1) % set->size) == 0){ \
  246. zero_bitvec(set->ones, hc); \
  247. set->ocp --; \
  248. } else { \
  249. one_bitvec(set->dels, hc); \
  250. } \
  251. set->count --; \
  252. return 1; \
  253. } \
  254. } \
  255. hc = (hc + 1) % set->size; \
  256. } \
  257. return 0; \
  258. }
  259. #define reset_iter_hashset_macro(hash_type) static inline void reset_iter_##hash_type(hash_type *set){ set->iter_ptr = 0; }
  260. #define ref_iter_hashset_macro(hash_type, hash_ele_type) \
  261. static inline hash_ele_type* ref_iter2_##hash_type(hash_type *set, size_t *iter_ptr){ \
  262. if(set->dels){ \
  263. while(((*iter_ptr) = next_one_bitvec(set->ones, (*iter_ptr))) < set->size){ \
  264. if(get_bitvec(set->dels, (*iter_ptr))){ \
  265. (*iter_ptr) ++; \
  266. } else { \
  267. return (((hash_ele_type*)set->array) + (*iter_ptr)++); \
  268. } \
  269. } \
  270. } else { \
  271. while((*iter_ptr) < set->count){ \
  272. return (((hash_ele_type*)set->array) + (*iter_ptr)++); \
  273. } \
  274. } \
  275. return NULL; \
  276. } \
  277. static inline hash_ele_type* ref_iter_##hash_type(hash_type *set){ \
  278. return ref_iter2_##hash_type(set, &(set->iter_ptr)); \
  279. }
  280. #define count_hashset_macro(hash_type) static inline int64_t count_##hash_type(hash_type *set){ return set->count; }
  281. #define freeze_hashset_macro(hash_type, hash_ele_type, hash_code_macro) \
  282. static inline int freeze_##hash_type(hash_type *set, float load_factor){ \
  283. size_t *hvs, i, j, sz; \
  284. if(set->dels == NULL) return 0; \
  285. if(load_factor == 0) load_factor = set->load_factor; \
  286. sz = set->count / load_factor; \
  287. sz = _rj_hashset_find_prime(sz); \
  288. for(i=j=0;(i=next_one_bitvec(set->ones, i))<set->size;i++){ \
  289. if(get_bitvec(set->dels, i)) continue; \
  290. if(j < i){ \
  291. set->array[j] = set->array[i]; \
  292. } \
  293. j ++; \
  294. } \
  295. free_bitvec(set->ones); \
  296. set->ones = NULL; \
  297. free_bitvec(set->dels); \
  298. set->dels = NULL; \
  299. set->size = sz; \
  300. set->load_factor = load_factor; \
  301. set->ocp = set->count; \
  302. set->array = realloc(set->array, (set->count + 1) * sizeof(hash_ele_type)); \
  303. memset(set->array + set->count, 0, sizeof(hash_ele_type)); \
  304. hvs = malloc(set->count * sizeof(size_t)); \
  305. for(i=0;i<set->count;i++){ \
  306. hvs[i] = hash_code_macro(set->array[i]) % sz; \
  307. } \
  308. sort_array_adv(set->count, hvs[a] > hvs[b], swap_var(hvs[a], hvs[b]); swap_var(set->array[a], set->array[b])); \
  309. for(i=j=0;i<set->count;i++){ \
  310. if(j < hvs[i]) j = hvs[i]; \
  311. j ++; \
  312. } \
  313. if(j < sz) j = sz; \
  314. set->ones = init_bitvec(j + 1); \
  315. for(i=j=0;i<set->count;i++){ \
  316. if(j < hvs[i]) j = hvs[i]; \
  317. one_bitvec(set->ones, j); \
  318. j ++; \
  319. } \
  320. free(hvs); \
  321. index_bitvec(set->ones); \
  322. return 1; \
  323. }
  324. #define clear_hashset_macro(hash_type) \
  325. static inline void clear_##hash_type(hash_type *set){ \
  326. if(set->dels == NULL){ \
  327. return; \
  328. } \
  329. zeros_bitvec(set->ones); \
  330. zeros_bitvec(set->dels); \
  331. set->count = 0; \
  332. set->ocp = 0; \
  333. set->iter_ptr = 0; \
  334. }
  335. #define free_hashset_macro(hash_type) \
  336. static inline void free_##hash_type(hash_type *set){ \
  337. free(set->array); \
  338. if(set->ones) free_bitvec(set->ones); \
  339. if(set->dels) free_bitvec(set->dels); \
  340. free(set); \
  341. }
  342. #define encap_hashset_macro(hash_type, hash_ele_type, hash_code_macro) \
  343. static inline void encap_##hash_type(hash_type *set, size_t num){ \
  344. BitVec *ones, *dels; \
  345. size_t i, n, hc; \
  346. hash_ele_type key; \
  347. if(set->dels == NULL) return; \
  348. if(set->ocp + num <= set->max) return; \
  349. n = set->size; \
  350. do{ n = _rj_hashset_find_prime(n * 2); } while(n * set->load_factor < set->count + num); \
  351. set->array = realloc(set->array, n * set->e_size); \
  352. if(set->array == NULL){ \
  353. fprintf(stderr, "-- Out of memory --\n"); \
  354. print_backtrace(stderr, 20); \
  355. exit(1); \
  356. } \
  357. ones = init_bitvec(n); \
  358. dels = init_bitvec(n); \
  359. set->ocp = set->count; \
  360. set->max = n * set->load_factor; \
  361. for(i=0;(i=next_one_bitvec(set->ones, i))<set->size;i++){ \
  362. if(get_bitvec(set->dels, i)) continue; \
  363. key = ((hash_ele_type*)set->array)[i]; \
  364. one_bitvec(set->dels, i); \
  365. while(1){ \
  366. hc = hash_code_macro(key) % n; \
  367. while(get_bitvec(ones, hc)){ \
  368. hc = (hc + 1) % n; \
  369. } \
  370. one_bitvec(ones, hc); \
  371. if(hc < set->size && get_bitvec(set->ones, hc) && get_bitvec(set->dels, hc) == 0){ \
  372. swap_var(key, ((hash_ele_type*)set->array)[hc]); \
  373. one_bitvec(set->dels, hc); \
  374. } else { \
  375. ((hash_ele_type*)set->array)[hc] = key; \
  376. break; \
  377. } \
  378. } \
  379. } \
  380. swap_var(ones, set->ones); \
  381. swap_var(dels, set->dels); \
  382. set->size = n; \
  383. free_bitvec(ones); \
  384. free_bitvec(dels); \
  385. } \
  386. static inline size_t offsetof_##hash_type(hash_type *set, hash_ele_type *ptr){ return ptr - set->array; } \
  387. #define ITSELF(E) (E)
  388. #define NUM_EQUALS(E1, E2) ((E1) == (E2))
  389. #define define_hashtable(hash_type, hash_ele_type, hash_code_macro, hash_equal_macro, hash_key_type, hash_key_code, hash_key_equal, hash_val_type, hash_ele2val) \
  390. init_hashset_macro(hash_type, hash_ele_type); \
  391. get_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal, hash_val_type, hash_ele2val); \
  392. prepare_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal); \
  393. exists_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal); \
  394. add_hashset_macro(hash_type, hash_ele_type, hash_code_macro, hash_equal_macro); \
  395. put_hashset_macro(hash_type, hash_ele_type); \
  396. remove_hashset_macro(hash_type, hash_ele_type, hash_key_type, hash_key_code, hash_key_equal); \
  397. ref_iter_hashset_macro(hash_type, hash_ele_type); \
  398. reset_iter_hashset_macro(hash_type); \
  399. count_hashset_macro(hash_type); \
  400. clear_hashset_macro(hash_type); \
  401. freeze_hashset_macro(hash_type, hash_ele_type, hash_code_macro); \
  402. free_hashset_macro(hash_type); \
  403. encap_hashset_macro(hash_type, hash_ele_type, hash_code_macro);
  404. #define define_hashset(hash_type, hash_ele_type, hash_code_macro, hash_equal_macro) define_hashtable(hash_type, hash_ele_type, hash_code_macro, hash_equal_macro, hash_ele_type, hash_code_macro, hash_equal_macro, hash_ele_type*, ITSELF)
  405. /* ------------------ Useful functions ------------------------------------- */
  406. static inline uint32_t __lh3_Jenkins_hash_int(uint32_t key){
  407. key += (key << 12);
  408. key ^= (key >> 22);
  409. key += (key << 4);
  410. key ^= (key >> 9);
  411. key += (key << 10);
  412. key ^= (key >> 2);
  413. key += (key << 7);
  414. key ^= (key >> 12);
  415. return key;
  416. }
  417. static inline uint64_t __lh3_Jenkins_hash_64(uint64_t key){
  418. key += ~(key << 32);
  419. key ^= (key >> 22);
  420. key += ~(key << 13);
  421. key ^= (key >> 8);
  422. key += (key << 3);
  423. key ^= (key >> 15);
  424. key += ~(key << 27);
  425. key ^= (key >> 31);
  426. return key;
  427. }
  428. static inline uint32_t jenkins_one_at_a_time_hash(char *key, size_t len){
  429. uint32_t hash, i;
  430. for(hash = i = 0; i < len; ++i){
  431. hash += key[i];
  432. hash += (hash << 10);
  433. hash ^= (hash >> 6);
  434. }
  435. hash += (hash << 3);
  436. hash ^= (hash >> 11);
  437. hash += (hash << 15);
  438. return hash;
  439. }
  440. static inline u8i invertible_hashcode(u8i x, int p){
  441. u8i m;
  442. m = 0xFFFFFFFFFFFFFFFFLLU >> (64 - p);
  443. x = ((~x) + (x << 21)) & m;
  444. x = x ^ (x >> 24);
  445. x = (x + (x << 3) + (x << 8)) & m;
  446. x = x ^ (x >> 14);
  447. x = (x + (x << 2) + (x << 4)) & m;
  448. x = x ^ (x >> 28);
  449. x = (x + (x << 31)) & m;
  450. return x;
  451. }
  452. static inline uint64_t hash64shift(uint64_t key){
  453. key = (~key) + (key << 21); // key = (key << 21) - key - 1;
  454. key = key ^ (key >> 24);
  455. key = (key + (key << 3)) + (key << 8); // key * 265
  456. key = key ^ (key >> 14);
  457. key = (key + (key << 2)) + (key << 4); // key * 21
  458. key = key ^ (key >> 28);
  459. key = key + (key << 31);
  460. return key;
  461. }
  462. static inline uint64_t MurmurHash64A(const void * key, int len, uint32_t seed){
  463. const uint64_t m = 0xc6a4a7935bd1e995LLU;
  464. const int r = 47;
  465. uint64_t h = seed ^ (len * m);
  466. const uint64_t * data = (const uint64_t *)key;
  467. const uint64_t * end = data + (len/8);
  468. while(data != end){
  469. uint64_t k = *data++;
  470. k *= m;
  471. k ^= k >> r;
  472. k *= m;
  473. h ^= k;
  474. h *= m;
  475. }
  476. const unsigned char * data2 = (const unsigned char*)data;
  477. switch(len & 7){
  478. case 7: h ^= ((uint64_t)data2[6]) << 48;
  479. case 6: h ^= ((uint64_t)data2[5]) << 40;
  480. case 5: h ^= ((uint64_t)data2[4]) << 32;
  481. case 4: h ^= ((uint64_t)data2[3]) << 24;
  482. case 3: h ^= ((uint64_t)data2[2]) << 16;
  483. case 2: h ^= ((uint64_t)data2[1]) << 8;
  484. case 1: h ^= ((uint64_t)data2[0]);
  485. h *= m;
  486. };
  487. h ^= h >> r;
  488. h *= m;
  489. h ^= h >> r;
  490. return h;
  491. }
  492. #define u32hashcode(key) __lh3_Jenkins_hash_int(key)
  493. #define u64hashcode(key) __lh3_Jenkins_hash_64(key)
  494. static inline uint32_t __string_hashcode(const char *s){
  495. uint32_t h = *s;
  496. if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
  497. return h;
  498. }
  499. #define u32hash_code(e) u32hashcode(e)
  500. #define u64hash_code(e) u64hashcode(e)
  501. #define uxxhash_equals(e1, e2) ((e1) == (e2))
  502. define_hashset(u32hash, uint32_t, u32hash_code, uxxhash_equals);
  503. define_hashset(u64hash, uint64_t, u64hash_code, uxxhash_equals);
  504. #define i32hash_code(e) u32hashcode((uint32_t)(e))
  505. #define i32hash_equals(e1, e2) ((e1) == (e2))
  506. define_hashset(i32hash, int, i32hash_code, i32hash_equals);
  507. #define chash_code(e) __string_hashcode(e)
  508. #define chash_equals(e1, e2) (strcmp(e1, e2) == 0)
  509. define_hashset(chash, char*, chash_code, chash_equals);
  510. #define KV_HASH_GET_VAL(e) (e)? (e)->val : ((typeof(e->val))MAX_U8)
  511. typedef struct { u4i key, val; } uuhash_t;
  512. #define uuhash_code(e) u32hashcode((e).key)
  513. #define uuhash_equals(e1, e2) ((e1).key == (e2).key)
  514. #define uuhash_key_equals(e1, e2) ((e1) == (e2).key)
  515. define_hashtable(uuhash, uuhash_t, uuhash_code, uuhash_equals, u4i, u32hashcode, uuhash_key_equals, u4i, KV_HASH_GET_VAL);
  516. typedef struct { u4i key; int val; } uihash_t;
  517. #define uihashcode(E) u32hashcode((E).key)
  518. #define uihashequals(E1, E2) (E1).key == (E2).key
  519. #define uihashkeyequals(E1, E2) (E1) == (E2).key
  520. define_hashtable(uihash, uihash_t, uihashcode, uihashequals, u4i, u32hashcode, uihashkeyequals, b4i, KV_HASH_GET_VAL);
  521. typedef struct { u8i key, val; } UUhash_t;
  522. #define UUhashcode(E) u64hashcode((E).key)
  523. #define UUhashequals(E1, E2) (E1).key == (E2).key
  524. #define UUhashkeyequals(E1, E2) (E1) == (E2).key
  525. define_hashtable(UUhash, UUhash_t, UUhashcode, UUhashequals, u8i, u64hashcode, UUhashkeyequals, u8i, KV_HASH_GET_VAL);
  526. typedef struct { char *key; u4i val; } cuhash_t;
  527. #define cuhash_code(e) __string_hashcode((e).key)
  528. #define cuhash_equals(e1, e2) (strcmp((e1).key, (e2).key) == 0)
  529. #define cuhash_key_equals(e1, e2) (strcmp((char*)(e1), (e2).key) == 0)
  530. define_hashtable(cuhash, cuhash_t, cuhash_code, cuhash_equals, char*, __string_hashcode, cuhash_key_equals, u4i, KV_HASH_GET_VAL);
  531. static const obj_desc_t cuhash_struct_deep_obj_desc = {"cuhash_struct_deep_obj_desc", sizeof(cuhash_t), 1, {1}, {offsetof(cuhash_t, key)}, {(obj_desc_t*)&OBJ_DESC_CHAR_ARRAY}, NULL, NULL};
  532. static const obj_desc_t cuhash_deep_obj_desc = {"cuhash_deep_obj_desc", sizeof(cuhash), 3, {1, 1, 1}, {offsetof(cuhash, array), offsetof(cuhash, ones), offsetof(cuhash, dels)}, {(obj_desc_t*)&cuhash_struct_deep_obj_desc, (obj_desc_t*)&bitvec_obj_desc, &bitvec_obj_desc}, cuhash_obj_desc_cnt, NULL};
  533. typedef struct { char *key; int val; } cihash_t;
  534. #define cihash_code(e) __string_hashcode((e).key)
  535. #define cihash_equals(e1, e2) (strcmp((e1).key, (e2).key) == 0)
  536. #define cihash_key_equals(e1, e2) (strcmp((char*)(e1), (e2).key) == 0)
  537. define_hashtable(cihash, cihash_t, cihash_code, cihash_equals, char*, __string_hashcode, cihash_key_equals, b4i, KV_HASH_GET_VAL);
  538. typedef struct { char *key; unsigned long long val; } clhash_t;
  539. #define clhash_code(e) __string_hashcode((e).key)
  540. #define clhash_equals(e1, e2) (strcmp((e1).key, (e2).key) == 0)
  541. #define clhash_key_equals(e1, e2) (strcmp((char*)(e1), (e2).key) == 0)
  542. define_hashtable(clhash, clhash_t, clhash_code, clhash_equals, char*, __string_hashcode, clhash_key_equals, u8i, KV_HASH_GET_VAL);
  543. typedef struct { char *key; char *val; } cchash_t;
  544. #define cchash_code(e) __string_hashcode((e).key)
  545. #define cchash_equals(e1, e2) (strcmp((e1).key, (e2).key) == 0)
  546. #define cchash_key_equals(e1, e2) (strcmp((char*)(e1), (e2).key) == 0)
  547. #define KV_CCHASH_GET_VAL(e) ((e)? (e)->val : NULL)
  548. define_hashtable(cchash, cchash_t, cchash_code, cchash_equals, char*, __string_hashcode, cchash_key_equals, char*, KV_CCHASH_GET_VAL);
  549. /**
  550. * Example of using userdata in thread-safe mode
  551. * char **strs;
  552. * ... codes init strs
  553. * #define test_hc(E) __string_hashcode(((char**)set->userdata)[E])
  554. * #define test_he(E1, E2) (strcmp(((char**)set->userdata)[E1], ((char**)set->userdata)[E2]) == 0)
  555. * define_hashset(testhash, uint32_t, test_hc, test_he);
  556. * testhash *hash = init_testhash(13);
  557. * set_userdata_testhash(hash, strs);
  558. * ... now, the key of testhash is uint32_t, but refer to strs
  559. */
  560. #endif