jk-ferret 0.11.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. data/CHANGELOG +24 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README +90 -0
  4. data/RELEASE_CHANGES +137 -0
  5. data/RELEASE_NOTES +60 -0
  6. data/Rakefile +443 -0
  7. data/TODO +109 -0
  8. data/TUTORIAL +231 -0
  9. data/bin/ferret-browser +79 -0
  10. data/ext/BZLIB_blocksort.c +1094 -0
  11. data/ext/BZLIB_bzlib.c +1578 -0
  12. data/ext/BZLIB_compress.c +672 -0
  13. data/ext/BZLIB_crctable.c +104 -0
  14. data/ext/BZLIB_decompress.c +626 -0
  15. data/ext/BZLIB_huffman.c +205 -0
  16. data/ext/BZLIB_randtable.c +84 -0
  17. data/ext/STEMMER_api.c +66 -0
  18. data/ext/STEMMER_libstemmer.c +93 -0
  19. data/ext/STEMMER_stem_ISO_8859_1_danish.c +337 -0
  20. data/ext/STEMMER_stem_ISO_8859_1_dutch.c +624 -0
  21. data/ext/STEMMER_stem_ISO_8859_1_english.c +1117 -0
  22. data/ext/STEMMER_stem_ISO_8859_1_finnish.c +762 -0
  23. data/ext/STEMMER_stem_ISO_8859_1_french.c +1246 -0
  24. data/ext/STEMMER_stem_ISO_8859_1_german.c +503 -0
  25. data/ext/STEMMER_stem_ISO_8859_1_hungarian.c +1230 -0
  26. data/ext/STEMMER_stem_ISO_8859_1_italian.c +1065 -0
  27. data/ext/STEMMER_stem_ISO_8859_1_norwegian.c +297 -0
  28. data/ext/STEMMER_stem_ISO_8859_1_porter.c +749 -0
  29. data/ext/STEMMER_stem_ISO_8859_1_portuguese.c +1017 -0
  30. data/ext/STEMMER_stem_ISO_8859_1_spanish.c +1093 -0
  31. data/ext/STEMMER_stem_ISO_8859_1_swedish.c +307 -0
  32. data/ext/STEMMER_stem_ISO_8859_2_romanian.c +998 -0
  33. data/ext/STEMMER_stem_KOI8_R_russian.c +700 -0
  34. data/ext/STEMMER_stem_UTF_8_danish.c +339 -0
  35. data/ext/STEMMER_stem_UTF_8_dutch.c +634 -0
  36. data/ext/STEMMER_stem_UTF_8_english.c +1125 -0
  37. data/ext/STEMMER_stem_UTF_8_finnish.c +768 -0
  38. data/ext/STEMMER_stem_UTF_8_french.c +1256 -0
  39. data/ext/STEMMER_stem_UTF_8_german.c +509 -0
  40. data/ext/STEMMER_stem_UTF_8_hungarian.c +1234 -0
  41. data/ext/STEMMER_stem_UTF_8_italian.c +1073 -0
  42. data/ext/STEMMER_stem_UTF_8_norwegian.c +299 -0
  43. data/ext/STEMMER_stem_UTF_8_porter.c +755 -0
  44. data/ext/STEMMER_stem_UTF_8_portuguese.c +1023 -0
  45. data/ext/STEMMER_stem_UTF_8_romanian.c +1004 -0
  46. data/ext/STEMMER_stem_UTF_8_russian.c +694 -0
  47. data/ext/STEMMER_stem_UTF_8_spanish.c +1097 -0
  48. data/ext/STEMMER_stem_UTF_8_swedish.c +309 -0
  49. data/ext/STEMMER_stem_UTF_8_turkish.c +2205 -0
  50. data/ext/STEMMER_utilities.c +478 -0
  51. data/ext/analysis.c +1710 -0
  52. data/ext/analysis.h +266 -0
  53. data/ext/api.h +26 -0
  54. data/ext/array.c +125 -0
  55. data/ext/array.h +62 -0
  56. data/ext/bitvector.c +96 -0
  57. data/ext/bitvector.h +594 -0
  58. data/ext/bzlib.h +282 -0
  59. data/ext/bzlib_private.h +503 -0
  60. data/ext/compound_io.c +384 -0
  61. data/ext/config.h +52 -0
  62. data/ext/document.c +159 -0
  63. data/ext/document.h +63 -0
  64. data/ext/except.c +102 -0
  65. data/ext/except.h +176 -0
  66. data/ext/extconf.rb +15 -0
  67. data/ext/ferret.c +416 -0
  68. data/ext/ferret.h +94 -0
  69. data/ext/field_index.c +262 -0
  70. data/ext/field_index.h +52 -0
  71. data/ext/filter.c +157 -0
  72. data/ext/fs_store.c +493 -0
  73. data/ext/global.c +458 -0
  74. data/ext/global.h +302 -0
  75. data/ext/hash.c +524 -0
  76. data/ext/hash.h +515 -0
  77. data/ext/hashset.c +192 -0
  78. data/ext/hashset.h +215 -0
  79. data/ext/header.h +58 -0
  80. data/ext/helper.c +63 -0
  81. data/ext/helper.h +21 -0
  82. data/ext/index.c +6804 -0
  83. data/ext/index.h +935 -0
  84. data/ext/internal.h +1019 -0
  85. data/ext/lang.c +10 -0
  86. data/ext/lang.h +68 -0
  87. data/ext/libstemmer.h +79 -0
  88. data/ext/mempool.c +88 -0
  89. data/ext/mempool.h +43 -0
  90. data/ext/modules.h +190 -0
  91. data/ext/multimapper.c +351 -0
  92. data/ext/multimapper.h +60 -0
  93. data/ext/posh.c +1006 -0
  94. data/ext/posh.h +973 -0
  95. data/ext/priorityqueue.c +149 -0
  96. data/ext/priorityqueue.h +155 -0
  97. data/ext/q_boolean.c +1621 -0
  98. data/ext/q_const_score.c +162 -0
  99. data/ext/q_filtered_query.c +212 -0
  100. data/ext/q_fuzzy.c +280 -0
  101. data/ext/q_match_all.c +149 -0
  102. data/ext/q_multi_term.c +673 -0
  103. data/ext/q_parser.c +3103 -0
  104. data/ext/q_phrase.c +1206 -0
  105. data/ext/q_prefix.c +98 -0
  106. data/ext/q_range.c +682 -0
  107. data/ext/q_span.c +2390 -0
  108. data/ext/q_term.c +337 -0
  109. data/ext/q_wildcard.c +167 -0
  110. data/ext/r_analysis.c +2626 -0
  111. data/ext/r_index.c +3468 -0
  112. data/ext/r_qparser.c +635 -0
  113. data/ext/r_search.c +4490 -0
  114. data/ext/r_store.c +513 -0
  115. data/ext/r_utils.c +1131 -0
  116. data/ext/ram_store.c +476 -0
  117. data/ext/scanner.c +895 -0
  118. data/ext/scanner.h +36 -0
  119. data/ext/scanner_mb.c +6701 -0
  120. data/ext/scanner_utf8.c +4415 -0
  121. data/ext/search.c +1864 -0
  122. data/ext/search.h +953 -0
  123. data/ext/similarity.c +151 -0
  124. data/ext/similarity.h +89 -0
  125. data/ext/sort.c +786 -0
  126. data/ext/stem_ISO_8859_1_danish.h +16 -0
  127. data/ext/stem_ISO_8859_1_dutch.h +16 -0
  128. data/ext/stem_ISO_8859_1_english.h +16 -0
  129. data/ext/stem_ISO_8859_1_finnish.h +16 -0
  130. data/ext/stem_ISO_8859_1_french.h +16 -0
  131. data/ext/stem_ISO_8859_1_german.h +16 -0
  132. data/ext/stem_ISO_8859_1_hungarian.h +16 -0
  133. data/ext/stem_ISO_8859_1_italian.h +16 -0
  134. data/ext/stem_ISO_8859_1_norwegian.h +16 -0
  135. data/ext/stem_ISO_8859_1_porter.h +16 -0
  136. data/ext/stem_ISO_8859_1_portuguese.h +16 -0
  137. data/ext/stem_ISO_8859_1_spanish.h +16 -0
  138. data/ext/stem_ISO_8859_1_swedish.h +16 -0
  139. data/ext/stem_ISO_8859_2_romanian.h +16 -0
  140. data/ext/stem_KOI8_R_russian.h +16 -0
  141. data/ext/stem_UTF_8_danish.h +16 -0
  142. data/ext/stem_UTF_8_dutch.h +16 -0
  143. data/ext/stem_UTF_8_english.h +16 -0
  144. data/ext/stem_UTF_8_finnish.h +16 -0
  145. data/ext/stem_UTF_8_french.h +16 -0
  146. data/ext/stem_UTF_8_german.h +16 -0
  147. data/ext/stem_UTF_8_hungarian.h +16 -0
  148. data/ext/stem_UTF_8_italian.h +16 -0
  149. data/ext/stem_UTF_8_norwegian.h +16 -0
  150. data/ext/stem_UTF_8_porter.h +16 -0
  151. data/ext/stem_UTF_8_portuguese.h +16 -0
  152. data/ext/stem_UTF_8_romanian.h +16 -0
  153. data/ext/stem_UTF_8_russian.h +16 -0
  154. data/ext/stem_UTF_8_spanish.h +16 -0
  155. data/ext/stem_UTF_8_swedish.h +16 -0
  156. data/ext/stem_UTF_8_turkish.h +16 -0
  157. data/ext/stopwords.c +410 -0
  158. data/ext/store.c +698 -0
  159. data/ext/store.h +799 -0
  160. data/ext/symbol.c +10 -0
  161. data/ext/symbol.h +23 -0
  162. data/ext/term_vectors.c +73 -0
  163. data/ext/threading.h +31 -0
  164. data/ext/win32.h +62 -0
  165. data/lib/ferret.rb +30 -0
  166. data/lib/ferret/browser.rb +246 -0
  167. data/lib/ferret/browser/s/global.js +192 -0
  168. data/lib/ferret/browser/s/style.css +148 -0
  169. data/lib/ferret/browser/views/document/list.rhtml +49 -0
  170. data/lib/ferret/browser/views/document/show.rhtml +27 -0
  171. data/lib/ferret/browser/views/error/index.rhtml +7 -0
  172. data/lib/ferret/browser/views/help/index.rhtml +8 -0
  173. data/lib/ferret/browser/views/home/index.rhtml +29 -0
  174. data/lib/ferret/browser/views/layout.rhtml +22 -0
  175. data/lib/ferret/browser/views/term-vector/index.rhtml +4 -0
  176. data/lib/ferret/browser/views/term/index.rhtml +199 -0
  177. data/lib/ferret/browser/views/term/termdocs.rhtml +1 -0
  178. data/lib/ferret/browser/webrick.rb +14 -0
  179. data/lib/ferret/document.rb +130 -0
  180. data/lib/ferret/field_infos.rb +44 -0
  181. data/lib/ferret/field_symbol.rb +87 -0
  182. data/lib/ferret/index.rb +973 -0
  183. data/lib/ferret/number_tools.rb +157 -0
  184. data/lib/ferret/version.rb +3 -0
  185. data/setup.rb +1555 -0
  186. data/test/long_running/largefile/tc_largefile.rb +46 -0
  187. data/test/test_all.rb +5 -0
  188. data/test/test_helper.rb +29 -0
  189. data/test/test_installed.rb +1 -0
  190. data/test/threading/number_to_spoken.rb +132 -0
  191. data/test/threading/thread_safety_index_test.rb +88 -0
  192. data/test/threading/thread_safety_read_write_test.rb +73 -0
  193. data/test/threading/thread_safety_test.rb +133 -0
  194. data/test/unit/analysis/tc_analyzer.rb +550 -0
  195. data/test/unit/analysis/tc_token_stream.rb +653 -0
  196. data/test/unit/index/tc_index.rb +867 -0
  197. data/test/unit/index/tc_index_reader.rb +699 -0
  198. data/test/unit/index/tc_index_writer.rb +447 -0
  199. data/test/unit/index/th_doc.rb +332 -0
  200. data/test/unit/query_parser/tc_query_parser.rb +238 -0
  201. data/test/unit/search/tc_filter.rb +156 -0
  202. data/test/unit/search/tc_fuzzy_query.rb +147 -0
  203. data/test/unit/search/tc_index_searcher.rb +67 -0
  204. data/test/unit/search/tc_multi_searcher.rb +128 -0
  205. data/test/unit/search/tc_multiple_search_requests.rb +58 -0
  206. data/test/unit/search/tc_search_and_sort.rb +179 -0
  207. data/test/unit/search/tc_sort.rb +49 -0
  208. data/test/unit/search/tc_sort_field.rb +27 -0
  209. data/test/unit/search/tc_spans.rb +190 -0
  210. data/test/unit/search/tm_searcher.rb +436 -0
  211. data/test/unit/store/tc_fs_store.rb +115 -0
  212. data/test/unit/store/tc_ram_store.rb +35 -0
  213. data/test/unit/store/tm_store.rb +34 -0
  214. data/test/unit/store/tm_store_lock.rb +68 -0
  215. data/test/unit/tc_document.rb +81 -0
  216. data/test/unit/tc_field_symbol.rb +26 -0
  217. data/test/unit/ts_analysis.rb +2 -0
  218. data/test/unit/ts_index.rb +2 -0
  219. data/test/unit/ts_largefile.rb +4 -0
  220. data/test/unit/ts_query_parser.rb +2 -0
  221. data/test/unit/ts_search.rb +2 -0
  222. data/test/unit/ts_store.rb +2 -0
  223. data/test/unit/ts_utils.rb +2 -0
  224. data/test/unit/utils/tc_bit_vector.rb +295 -0
  225. data/test/unit/utils/tc_number_tools.rb +117 -0
  226. data/test/unit/utils/tc_priority_queue.rb +106 -0
  227. data/test/utils/content_generator.rb +226 -0
  228. metadata +319 -0
