isomorfeus-ferret 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +612 -0
  3. data/README.md +44 -0
  4. data/ext/isomorfeus_ferret_ext/benchmark.c +223 -0
  5. data/ext/isomorfeus_ferret_ext/benchmark.h +45 -0
  6. data/ext/isomorfeus_ferret_ext/benchmarks_all.h +25 -0
  7. data/ext/isomorfeus_ferret_ext/bm_bitvector.c +123 -0
  8. data/ext/isomorfeus_ferret_ext/bm_hash.c +118 -0
  9. data/ext/isomorfeus_ferret_ext/bm_micro_string.c +40 -0
  10. data/ext/isomorfeus_ferret_ext/bm_store.c +93 -0
  11. data/ext/isomorfeus_ferret_ext/email.rl +21 -0
  12. data/ext/isomorfeus_ferret_ext/extconf.rb +5 -0
  13. data/ext/isomorfeus_ferret_ext/fio_tmpfile.h +53 -0
  14. data/ext/isomorfeus_ferret_ext/frb_analysis.c +2577 -0
  15. data/ext/isomorfeus_ferret_ext/frb_index.c +3457 -0
  16. data/ext/isomorfeus_ferret_ext/frb_lang.c +9 -0
  17. data/ext/isomorfeus_ferret_ext/frb_lang.h +17 -0
  18. data/ext/isomorfeus_ferret_ext/frb_qparser.c +629 -0
  19. data/ext/isomorfeus_ferret_ext/frb_search.c +4460 -0
  20. data/ext/isomorfeus_ferret_ext/frb_store.c +515 -0
  21. data/ext/isomorfeus_ferret_ext/frb_threading.h +30 -0
  22. data/ext/isomorfeus_ferret_ext/frb_utils.c +1127 -0
  23. data/ext/isomorfeus_ferret_ext/frt_analysis.c +1644 -0
  24. data/ext/isomorfeus_ferret_ext/frt_analysis.h +247 -0
  25. data/ext/isomorfeus_ferret_ext/frt_array.c +124 -0
  26. data/ext/isomorfeus_ferret_ext/frt_array.h +54 -0
  27. data/ext/isomorfeus_ferret_ext/frt_bitvector.c +95 -0
  28. data/ext/isomorfeus_ferret_ext/frt_bitvector.h +586 -0
  29. data/ext/isomorfeus_ferret_ext/frt_compound_io.c +374 -0
  30. data/ext/isomorfeus_ferret_ext/frt_config.h +44 -0
  31. data/ext/isomorfeus_ferret_ext/frt_document.c +134 -0
  32. data/ext/isomorfeus_ferret_ext/frt_document.h +52 -0
  33. data/ext/isomorfeus_ferret_ext/frt_except.c +95 -0
  34. data/ext/isomorfeus_ferret_ext/frt_except.h +188 -0
  35. data/ext/isomorfeus_ferret_ext/frt_field_index.c +233 -0
  36. data/ext/isomorfeus_ferret_ext/frt_field_index.h +42 -0
  37. data/ext/isomorfeus_ferret_ext/frt_filter.c +157 -0
  38. data/ext/isomorfeus_ferret_ext/frt_fs_store.c +502 -0
  39. data/ext/isomorfeus_ferret_ext/frt_global.c +427 -0
  40. data/ext/isomorfeus_ferret_ext/frt_global.h +290 -0
  41. data/ext/isomorfeus_ferret_ext/frt_hash.c +518 -0
  42. data/ext/isomorfeus_ferret_ext/frt_hash.h +466 -0
  43. data/ext/isomorfeus_ferret_ext/frt_hashset.c +191 -0
  44. data/ext/isomorfeus_ferret_ext/frt_hashset.h +206 -0
  45. data/ext/isomorfeus_ferret_ext/frt_helper.c +62 -0
  46. data/ext/isomorfeus_ferret_ext/frt_helper.h +13 -0
  47. data/ext/isomorfeus_ferret_ext/frt_ind.c +353 -0
  48. data/ext/isomorfeus_ferret_ext/frt_ind.h +54 -0
  49. data/ext/isomorfeus_ferret_ext/frt_index.c +6377 -0
  50. data/ext/isomorfeus_ferret_ext/frt_index.h +880 -0
  51. data/ext/isomorfeus_ferret_ext/frt_lang.c +104 -0
  52. data/ext/isomorfeus_ferret_ext/frt_lang.h +44 -0
  53. data/ext/isomorfeus_ferret_ext/frt_mempool.c +87 -0
  54. data/ext/isomorfeus_ferret_ext/frt_mempool.h +33 -0
  55. data/ext/isomorfeus_ferret_ext/frt_multimapper.c +349 -0
  56. data/ext/isomorfeus_ferret_ext/frt_multimapper.h +52 -0
  57. data/ext/isomorfeus_ferret_ext/frt_posh.c +1006 -0
  58. data/ext/isomorfeus_ferret_ext/frt_posh.h +973 -0
  59. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.c +147 -0
  60. data/ext/isomorfeus_ferret_ext/frt_priorityqueue.h +147 -0
  61. data/ext/isomorfeus_ferret_ext/frt_q_boolean.c +1612 -0
  62. data/ext/isomorfeus_ferret_ext/frt_q_const_score.c +157 -0
  63. data/ext/isomorfeus_ferret_ext/frt_q_filtered_query.c +209 -0
  64. data/ext/isomorfeus_ferret_ext/frt_q_fuzzy.c +281 -0
  65. data/ext/isomorfeus_ferret_ext/frt_q_match_all.c +147 -0
  66. data/ext/isomorfeus_ferret_ext/frt_q_multi_term.c +672 -0
  67. data/ext/isomorfeus_ferret_ext/frt_q_parser.c +3084 -0
  68. data/ext/isomorfeus_ferret_ext/frt_q_phrase.c +1182 -0
  69. data/ext/isomorfeus_ferret_ext/frt_q_prefix.c +98 -0
  70. data/ext/isomorfeus_ferret_ext/frt_q_range.c +665 -0
  71. data/ext/isomorfeus_ferret_ext/frt_q_span.c +2386 -0
  72. data/ext/isomorfeus_ferret_ext/frt_q_term.c +311 -0
  73. data/ext/isomorfeus_ferret_ext/frt_q_wildcard.c +166 -0
  74. data/ext/isomorfeus_ferret_ext/frt_ram_store.c +460 -0
  75. data/ext/isomorfeus_ferret_ext/frt_scanner.c +899 -0
  76. data/ext/isomorfeus_ferret_ext/frt_scanner.h +28 -0
  77. data/ext/isomorfeus_ferret_ext/frt_scanner_mb.c +6705 -0
  78. data/ext/isomorfeus_ferret_ext/frt_scanner_utf8.c +4419 -0
  79. data/ext/isomorfeus_ferret_ext/frt_search.c +1824 -0
  80. data/ext/isomorfeus_ferret_ext/frt_search.h +924 -0
  81. data/ext/isomorfeus_ferret_ext/frt_similarity.c +150 -0
  82. data/ext/isomorfeus_ferret_ext/frt_similarity.h +79 -0
  83. data/ext/isomorfeus_ferret_ext/frt_sort.c +796 -0
  84. data/ext/isomorfeus_ferret_ext/frt_stopwords.c +395 -0
  85. data/ext/isomorfeus_ferret_ext/frt_store.c +680 -0
  86. data/ext/isomorfeus_ferret_ext/frt_store.h +789 -0
  87. data/ext/isomorfeus_ferret_ext/frt_term_vectors.c +72 -0
  88. data/ext/isomorfeus_ferret_ext/frt_threading.h +23 -0
  89. data/ext/isomorfeus_ferret_ext/frt_win32.h +54 -0
  90. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +409 -0
  91. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.h +95 -0
  92. data/ext/isomorfeus_ferret_ext/libstemmer.c +93 -0
  93. data/ext/isomorfeus_ferret_ext/libstemmer.h +73 -0
  94. data/ext/isomorfeus_ferret_ext/q_parser.y +1366 -0
  95. data/ext/isomorfeus_ferret_ext/scanner.h +28 -0
  96. data/ext/isomorfeus_ferret_ext/scanner.in +43 -0
  97. data/ext/isomorfeus_ferret_ext/scanner.rl +84 -0
  98. data/ext/isomorfeus_ferret_ext/scanner_mb.rl +200 -0
  99. data/ext/isomorfeus_ferret_ext/scanner_utf8.rl +85 -0
  100. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_danish.c +324 -0
  101. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_danish.h +7 -0
  102. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_dutch.c +610 -0
  103. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_dutch.h +6 -0
  104. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_english.c +1104 -0
  105. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_english.h +6 -0
  106. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_finnish.c +749 -0
  107. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_finnish.h +7 -0
  108. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_french.c +1233 -0
  109. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_french.h +6 -0
  110. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_german.c +490 -0
  111. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_german.h +6 -0
  112. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_hungarian.c +1217 -0
  113. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_hungarian.h +7 -0
  114. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_italian.c +1052 -0
  115. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_italian.h +6 -0
  116. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_norwegian.c +283 -0
  117. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_norwegian.h +6 -0
  118. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_porter.c +735 -0
  119. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_porter.h +6 -0
  120. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_portuguese.c +1003 -0
  121. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_portuguese.h +7 -0
  122. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_spanish.c +1079 -0
  123. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_spanish.h +6 -0
  124. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_swedish.c +293 -0
  125. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_1_swedish.h +6 -0
  126. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_2_romanian.c +984 -0
  127. data/ext/isomorfeus_ferret_ext/stem_ISO_8859_2_romanian.h +6 -0
  128. data/ext/isomorfeus_ferret_ext/stem_KOI8_R_russian.c +686 -0
  129. data/ext/isomorfeus_ferret_ext/stem_KOI8_R_russian.h +6 -0
  130. data/ext/isomorfeus_ferret_ext/stem_UTF_8_danish.c +325 -0
  131. data/ext/isomorfeus_ferret_ext/stem_UTF_8_danish.h +6 -0
  132. data/ext/isomorfeus_ferret_ext/stem_UTF_8_dutch.c +620 -0
  133. data/ext/isomorfeus_ferret_ext/stem_UTF_8_dutch.h +6 -0
  134. data/ext/isomorfeus_ferret_ext/stem_UTF_8_english.c +1111 -0
  135. data/ext/isomorfeus_ferret_ext/stem_UTF_8_english.h +6 -0
  136. data/ext/isomorfeus_ferret_ext/stem_UTF_8_finnish.c +754 -0
  137. data/ext/isomorfeus_ferret_ext/stem_UTF_8_finnish.h +6 -0
  138. data/ext/isomorfeus_ferret_ext/stem_UTF_8_french.c +1242 -0
  139. data/ext/isomorfeus_ferret_ext/stem_UTF_8_french.h +6 -0
  140. data/ext/isomorfeus_ferret_ext/stem_UTF_8_german.c +495 -0
  141. data/ext/isomorfeus_ferret_ext/stem_UTF_8_german.h +6 -0
  142. data/ext/isomorfeus_ferret_ext/stem_UTF_8_hungarian.c +1220 -0
  143. data/ext/isomorfeus_ferret_ext/stem_UTF_8_hungarian.h +6 -0
  144. data/ext/isomorfeus_ferret_ext/stem_UTF_8_italian.c +1059 -0
  145. data/ext/isomorfeus_ferret_ext/stem_UTF_8_italian.h +6 -0
  146. data/ext/isomorfeus_ferret_ext/stem_UTF_8_norwegian.c +285 -0
  147. data/ext/isomorfeus_ferret_ext/stem_UTF_8_norwegian.h +6 -0
  148. data/ext/isomorfeus_ferret_ext/stem_UTF_8_porter.c +741 -0
  149. data/ext/isomorfeus_ferret_ext/stem_UTF_8_porter.h +6 -0
  150. data/ext/isomorfeus_ferret_ext/stem_UTF_8_portuguese.c +1009 -0
  151. data/ext/isomorfeus_ferret_ext/stem_UTF_8_portuguese.h +6 -0
  152. data/ext/isomorfeus_ferret_ext/stem_UTF_8_romanian.c +990 -0
  153. data/ext/isomorfeus_ferret_ext/stem_UTF_8_romanian.h +6 -0
  154. data/ext/isomorfeus_ferret_ext/stem_UTF_8_russian.c +680 -0
  155. data/ext/isomorfeus_ferret_ext/stem_UTF_8_russian.h +6 -0
  156. data/ext/isomorfeus_ferret_ext/stem_UTF_8_spanish.c +1083 -0
  157. data/ext/isomorfeus_ferret_ext/stem_UTF_8_spanish.h +6 -0
  158. data/ext/isomorfeus_ferret_ext/stem_UTF_8_swedish.c +294 -0
  159. data/ext/isomorfeus_ferret_ext/stem_UTF_8_swedish.h +6 -0
  160. data/ext/isomorfeus_ferret_ext/stem_UTF_8_turkish.c +2191 -0
  161. data/ext/isomorfeus_ferret_ext/stem_UTF_8_turkish.h +6 -0
  162. data/ext/isomorfeus_ferret_ext/stem_api.c +66 -0
  163. data/ext/isomorfeus_ferret_ext/stem_api.h +26 -0
  164. data/ext/isomorfeus_ferret_ext/stem_header.h +57 -0
  165. data/ext/isomorfeus_ferret_ext/stem_modules.h +190 -0
  166. data/ext/isomorfeus_ferret_ext/stem_modules.txt +50 -0
  167. data/ext/isomorfeus_ferret_ext/stem_utilities.c +478 -0
  168. data/ext/isomorfeus_ferret_ext/test.c +850 -0
  169. data/ext/isomorfeus_ferret_ext/test.h +416 -0
  170. data/ext/isomorfeus_ferret_ext/test_1710.c +63 -0
  171. data/ext/isomorfeus_ferret_ext/test_analysis.c +1221 -0
  172. data/ext/isomorfeus_ferret_ext/test_array.c +272 -0
  173. data/ext/isomorfeus_ferret_ext/test_bitvector.c +600 -0
  174. data/ext/isomorfeus_ferret_ext/test_compound_io.c +170 -0
  175. data/ext/isomorfeus_ferret_ext/test_document.c +156 -0
  176. data/ext/isomorfeus_ferret_ext/test_except.c +244 -0
  177. data/ext/isomorfeus_ferret_ext/test_fields.c +522 -0
  178. data/ext/isomorfeus_ferret_ext/test_file_deleter.c +185 -0
  179. data/ext/isomorfeus_ferret_ext/test_filter.c +331 -0
  180. data/ext/isomorfeus_ferret_ext/test_fs_store.c +25 -0
  181. data/ext/isomorfeus_ferret_ext/test_global.c +299 -0
  182. data/ext/isomorfeus_ferret_ext/test_hash.c +485 -0
  183. data/ext/isomorfeus_ferret_ext/test_hashset.c +288 -0
  184. data/ext/isomorfeus_ferret_ext/test_helper.c +47 -0
  185. data/ext/isomorfeus_ferret_ext/test_highlighter.c +548 -0
  186. data/ext/isomorfeus_ferret_ext/test_index.c +2323 -0
  187. data/ext/isomorfeus_ferret_ext/test_lang.c +74 -0
  188. data/ext/isomorfeus_ferret_ext/test_mempool.c +102 -0
  189. data/ext/isomorfeus_ferret_ext/test_multimapper.c +64 -0
  190. data/ext/isomorfeus_ferret_ext/test_priorityqueue.c +213 -0
  191. data/ext/isomorfeus_ferret_ext/test_q_const_score.c +84 -0
  192. data/ext/isomorfeus_ferret_ext/test_q_filtered.c +61 -0
  193. data/ext/isomorfeus_ferret_ext/test_q_fuzzy.c +241 -0
  194. data/ext/isomorfeus_ferret_ext/test_q_parser.c +464 -0
  195. data/ext/isomorfeus_ferret_ext/test_q_span.c +575 -0
  196. data/ext/isomorfeus_ferret_ext/test_ram_store.c +77 -0
  197. data/ext/isomorfeus_ferret_ext/test_search.c +1874 -0
  198. data/ext/isomorfeus_ferret_ext/test_segments.c +167 -0
  199. data/ext/isomorfeus_ferret_ext/test_similarity.c +25 -0
  200. data/ext/isomorfeus_ferret_ext/test_sort.c +333 -0
  201. data/ext/isomorfeus_ferret_ext/test_store.c +591 -0
  202. data/ext/isomorfeus_ferret_ext/test_store.h +3 -0
  203. data/ext/isomorfeus_ferret_ext/test_term.c +351 -0
  204. data/ext/isomorfeus_ferret_ext/test_term_vectors.c +373 -0
  205. data/ext/isomorfeus_ferret_ext/test_test.c +83 -0
  206. data/ext/isomorfeus_ferret_ext/test_threading.c +188 -0
  207. data/ext/isomorfeus_ferret_ext/testhelper.c +561 -0
  208. data/ext/isomorfeus_ferret_ext/testhelper.h +25 -0
  209. data/ext/isomorfeus_ferret_ext/tests_all.h +87 -0
  210. data/ext/isomorfeus_ferret_ext/uchar-ucs4.rl +1854 -0
  211. data/ext/isomorfeus_ferret_ext/uchar-utf8.rl +1999 -0
  212. data/ext/isomorfeus_ferret_ext/url.rl +27 -0
  213. data/ext/isomorfeus_ferret_ext/word_list.h +15156 -0
  214. data/lib/isomorfeus/ferret/document.rb +132 -0
  215. data/lib/isomorfeus/ferret/field_symbol.rb +85 -0
  216. data/lib/isomorfeus/ferret/index/field_infos.rb +48 -0
  217. data/lib/isomorfeus/ferret/index/index.rb +970 -0
  218. data/lib/isomorfeus/ferret/monitor.rb +323 -0
  219. data/lib/isomorfeus/ferret/stdlib_patches.rb +151 -0
  220. data/lib/isomorfeus/ferret/version.rb +5 -0
  221. data/lib/isomorfeus-ferret.rb +8 -0
  222. metadata +307 -0