data/ext/hash.h ADDED
@@ -0,0 +1,515 @@
1
+ #ifndef FRT_HASH_H
2
+ #define FRT_HASH_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include "global.h"
9
+
10
+ /****************************************************************************
11
+ *
12
+ * Hash
13
+ *
14
+ ****************************************************************************/
15
+
16
+ #define FRT_HASH_MINSIZE 8
17
+ #define FRT_SLOW_DOWN 50000 /* stop increasing the hash table so quickly to
18
+ * conserve memory */
19
+
20
+ /**
21
+ * Return values for h_set
22
+ */
23
+ typedef enum
24
+ {
25
+ FRT_HASH_KEY_DOES_NOT_EXIST = 0,
26
+ FRT_HASH_KEY_EQUAL = 1,
27
+ FRT_HASH_KEY_SAME = 2
28
+ } FrtHashKeyStatus;
29
+
30
+ /**
31
+ * struct used internally to store values in the Hash
32
+ */
33
+ typedef struct
34
+ {
35
+ unsigned long hash;
36
+ void *key;
37
+ void *value;
38
+ } FrtHashEntry;
39
+
40
+ /**
41
+ * As the hash table is filled and entries are deleted, Dummy HashEntries are
42
+ * put in place. We therefor keep two counts. +size+ is the number active
43
+ * elements and +fill+ is the number of active elements together with the
44
+ * number of dummy elements. +fill+ is basically just kept around so that we
45
+ * know when to resize. The Hash is resized when more than two thirds of
46
+ * the Hash is Filled.
47
+ */
48
+ typedef struct FrtHash
49
+ {
50
+ int fill; /* num Active + num Dummy */
51
+ int size; /* num Active ie, num keys set */
52
+ int mask; /* capacity_of_table - 1 */
53
+ int ref_cnt;
54
+
55
+ /* table points to smalltable initially. If the table grows beyond 2/3 of
56
+ * HASH_MINSIZE it will point to newly malloced memory as it grows. */
57
+ FrtHashEntry *table;
58
+
59
+ /* When a Hash is created it needs an initial table to start if off.
60
+ * All Hashs will start with smalltable and then malloc a larger
61
+ * table as the Hash grows */
62
+ FrtHashEntry smalltable[FRT_HASH_MINSIZE];
63
+
64
+ /* the following function pointers are used internally and should not be
65
+ * used outside of the Hash methods */
66
+ FrtHashEntry *(*lookup_i)(struct FrtHash *self,
67
+ register const void *key);
68
+ unsigned long (*hash_i)(const void *key);
69
+ int (*eq_i)(const void *key1, const void *key2);
70
+ void (*free_key_i)(void *p);
71
+ void (*free_value_i)(void *p);
72
+ } FrtHash;
73
+
74
+ /**
75
+ * Hashing function type used by Hash. A function of this type must be
76
+ * passed to create a new Hash.
77
+ *
78
+ * @param key object to hash
79
+ * @return an unsigned 32-bit integer hash value
80
+ */
81
+ typedef unsigned long (*frt_hash_ft)(const void *key);
82
+
83
+ /**
84
+ * Equals function type used by Hash. A function of this type must be
85
+ * passed to create a new Hash.
86
+ */
87
+ typedef int (*frt_eq_ft)(const void *key1, const void *key2);
88
+
89
+ /**
90
+ * Determine a hash value for a string. The string must be null terminated
91
+ *
92
+ * @param str string to hash
93
+ * @return an unsigned long integer hash value
94
+ */
95
+ extern unsigned long frt_str_hash(const char *const str);
96
+
97
+ /**
98
+ * Determine a hash value for a pointer. Just cast the pointer to an unsigned
99
+ * long.
100
+ *
101
+ * @param ptr pointer to hash
102
+ * @return an unsigned long integer hash value
103
+ */
104
+ extern unsigned long frt_ptr_hash(const void *const ptr);
105
+
106
+ /**
107
+ * Determine if two pointers point to the same point in memory.
108
+ *
109
+ * @param q1 first pointer
110
+ * @param q2 second pointer
111
+ * @return true if the pointers are equal
112
+ */
113
+ extern int frt_ptr_eq(const void *q1, const void *q2);
114
+
115
+ /**
116
+ * Create a new Hash that uses any type of object as its key. The
117
+ * Hash will store all keys and values so if you want to destroy those
118
+ * values when the Hash is destroyed then you should pass free functions.
119
+ * NULL will suffice otherwise.
120
+ *
121
+ * @param hash function to determine the hash value of a key in the Hash
122
+ * @param eq function to determine the equality of to keys in the Hash
123
+ * @param free_key function to free the key stored in the Hash when an
124
+ * entry is deleted, replaced or when the Hash is destroyed. If you
125
+ * pass NULL in place of this parameter the key will not be destroyed.
126
+ * @param free_value function to free the value stored in the Hash when
127
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
128
+ * pass NULL in place of this parameter the value will not be destroyed.
129
+ * @return A newly allocated Hash
130
+ */
131
+ extern FrtHash *frt_h_new(frt_hash_ft hash,
132
+ frt_eq_ft eq,
133
+ frt_free_ft free_key,
134
+ frt_free_ft free_value);
135
+
136
+ /**
137
+ * Create a new Hash that uses null-terminated strings as its keys. The
138
+ * Hash will store all keys and values so if you want to destroy those
139
+ * values when the Hash is destroyed then you should pass free functions.
140
+ * NULL will suffice otherwise.
141
+ *
142
+ * @param free_key function to free the key stored in the Hash when an
143
+ * entry is deleted, replaced or when the Hash is destroyed. If you
144
+ * pass NULL in place of this parameter the key will not be destroyed.
145
+ * @param free_value function to free the value stored in the Hash when
146
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
147
+ * pass NULL in place of this parameter the value will not be destroyed.
148
+ * @return A newly allocated Hash
149
+ */
150
+ extern FrtHash *frt_h_new_str(frt_free_ft free_key,
151
+ frt_free_ft free_value);
152
+
153
+ /**
154
+ * Create a new Hash that uses integers as its keys. The Hash will store all
155
+ * values so if you want to destroy those values when the Hash is destroyed
156
+ * then you should pass a free function. NULL will suffice otherwise.
157
+ *
158
+ * @param free_value function to free the value stored in the Hash when
159
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
160
+ * pass NULL in place of this parameter the value will not be destroyed.
161
+ * @return A newly allocated Hash
162
+ */
163
+ extern FrtHash *frt_h_new_int(frt_free_ft free_value);
164
+
165
+ /**
166
+ * Create a new Hash that uses pointers as its keys. The Hash will store all
167
+ * values so if you want to destroy those values when the Hash is destroyed
168
+ * then you should pass a free function. NULL will suffice otherwise.
169
+ *
170
+ * @param free_value function to free the value stored in the Hash when
171
+ * an entry is deleted, replaced or when the Hash is destroyed. If you
172
+ * pass NULL in place of this parameter the value will not be destroyed.
173
+ * @return A newly allocated Hash
174
+ */
175
+ #define frt_h_new_ptr(free_value) frt_h_new_int(free_value)
176
+
177
+ /**
178
+ * Destroy the Hash. This function will also destroy all keys and values
179
+ * in the Hash depending on how the free_key and free_value were set.
180
+ *
181
+ * @param self the Hash to destroy
182
+ */
183
+ extern void frt_h_destroy(FrtHash *self);
184
+
185
+ /**
186
+ * Clear the Hash. This function will delete all keys and values from the
187
+ * hash table, also destroying all keys and values in the Hash depending
188
+ * on how the free_key and free_value were set.
189
+ *
190
+ * @param self the Hash to clear
191
+ */
192
+ extern void frt_h_clear(FrtHash *self);
193
+
194
+ /**
195
+ * Get the value in the Hash referenced by the key +key+.
196
+ *
197
+ * @param self the Hash to reference
198
+ * @param key the key to lookup
199
+ * @return the value referenced by the key +key+. If there is no value
200
+ * referenced by that key, NULL is returned.
201
+ */
202
+ extern void *frt_h_get(FrtHash *self, const void *key);
203
+
204
+ /**
205
+ * Delete the value in Hash referenced by the key +key+. When the value
206
+ * is deleted it is also destroyed along with the key depending on how
207
+ * free_key and free_value where set when the Hash was created. If you
208
+ * don't want to destroy the value use h_rem.
209
+ *
210
+ * This functions returns +true+ if the value was deleted successfully or
211
+ * false if the key was not found.
212
+ *
213
+ * @see h_rem
214
+ *
215
+ * @param self the Hash to reference
216
+ * @param key the key to lookup
217
+ * @return true if the object was successfully deleted or false if the key was
218
+ * not found
219
+ */
220
+ extern int frt_h_del(FrtHash *self, const void *key);
221
+
222
+ /**
223
+ * Remove the value in Hash referenced by the key +key+. When the value
224
+ * is removed it is returned rather than destroyed. The key however is
225
+ * destroyed using the free_key functions passed when the Hash is created
226
+ * if del_key is true.
227
+ *
228
+ * If you want the value to be destroyed, use the h_del function.
229
+ *
230
+ * @see h_del
231
+ *
232
+ * @param self the Hash to reference
233
+ * @param key the key to lookup
234
+ * @param del_key set to true if you want the key to be deleted when the value
235
+ * is removed from the Hash
236
+ * @return the value referenced by +key+ if it can be found or NULL otherwise
237
+ */
238
+ extern void *frt_h_rem(FrtHash *self, const void *key, bool del_key);
239
+
240
+ /**
241
+ * WARNING: this function may destroy an old value or key if the key already
242
+ * exists in the Hash, depending on how free_value and free_key were set
243
+ * for this Hash.
244
+ *
245
+ * Add the value +value+ to the Hash referencing it with key +key+.
246
+ *
247
+ * When a value is added to the Hash it replaces any value that
248
+ * might already be stored under that key. If free_value is already set then
249
+ * the old value will be freed using that function.
250
+ *
251
+ * Similarly the old key might replace be replaced by the new key if they are
252
+ * are equal (according to the Hash's eq function) but seperately
253
+ * allocated objects.
254
+ *
255
+ * @param self the Hash to add the value to
256
+ * @param key the key to use to reference the value
257
+ * @param value the value to add to the Hash
258
+ * @return one of three values;
259
+ * <pre>
260
+ * HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
261
+ * HASH_KEY_EQUAL the key existed and was seperately allocated.
262
+ * In this situation the old key will have been
263
+ * destroyed if free_key was set
264
+ * HASH_KEY_SAME the key was identical (same memory pointer) to
265
+ * the existing key so no key was freed
266
+ * </pre>
267
+ */
268
+ extern FrtHashKeyStatus frt_h_set(FrtHash *self,
269
+ const void *key, void *value);
270
+
271
+ /**
272
+ * Add the value +value+ to the Hash referencing it with key +key+. If
273
+ * the key already exists in the Hash, the value won't be added and the
274
+ * function will return false. Otherwise it will return true.
275
+ *
276
+ * @param self the Hash to add the value to
277
+ * @param key the key to use to reference the value
278
+ * @param value the value to add to the Hash
279
+ * @return true if the value was successfully added or false otherwise
280
+ */
281
+ extern int frt_h_set_safe(FrtHash *self, const void *key, void *value);
282
+
283
+ /**
284
+ * Return a hash entry object so you can handle the insert yourself. This can
285
+ * be used for performance reasons or for more control over how a value is
286
+ * added. Say, for example, you wanted to append a value to an array, or add a
287
+ * new array if non-existed, you could use this method by checking the value
288
+ * of the HashEntry returned.
289
+ *
290
+ * @param self the Hash to add the value to
291
+ * @param key the key to use to reference the value
292
+ * @param he HashEntry a pointer to the hash entry object now reserved for this
293
+ * value. Be sure to set both the *key* and the *value*
294
+ * @return true if the key was empty, false otherwise
295
+ */
296
+ extern FRT_INLINE bool frt_h_set_ext(FrtHash *self,
297
+ const void *key,
298
+ FrtHashEntry **he);
299
+
300
+ /**
301
+ * Check whether key +key+ exists in the Hash.
302
+ *
303
+ * @param self the Hash to check in
304
+ * @param key the key to check for in the Hash
305
+ * @return one of three values;
306
+ * <pre>
307
+ * 0 - HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
308
+ * 1 - HASH_KEY_EQUAL the key existed and was seperately
309
+ * allocated.
310
+ * 2 - HASH_KEY_SAME the key was identical (same memory
311
+ * pointer) to the existing key so no key was
312
+ * freed
313
+ * </pre>
314
+ * Note: the return value can be treated as a true/false value, ie 0 if the
315
+ * key doesn't exist, non-zero if it does.
316
+ */
317
+ extern FrtHashKeyStatus frt_h_has_key(FrtHash *self,
318
+ const void *key);
319
+
320
+ /**
321
+ * Get the value in the Hash referenced by an integer key +key+.
322
+ *
323
+ * @param self the Hash to reference
324
+ * @param key the integer key to lookup
325
+ * @return the value referenced by the key +key+. If there is no value
326
+ * referenced by that key, NULL is returned.
327
+ */
328
+ extern void *frt_h_get_int(FrtHash *self, const unsigned long key);
329
+
330
+ /**
331
+ * Delete the value in Hash referenced by the integer key +key+. When the
332
+ * value is deleted it is also destroyed using the free_value function. If you
333
+ * don't want to destroy the value use h_rem.
334
+ *
335
+ * This functions returns +true+ if the value was deleted successfully or
336
+ * false if the key was not found.
337
+ *
338
+ * @see h_rem
339
+ *
340
+ * @param self the Hash to reference
341
+ * @param key the integer key to lookup
342
+ * @return true if the object was successfully deleted or false if the key was
343
+ * not found
344
+ */
345
+ extern int frt_h_del_int(FrtHash *self, const unsigned long key);
346
+
347
+ /**
348
+ * Remove the value in Hash referenced by the integer key +key+. When the
349
+ * value is removed it is returned rather than destroyed.
350
+ *
351
+ * If you want the value to be destroyed, use the h_del function.
352
+ *
353
+ * @see h_del
354
+ *
355
+ * @param self the Hash to reference
356
+ * @param key the integer key to lookup
357
+ * @return the value referenced by +key+ if it can be found or NULL otherwise
358
+ */
359
+ extern void *frt_h_rem_int(FrtHash *self, const unsigned long key);
360
+
361
+ /**
362
+ * WARNING: this function may destroy an old value if the key already exists
363
+ * in the Hash, depending on how free_value was set for this Hash.
364
+ *
365
+ * Add the value +value+ to the Hash referencing it with an integer key
366
+ * +key+.
367
+ *
368
+ * When a value is added to the Hash it replaces any value that
369
+ * might already be stored under that key. If free_value is already set then
370
+ * the old value will be freed using that function.
371
+ *
372
+ * Similarly the old key might replace be replaced by the new key if they are
373
+ * are equal (according to the Hash's eq function) but seperately
374
+ * allocated objects.
375
+ *
376
+ * @param self the Hash to add the value to
377
+ * @param key the integer key to use to reference the value
378
+ * @param value the value to add to the Hash
379
+ * @return one of three values;
380
+ * <pre>
381
+ * HASH_KEY_DOES_NOT_EXIST there was no value stored with that key
382
+ * HASH_KEY_EQUAL the key existed and was seperately allocated.
383
+ * In this situation the old key will have been
384
+ * destroyed if free_key was set
385
+ * HASH_KEY_SAME the key was identical (same memory pointer) to
386
+ * the existing key so no key was freed
387
+ * </pre>
388
+ */
389
+ extern FrtHashKeyStatus frt_h_set_int(FrtHash *self,
390
+ const unsigned long key,
391
+ void *value);
392
+
393
+ /**
394
+ * Add the value +value+ to the Hash referencing it with integer key
395
+ * +key+. If the key already exists in the Hash, the value won't be added
396
+ * and the function will return false. Otherwise it will return true.
397
+ *
398
+ * @param self the Hash to add the value to
399
+ * @param key the integer key to use to reference the value
400
+ * @param value the value to add to the Hash
401
+ * @return true if the value was successfully added or false otherwise
402
+ */
403
+ extern int frt_h_set_safe_int(FrtHash *self,
404
+ const unsigned long key,
405
+ void *value);
406
+ /**
407
+ * Check whether integer key +key+ exists in the Hash.
408
+ *
409
+ * @param self the Hash to check in
410
+ * @param key the integer key to check for in the Hash
411
+ * @return true if the key exists in the Hash, false otherwise.
412
+ */
413
+ extern int frt_h_has_key_int(FrtHash *self, const unsigned long key);
414
+
415
+ typedef void (*frt_h_each_key_val_ft)(void *key, void *value, void *arg);
416
+
417
+ /**
418
+ * Run function +each_key_val+ on each key and value in the Hash. The third
419
+ * argument +arg+ will also be passed to +each_key_val+. If you need to pass
420
+ * more than one argument to the function you should pass a struct.
421
+ *
422
+ * example;
423
+ *
424
+ * // Lets say we have stored strings in a Hash and we want to put them
425
+ * // all into an array. First we need to create a struct to store the
426
+ * // strings;
427
+ *
428
+ * struct StringArray {
429
+ * char **strings;
430
+ * int cnt;
431
+ * int size;
432
+ * };
433
+ *
434
+ * static void add_string_ekv(void *key, void *value,
435
+ * struct StringArray *str_arr)
436
+ * {
437
+ * str_arr->strings[str_arr->cnt] = (char *)value;
438
+ * str_arr->cnt++;
439
+ * }
440
+ *
441
+ * struct StringArray *h_extract_strings(Hash *ht)
442
+ * {
443
+ * struct StringArray *str_arr = FRT_ALLOC(struct StringArray);
444
+ *
445
+ * str_arr->strings = FRT_ALLOC_N(char *, ht->size);
446
+ * str_arr->cnt = 0;
447
+ * str_arr->size = ht->size;
448
+ *
449
+ * h_each(ht, (h_each_key_val_ft)add_string_ekv, str_arr);
450
+ *
451
+ * return str_arr;
452
+ * }
453
+ *
454
+ * @param self the Hash to run the function on
455
+ * @param each_key_val function to run on on each key and value in the
456
+ * Hash
457
+ * @param arg an extra argument to pass to each_key_val each time it is called
458
+ */
459
+ extern void frt_h_each(FrtHash *self,
460
+ void (*each_key_val)(void *key, void *value, void *arg),
461
+ void *arg);
462
+
463
+ typedef void *(*frt_h_clone_ft)(void *val);
464
+ /**
465
+ * Clone the Hash as well as cloning each of the keys and values if you
466
+ * want to do a deep clone. To do a deep clone you will need to pass a
467
+ * clone_key function and/or a clone_value function.
468
+ *
469
+ * @param self the Hash to clone
470
+ * @param clone_key the function to clone the key with
471
+ * @param clone_value the function to clone the value with
472
+ * @return a clone of the original Hash
473
+ */
474
+ extern FrtHash *frt_h_clone(FrtHash *self,
475
+ frt_h_clone_ft clone_key,
476
+ frt_h_clone_ft clone_value);
477
+
478
+ /*
479
+ * The following functions should only be used in static Hash
480
+ * declarations
481
+ */
482
+ /**
483
+ * This is the lookup function for a hash table with non-string keys. The
484
+ * hash() and eq() methods used are stored in the hash table. This method will
485
+ * always return a HashEntry. If there is no entry with the given key then an
486
+ * empty entry will be returned with the key set to the key that was passed.
487
+ *
488
+ * @param ht the hash table to look in
489
+ * @param key the key to lookup
490
+ * @return the HashEntry that was found
491
+ */
492
+ extern FrtHashEntry *frt_h_lookup(FrtHash *ht,
493
+ register const void *key);
494
+
495
+ typedef FrtHashEntry *(*frt_h_lookup_ft)(FrtHash *ht,
496
+ register const void *key);
497
+
498
+ extern void frt_h_str_print_keys(FrtHash *ht, FILE *out);
499
+
500
+ /**
501
+ * The Hash implementation actually keeps a buffer of old hash tables around
502
+ * for performance reasons. If you want all memory freed when your program
503
+ * finishes (useful if you are using valgrind) you should call this method on
504
+ * exit.
505
+ *
506
+ * One way to do this is to register it with atexit(). This is done for you
507
+ * when you call +frt_init+.
508
+ */
509
+ extern void frt_hash_finalize();
510
+
511
+ #ifdef __cplusplus
512
+ } // extern "C"
513
+ #endif
514
+
515
+ #endif