@@ -0,0 +1,466 @@
1
+ #ifndef FRT_HASH_H
2
+ #define FRT_HASH_H
3
+
4
+ #include "frt_global.h"
5
+
6
+ /****************************************************************************
7
+ *
8
+ * Hash
9
+ *
10
+ ****************************************************************************/
11
+
12
+ #define FRT_HASH_MINSIZE 16
13
+ #define FRT_SLOW_DOWN 50000 /* stop increasing the hash table so quickly to conserve memory */
14
+
15
+ /**
16
+ * Return values for frt_h_set
17
+ */
18
+ typedef enum
19
+ {
20
+ FRT_HASH_KEY_DOES_NOT_EXIST = 0,
21
+ FRT_HASH_KEY_EQUAL = 1,
22
+ FRT_HASH_KEY_SAME = 2
23
+ } FrtHashKeyStatus;
24
+
25
+ /**
26
+ * struct used internally to store values in the Hash
27
+ */
28
+ typedef struct
29
+ {
30
+ unsigned long long hash;
31
+ void *key;
32
+ void *value;
33
+ } FrtHashEntry;
34
+
35
+ /**
36
+ * As the hash table is filled and entries are deleted, Dummy HashEntries are
37
+ * put in place. We therefor keep two counts. +size+ is the number active
38
+ * elements and +fill+ is the number of active elements together with the
39
+ * number of dummy elements. +fill+ is basically just kept around so that we
40
+ * know when to resize. The Hash is resized when more than two thirds of
41
+ * the Hash is Filled.
42
+ */
43
+ typedef struct FrtHash
44
+ {
45
+ int fill; /* num Active + num Dummy */
46
+ int size; /* num Active ie, num keys set */
47
+ int mask; /* capacity_of_table - 1 */
48
+ int ref_cnt;
49
+
50
+ /* table points to smalltable initially. If the table grows beyond 2/3 of
51
+ * FRT_HASH_MINSIZE it will point to newly malloced memory as it grows. */
52
+ FrtHashEntry *table;
53
+
54
+ /* When a Hash is created it needs an initial table to start it off.
55
+ * All Hashs will start with smalltable and then malloc a larger
56
+ * table as the Hash grows */
57
+ FrtHashEntry smalltable[FRT_HASH_MINSIZE];
58
+
59
+ /* the following function pointers are used internally and should not be
60
+ * used outside of the Hash methods */
61
+ FrtHashEntry *(*lookup_i)(struct FrtHash *self,
62
+ register const void *key);
63
+ unsigned long long (*hash_i)(const void *key);
64
+ int (*eq_i)(const void *key1, const void *key2);
65
+ void (*free_key_i)(void *p);
66
+ void (*free_value_i)(void *p);
67
+ } FrtHash;
68
+
69
+ /**
70
+ * Hashing function type used by Hash. A function of this type must be
71
+ * passed to create a new Hash.
72
+ *
73
+ * @param key object to hash
74
+ * @return an unsigned 32-bit integer hash value
75
+ */
76
+ typedef unsigned long long (*frt_hash_ft)(const void *key);
77
+
78
+ /**
79
+ * Equals function type used by Hash. A function of this type must be
80
+ * passed to create a new Hash.
81
+ */
82
+ typedef int (*frt_eq_ft)(const void *key1, const void *key2);
83
+
84
+ /**
85
+ * Determine a hash value for a string. The string must be null terminated
86
+ *
87
+ * @param str string to hash
88
+ * @return an unsigned long integer hash value
89
+ */
90
+ extern unsigned long long frt_str_hash(const char *const str);
91
+
92
+ /**
93
+ * Determine a hash value for a pointer. Just cast the pointer to an unsigned
94
+ * long.
95
+ *
96
+ * @param ptr pointer to hash
97
+ * @return an unsigned long integer hash value
98
+ */
99
+ extern unsigned long long frt_ptr_hash(const void *const ptr);
100
+
101
+ /**
102
+ * Determine if two pointers point to the same point in memory.
103
+ *
104
+ * @param q1 first pointer
105
+ * @param q2 second pointer
106
+ * @return true if the pointers are equal
107
+ */
108
+ extern int frt_ptr_eq(const void *q1, const void *q2);
109
+
110
+ /**
111
+ * Create a new Hash that uses any type of object as its key. The
112
+ * Hash will store all keys and values so if you want to destroy those
113
+ * values when the Hash is destroyed then you should pass free functions.
114
+ * NULL will suffice otherwise.
115
+ *
116
+ * @param hash function to determine the hash value of a key in the Hash
117
+ * @param eq function to determine the equality of to keys in the Hash
118
+ * @param free_key function to free the key stored in the Hash when an
119
+ * entry is deleted, replaced or when the Hash is destroyed. If you
120
+ * pass NULL in place of this parameter the key will not be destroyed.
121
+ * @param free_value function to free the value stored in the Hash when
122
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
123
+ * pass NULL in place of this parameter the value will not be destroyed.
124
+ * @return A newly allocated Hash
125
+ */
126
+ extern FrtHash *frt_h_new(frt_hash_ft hash,
127
+ frt_eq_ft eq,
128
+ frt_free_ft free_key,
129
+ frt_free_ft free_value);
130
+
131
+ /**
132
+ * Create a new Hash that uses null-terminated strings as its keys. The
133
+ * Hash will store all keys and values so if you want to destroy those
134
+ * values when the Hash is destroyed then you should pass free functions.
135
+ * NULL will suffice otherwise.
136
+ *
137
+ * @param free_key function to free the key stored in the Hash when an
138
+ * entry is deleted, replaced or when the Hash is destroyed. If you
139
+ * pass NULL in place of this parameter the key will not be destroyed.
140
+ * @param free_value function to free the value stored in the Hash when
141
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
142
+ * pass NULL in place of this parameter the value will not be destroyed.
143
+ * @return A newly allocated Hash
144
+ */
145
+ extern FrtHash *frt_h_new_str(frt_free_ft free_key,
146
+ frt_free_ft free_value);
147
+
148
+ /**
149
+ * Create a new Hash that uses integers as its keys. The Hash will store all
150
+ * values so if you want to destroy those values when the Hash is destroyed
151
+ * then you should pass a free function. NULL will suffice otherwise.
152
+ *
153
+ * @param free_value function to free the value stored in the Hash when
154
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
155
+ * pass NULL in place of this parameter the value will not be destroyed.
156
+ * @return A newly allocated Hash
157
+ */
158
+ extern FrtHash *frt_h_new_int(frt_free_ft free_value);
159
+
160
+ /**
161
+ * Create a new Hash that uses pointers as its keys. The Hash will store all
162
+ * values so if you want to destroy those values when the Hash is destroyed
163
+ * then you should pass a free function. NULL will suffice otherwise.
164
+ *
165
+ * @param free_value function to free the value stored in the Hash when
166
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
167
+ * pass NULL in place of this parameter the value will not be destroyed.
168
+ * @return A newly allocated Hash
169
+ */
170
+ #define frt_h_new_ptr(free_value) frt_h_new_int(free_value)
171
+
172
+ /**
173
+ * Destroy the Hash. This function will also destroy all keys and values
174
+ * in the Hash depending on how the free_key and free_value were set.
175
+ *
176
+ * @param self the Hash to destroy
177
+ */
178
+ extern void frt_h_destroy(FrtHash *self);
179
+
180
+ /**
181
+ * Clear the Hash. This function will delete all keys and values from the
182
+ * hash table, also destroying all keys and values in the Hash depending
183
+ * on how the free_key and free_value were set.
184
+ *
185
+ * @param self the Hash to clear
186
+ */
187
+ extern void frt_h_clear(FrtHash *self);
188
+
189
+ /**
190
+ * Get the value in the Hash referenced by the key +key+.
191
+ *
192
+ * @param self the Hash to reference
193
+ * @param key the key to lookup
194
+ * @return the value referenced by the key +key+. If there is no value
195
+ * referenced by that key, NULL is returned.
196
+ */
197
+ extern void *frt_h_get(FrtHash *self, const void *key);
198
+
199
+ /**
200
+ * Delete the value in Hash referenced by the key +key+. When the value
201
+ * is deleted it is also destroyed along with the key depending on how
202
+ * free_key and free_value where set when the Hash was created. If you
203
+ * don't want to destroy the value use frt_h_rem.
204
+ *
205
+ * This functions returns +true+ if the value was deleted successfully or
206
+ * false if the key was not found.
207
+ *
208
+ * @see frt_h_rem
209
+ *
210
+ * @param self the Hash to reference
211
+ * @param key the key to lookup
212
+ * @return true if the object was successfully deleted or false if the key was
213
+ * not found
214
+ */
215
+ extern int frt_h_del(FrtHash *self, const void *key);
216
+
217
+ /**
218
+ * Remove the value in Hash referenced by the key +key+. When the value
219
+ * is removed it is returned rather than destroyed. The key however is
220
+ * destroyed using the free_key functions passed when the Hash is created
221
+ * if del_key is true.
222
+ *
223
+ * If you want the value to be destroyed, use the frt_h_del function.
224
+ *
225
+ * @see frt_h_del
226
+ *
227
+ * @param self the Hash to reference
228
+ * @param key the key to lookup
229
+ * @param del_key set to true if you want the key to be deleted when the value
230
+ * is removed from the Hash
231
+ * @return the value referenced by +key+ if it can be found or NULL otherwise
232
+ */
233
+ extern void *frt_h_rem(FrtHash *self, const void *key, bool del_key);
234
+
235
+ /**
236
+ * WARNING: this function may destroy an old value or key if the key already
237
+ * exists in the Hash, depending on how free_value and free_key were set
238
+ * for this Hash.
239
+ *
240
+ * Add the value +value+ to the Hash referencing it with key +key+.
241
+ *
242
+ * When a value is added to the Hash it replaces any value that
243
+ * might already be stored under that key. If free_value is already set then
244
+ * the old value will be freed using that function.
245
+ *
246
+ * Similarly the old key might replace be replaced by the new key if they are
247
+ * are equal (according to the Hash's eq function) but seperately
248
+ * allocated objects.
249
+ *
250
+ * @param self the Hash to add the value to
251
+ * @param key the key to use to reference the value
252
+ * @param value the value to add to the Hash
253
+ * @return one of three values;
254
+ * <pre>
255
+ * FRT_HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
256
+ * FRT_HASH_KEY_EQUAL the key existed and was seperately allocated.
257
+ * In this situation the old key will have been
258
+ * destroyed if free_key was set
259
+ * FRT_HASH_KEY_SAME the key was identical (same memory pointer) to
260
+ * the existing key so no key was freed
261
+ * </pre>
262
+ */
263
+ extern FrtHashKeyStatus frt_h_set(FrtHash *self,
264
+ const void *key, void *value);
265
+
266
+ /**
267
+ * Add the value +value+ to the Hash referencing it with key +key+. If
268
+ * the key already exists in the Hash, the value won't be added and the
269
+ * function will return false. Otherwise it will return true.
270
+ *
271
+ * @param self the Hash to add the value to
272
+ * @param key the key to use to reference the value
273
+ * @param value the value to add to the Hash
274
+ * @return true if the value was successfully added or false otherwise
275
+ */
276
+ extern int frt_h_set_safe(FrtHash *self, const void *key, void *value);
277
+
278
+ /**
279
+ * Return a hash entry object so you can handle the insert yourself. This can
280
+ * be used for performance reasons or for more control over how a value is
281
+ * added. Say, for example, you wanted to append a value to an array, or add a
282
+ * new array if non-existed, you could use this method by checking the value
283
+ * of the HashEntry returned.
284
+ *
285
+ * @param self the Hash to add the value to
286
+ * @param key the key to use to reference the value
287
+ * @param he HashEntry a pointer to the hash entry object now reserved for this
288
+ * value. Be sure to set both the *key* and the *value*
289
+ * @return true if the key was empty, false otherwise
290
+ */
291
+ extern bool frt_h_set_ext(FrtHash *self,
292
+ const void *key,
293
+ FrtHashEntry **he);
294
+
295
+ /**
296
+ * Check whether key +key+ exists in the Hash.
297
+ *
298
+ * @param self the Hash to check in
299
+ * @param key the key to check for in the Hash
300
+ * @return one of three values;
301
+ * <pre>
302
+ * 0 - FRT_HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
303
+ * 1 - FRT_HASH_KEY_EQUAL the key existed and was seperately
304
+ * allocated.
305
+ * 2 - FRT_HASH_KEY_SAME the key was identical (same memory
306
+ * pointer) to the existing key so no key was
307
+ * freed
308
+ * </pre>
309
+ * Note: the return value can be treated as a true/false value, ie 0 if the
310
+ * key doesn't exist, non-zero if it does.
311
+ */
312
+ extern FrtHashKeyStatus frt_h_has_key(FrtHash *self,
313
+ const void *key);
314
+
315
+ /**
316
+ * Get the value in the Hash referenced by an integer key +key+.
317
+ *
318
+ * @param self the Hash to reference
319
+ * @param key the integer key to lookup
320
+ * @return the value referenced by the key +key+. If there is no value
321
+ * referenced by that key, NULL is returned.
322
+ */
323
+ extern void *frt_h_get_int(FrtHash *self, const unsigned long long key);
324
+
325
+ /**
326
+ * Delete the value in Hash referenced by the integer key +key+. When the
327
+ * value is deleted it is also destroyed using the free_value function. If you
328
+ * don't want to destroy the value use frt_h_rem.
329
+ *
330
+ * This functions returns +true+ if the value was deleted successfully or
331
+ * false if the key was not found.
332
+ *
333
+ * @see frt_h_rem
334
+ *
335
+ * @param self the Hash to reference
336
+ * @param key the integer key to lookup
337
+ * @return true if the object was successfully deleted or false if the key was
338
+ * not found
339
+ */
340
+ extern int frt_h_del_int(FrtHash *self, const unsigned long long key);
341
+
342
+ /**
343
+ * Remove the value in Hash referenced by the integer key +key+. When the
344
+ * value is removed it is returned rather than destroyed.
345
+ *
346
+ * If you want the value to be destroyed, use the frt_h_del function.
347
+ *
348
+ * @see frt_h_del
349
+ *
350
+ * @param self the Hash to reference
351
+ * @param key the integer key to lookup
352
+ * @return the value referenced by +key+ if it can be found or NULL otherwise
353
+ */
354
+ extern void *frt_h_rem_int(FrtHash *self, const unsigned long long key);
355
+
356
+ /**
357
+ * WARNING: this function may destroy an old value if the key already exists
358
+ * in the Hash, depending on how free_value was set for this Hash.
359
+ *
360
+ * Add the value +value+ to the Hash referencing it with an integer key
361
+ * +key+.
362
+ *
363
+ * When a value is added to the Hash it replaces any value that
364
+ * might already be stored under that key. If free_value is already set then
365
+ * the old value will be freed using that function.
366
+ *
367
+ * Similarly the old key might replace be replaced by the new key if they are
368
+ * are equal (according to the Hash's eq function) but seperately
369
+ * allocated objects.
370
+ *
371
+ * @param self the Hash to add the value to
372
+ * @param key the integer key to use to reference the value
373
+ * @param value the value to add to the Hash
374
+ * @return one of three values;
375
+ * <pre>
376
+ * FRT_HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
377
+ * FRT_HASH_KEY_EQUAL the key existed and was seperately allocated.
378
+ * In this situation the old key will have been
379
+ * destroyed if free_key was set
380
+ * FRT_HASH_KEY_SAME the key was identical (same memory pointer) to
381
+ * the existing key so no key was freed
382
+ * </pre>
383
+ */
384
+ extern FrtHashKeyStatus frt_h_set_int(FrtHash *self,
385
+ const unsigned long long key,
386
+ void *value);
387
+
388
+ /**
389
+ * Add the value +value+ to the Hash referencing it with integer key
390
+ * +key+. If the key already exists in the Hash, the value won't be added
391
+ * and the function will return false. Otherwise it will return true.
392
+ *
393
+ * @param self the Hash to add the value to
394
+ * @param key the integer key to use to reference the value
395
+ * @param value the value to add to the Hash
396
+ * @return true if the value was successfully added or false otherwise
397
+ */
398
+ extern int frt_h_set_safe_int(FrtHash *self,
399
+ const unsigned long long key,
400
+ void *value);
401
+ /**
402
+ * Check whether integer key +key+ exists in the Hash.
403
+ *
404
+ * @param self the Hash to check in
405
+ * @param key the integer key to check for in the Hash
406
+ * @return true if the key exists in the Hash, false otherwise.
407
+ */
408
+ extern int frt_h_has_key_int(FrtHash *self, const unsigned long long key);
409
+
410
+ typedef void (*frt_h_each_key_val_ft)(void *key, void *value, void *arg);
411
+
412
+ /**
413
+ * @param self the Hash to run the function on
414
+ * @param each_key_val function to run on on each key and value in the
415
+ * Hash
416
+ * @param arg an extra argument to pass to each_key_val each time it is called
417
+ */
418
+ extern void frt_h_each(FrtHash *self,
419
+ void (*each_key_val)(void *key, void *value, void *arg),
420
+ void *arg);
421
+
422
+ typedef void *(*frt_h_clone_ft)(void *val);
423
+ /**
424
+ * Clone the Hash as well as cloning each of the keys and values if you
425
+ * want to do a deep clone. To do a deep clone you will need to pass a
426
+ * clone_key function and/or a clone_value function.
427
+ *
428
+ * @param self the Hash to clone
429
+ * @param clone_key the function to clone the key with
430
+ * @param clone_value the function to clone the value with
431
+ * @return a clone of the original Hash
432
+ */
433
+ extern FrtHash *frt_h_clone(FrtHash *self,
434
+ frt_h_clone_ft clone_key,
435
+ frt_h_clone_ft clone_value);
436
+
437
+ /*
438
+ * The following functions should only be used in static Hash
439
+ * declarations
440
+ */
441
+ /**
442
+ * This is the lookup function for a hash table with non-string keys. The
443
+ * hash() and eq() methods used are stored in the hash table. This method will
444
+ * always return a HashEntry. If there is no entry with the given key then an
445
+ * empty entry will be returned with the key set to the key that was passed.
446
+ *
447
+ * @param ht the hash table to look in
448
+ * @param key the key to lookup
449
+ * @return the HashEntry that was found
450
+ */
451
+ extern FrtHashEntry *frt_h_lookup(FrtHash *ht, register const void *key);
452
+
453
+ extern void frt_h_str_print_keys(FrtHash *ht, FILE *out);
454
+
455
+ /**
456
+ * The Hash implementation actually keeps a buffer of old hash tables around
457
+ * for performance reasons. If you want all memory freed when your program
458
+ * finishes (useful if you are using valgrind) you should call this method on
459
+ * exit.
460
+ *
461
+ * One way to do this is to register it with atexit(). This is done for you
462
+ * when you call +frt_init+.
463
+ */
464
+ extern void frt_hash_finalize();
465
+
466
+ #endif
@@ -0,0 +1,191 @@
1
+ #include "frt_hashset.h"
2
+ #include <string.h>
3
+
4
+ /*
5
+ * The HashSet contains an array +elems+ of the elements that have been added.
6
+ * It always has +size+ elements so +size+ ane +elems+ can be used to iterate
7
+ * over all alements in the HashSet. It also uses a Hash to keep track of
8
+ * which elements have been added and their index in the +elems+ array.
9
+ */
10
+ static FrtHashSet *hs_alloc(frt_free_ft free_func)
11
+ {
12
+ FrtHashSet *hs = FRT_ALLOC(FrtHashSet);
13
+ hs->size = 0;
14
+ hs->first = hs->last = NULL;
15
+ hs->free_elem_i = free_func ? free_func : &frt_dummy_free;
16
+ return hs;
17
+ }
18
+
19
+ FrtHashSet *frt_hs_new(frt_hash_ft hash_func, frt_eq_ft eq_func, frt_free_ft free_func)
20
+ {
21
+ FrtHashSet *hs = hs_alloc(free_func);
22
+ hs->ht = frt_h_new(hash_func, eq_func, NULL, NULL);
23
+ return hs;
24
+ }
25
+
26
+ FrtHashSet *frt_hs_new_str(frt_free_ft free_func)
27
+ {
28
+ FrtHashSet *hs = hs_alloc(free_func);
29
+ hs->ht = frt_h_new_str((frt_free_ft) NULL, NULL);
30
+ return hs;
31
+ }
32
+
33
+ FrtHashSet *frt_hs_new_ptr(frt_free_ft free_func)
34
+ {
35
+ FrtHashSet *hs = hs_alloc(free_func);
36
+ hs->ht = frt_h_new_ptr(NULL);
37
+ return hs;
38
+ }
39
+
40
+ static void clear(FrtHashSet *hs, bool destroy)
41
+ {
42
+ FrtHashSetEntry *curr, *next = hs->first;
43
+ frt_free_ft do_free = destroy ? hs->free_elem_i : &frt_dummy_free;
44
+ while (NULL != (curr = next)) {
45
+ next = curr->next;
46
+ do_free(curr->elem);
47
+ free(curr);
48
+ }
49
+ hs->first = hs->last = NULL;
50
+ hs->size = 0;
51
+ }
52
+
53
+ void frt_hs_clear(FrtHashSet *hs)
54
+ {
55
+ clear(hs, true);
56
+ frt_h_clear(hs->ht);
57
+ }
58
+
59
+ void frt_hs_free(FrtHashSet *hs)
60
+ {
61
+ clear(hs, false);
62
+ frt_h_destroy(hs->ht);
63
+ free(hs);
64
+ }
65
+
66
+ void frt_hs_destroy(FrtHashSet *hs)
67
+ {
68
+ clear(hs, true);
69
+ frt_h_destroy(hs->ht);
70
+ free(hs);
71
+ }
72
+
73
+ static void append(FrtHashSet *hs, void *elem)
74
+ {
75
+ FrtHashSetEntry *entry = FRT_ALLOC(FrtHashSetEntry);
76
+ entry->elem = elem;
77
+ entry->prev = hs->last;
78
+ entry->next = NULL;
79
+ if (!hs->first) {
80
+ hs->first = hs->last = entry;
81
+ }
82
+ else {
83
+ hs->last->next = entry;
84
+ hs->last = entry;
85
+ }
86
+ frt_h_set(hs->ht, elem, entry);
87
+ hs->size++;
88
+ }
89
+
90
+ FrtHashKeyStatus frt_hs_add(FrtHashSet *hs, void *elem)
91
+ {
92
+ FrtHashKeyStatus has_elem = frt_h_has_key(hs->ht, elem);
93
+ switch (has_elem)
94
+ {
95
+ /* We don't want to keep two of the same elem so free if necessary */
96
+ case FRT_HASH_KEY_EQUAL:
97
+ hs->free_elem_i(elem);
98
+ return has_elem;
99
+
100
+ /* No need to do anything */
101
+ case FRT_HASH_KEY_SAME:
102
+ return has_elem;
103
+
104
+ /* add the elem to the array, resizing if necessary */
105
+ case FRT_HASH_KEY_DOES_NOT_EXIST:
106
+ break;
107
+
108
+ }
109
+
110
+ append(hs, elem);
111
+ return has_elem;
112
+ }
113
+
114
+ int frt_hs_add_safe(FrtHashSet *hs, void *elem)
115
+ {
116
+ switch(frt_h_has_key(hs->ht, elem))
117
+ {
118
+ /* element can't be added */
119
+ case FRT_HASH_KEY_EQUAL: return false;
120
+
121
+ /* the exact same element has already been added */
122
+ case FRT_HASH_KEY_SAME : return true;
123
+
124
+ /* add the elem to the array, resizing if necessary */
125
+ case FRT_HASH_KEY_DOES_NOT_EXIST : break;
126
+ }
127
+ append(hs, elem);
128
+ return true;
129
+ }
130
+
131
+ void *frt_hs_rem(FrtHashSet *hs, const void *elem)
132
+ {
133
+ void *return_elem;
134
+ FrtHashSetEntry *entry = (FrtHashSetEntry *)frt_h_get(hs->ht, elem);
135
+ if (entry == NULL) return NULL;
136
+
137
+ if (hs->first == hs->last) {
138
+ hs->first = hs->last = NULL;
139
+ }
140
+ else if (hs->first == entry) {
141
+ hs->first = entry->next;
142
+ hs->first->prev = NULL;
143
+ }
144
+ else if (hs->last == entry) {
145
+ hs->last = entry->prev;
146
+ hs->last->next = NULL;
147
+ }
148
+ else {
149
+ entry->prev->next = entry->next;
150
+ entry->next->prev = entry->prev;
151
+ }
152
+ return_elem = entry->elem;
153
+ frt_h_del(hs->ht, return_elem);
154
+ free(entry);
155
+ hs->size--;
156
+ return return_elem;
157
+ }
158
+
159
+ int frt_hs_del(FrtHashSet *hs, const void *elem)
160
+ {
161
+ void *tmp_elem = frt_hs_rem(hs, elem);
162
+ if (tmp_elem != NULL) {
163
+ hs->free_elem_i(tmp_elem);
164
+ return 1;
165
+ }
166
+ return 0;
167
+ }
168
+
169
+ FrtHashKeyStatus frt_hs_exists(FrtHashSet *hs, const void *elem)
170
+ {
171
+ return frt_h_has_key(hs->ht, elem);
172
+ }
173
+
174
+ FrtHashSet *frt_hs_merge(FrtHashSet *hs, FrtHashSet * other)
175
+ {
176
+ FrtHashSetEntry *entry = other->first;
177
+ for (; entry != NULL; entry = entry->next) {
178
+ frt_hs_add(hs, entry->elem);
179
+ }
180
+ /* Now free the other hashset. It is no longer needed. No need, however,
181
+ * to delete the elements as they were either destroyed or added to the
182
+ * new hashset. */
183
+ frt_hs_free(other);
184
+ return hs;
185
+ }
186
+
187
+ void *frt_hs_orig(FrtHashSet *hs, const void *elem)
188
+ {
189
+ FrtHashSetEntry *entry = (FrtHashSetEntry *)frt_h_get(hs->ht, elem);
190
+ return entry ? entry->elem : NULL;
191
+ }