ferret 0.9.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. data/MIT-LICENSE +1 -1
  2. data/README +12 -24
  3. data/Rakefile +38 -54
  4. data/TODO +14 -17
  5. data/ext/analysis.c +982 -823
  6. data/ext/analysis.h +133 -76
  7. data/ext/array.c +96 -58
  8. data/ext/array.h +40 -13
  9. data/ext/bitvector.c +476 -118
  10. data/ext/bitvector.h +264 -22
  11. data/ext/compound_io.c +217 -229
  12. data/ext/defines.h +49 -0
  13. data/ext/document.c +107 -317
  14. data/ext/document.h +31 -65
  15. data/ext/except.c +81 -36
  16. data/ext/except.h +117 -55
  17. data/ext/extconf.rb +2 -9
  18. data/ext/ferret.c +211 -104
  19. data/ext/ferret.h +22 -11
  20. data/ext/filter.c +97 -82
  21. data/ext/fs_store.c +348 -367
  22. data/ext/global.c +226 -188
  23. data/ext/global.h +44 -26
  24. data/ext/hash.c +474 -391
  25. data/ext/hash.h +441 -68
  26. data/ext/hashset.c +124 -96
  27. data/ext/hashset.h +169 -20
  28. data/ext/helper.c +56 -5
  29. data/ext/helper.h +7 -0
  30. data/ext/inc/lang.h +29 -49
  31. data/ext/inc/threading.h +31 -0
  32. data/ext/ind.c +288 -278
  33. data/ext/ind.h +68 -0
  34. data/ext/index.c +5688 -0
  35. data/ext/index.h +663 -616
  36. data/ext/lang.h +29 -49
  37. data/ext/libstemmer.c +3 -3
  38. data/ext/mem_pool.c +84 -0
  39. data/ext/mem_pool.h +35 -0
  40. data/ext/posh.c +1006 -0
  41. data/ext/posh.h +1007 -0
  42. data/ext/priorityqueue.c +117 -194
  43. data/ext/priorityqueue.h +135 -39
  44. data/ext/q_boolean.c +1305 -1108
  45. data/ext/q_const_score.c +106 -93
  46. data/ext/q_filtered_query.c +138 -135
  47. data/ext/q_fuzzy.c +206 -242
  48. data/ext/q_match_all.c +94 -80
  49. data/ext/q_multi_term.c +663 -0
  50. data/ext/q_parser.c +667 -593
  51. data/ext/q_phrase.c +992 -555
  52. data/ext/q_prefix.c +72 -61
  53. data/ext/q_range.c +235 -210
  54. data/ext/q_span.c +1480 -1166
  55. data/ext/q_term.c +273 -246
  56. data/ext/q_wildcard.c +127 -114
  57. data/ext/r_analysis.c +1720 -711
  58. data/ext/r_index.c +3049 -0
  59. data/ext/r_qparser.c +433 -146
  60. data/ext/r_search.c +2934 -1993
  61. data/ext/r_store.c +372 -143
  62. data/ext/r_utils.c +941 -0
  63. data/ext/ram_store.c +330 -326
  64. data/ext/search.c +1291 -668
  65. data/ext/search.h +403 -702
  66. data/ext/similarity.c +91 -113
  67. data/ext/similarity.h +45 -30
  68. data/ext/sort.c +721 -484
  69. data/ext/stopwords.c +361 -273
  70. data/ext/store.c +556 -58
  71. data/ext/store.h +706 -126
  72. data/ext/tags +3578 -2780
  73. data/ext/term_vectors.c +352 -0
  74. data/ext/threading.h +31 -0
  75. data/ext/win32.h +54 -0
  76. data/lib/ferret.rb +5 -17
  77. data/lib/ferret/document.rb +130 -2
  78. data/lib/ferret/index.rb +577 -26
  79. data/lib/ferret/number_tools.rb +157 -0
  80. data/lib/ferret_version.rb +3 -0
  81. data/test/test_helper.rb +5 -13
  82. data/test/unit/analysis/tc_analyzer.rb +513 -1
  83. data/test/unit/analysis/{ctc_tokenstream.rb → tc_token_stream.rb} +23 -0
  84. data/test/unit/index/tc_index.rb +183 -240
  85. data/test/unit/index/tc_index_reader.rb +312 -479
  86. data/test/unit/index/tc_index_writer.rb +397 -13
  87. data/test/unit/index/th_doc.rb +269 -206
  88. data/test/unit/query_parser/tc_query_parser.rb +40 -33
  89. data/test/unit/search/tc_filter.rb +59 -71
  90. data/test/unit/search/tc_fuzzy_query.rb +24 -16
  91. data/test/unit/search/tc_index_searcher.rb +23 -201
  92. data/test/unit/search/tc_multi_searcher.rb +78 -226
  93. data/test/unit/search/tc_search_and_sort.rb +93 -81
  94. data/test/unit/search/tc_sort.rb +23 -23
  95. data/test/unit/search/tc_sort_field.rb +7 -7
  96. data/test/unit/search/tc_spans.rb +51 -47
  97. data/test/unit/search/tm_searcher.rb +339 -0
  98. data/test/unit/store/tc_fs_store.rb +1 -1
  99. data/test/unit/store/tm_store_lock.rb +3 -3
  100. data/test/unit/tc_document.rb +81 -0
  101. data/test/unit/ts_analysis.rb +1 -1
  102. data/test/unit/ts_utils.rb +1 -1
  103. data/test/unit/utils/tc_bit_vector.rb +288 -0
  104. data/test/unit/utils/tc_number_tools.rb +117 -0
  105. data/test/unit/utils/tc_priority_queue.rb +106 -0
  106. metadata +140 -301
  107. data/CHANGELOG +0 -9
  108. data/ext/dummy.exe +0 -0
  109. data/ext/field.c +0 -408
  110. data/ext/frtio.h +0 -13
  111. data/ext/inc/except.h +0 -90
  112. data/ext/index_io.c +0 -382
  113. data/ext/index_rw.c +0 -2658
  114. data/ext/lang.c +0 -41
  115. data/ext/nix_io.c +0 -134
  116. data/ext/q_multi_phrase.c +0 -380
  117. data/ext/r_doc.c +0 -582
  118. data/ext/r_index_io.c +0 -1021
  119. data/ext/r_term.c +0 -219
  120. data/ext/term.c +0 -820
  121. data/ext/termdocs.c +0 -611
  122. data/ext/vector.c +0 -637
  123. data/ext/w32_io.c +0 -150
  124. data/lib/ferret/analysis.rb +0 -11
  125. data/lib/ferret/analysis/analyzers.rb +0 -112
  126. data/lib/ferret/analysis/standard_tokenizer.rb +0 -71
  127. data/lib/ferret/analysis/token.rb +0 -100
  128. data/lib/ferret/analysis/token_filters.rb +0 -86
  129. data/lib/ferret/analysis/token_stream.rb +0 -26
  130. data/lib/ferret/analysis/tokenizers.rb +0 -112
  131. data/lib/ferret/analysis/word_list_loader.rb +0 -27
  132. data/lib/ferret/document/document.rb +0 -152
  133. data/lib/ferret/document/field.rb +0 -312
  134. data/lib/ferret/index/compound_file_io.rb +0 -338
  135. data/lib/ferret/index/document_writer.rb +0 -289
  136. data/lib/ferret/index/field_infos.rb +0 -279
  137. data/lib/ferret/index/fields_io.rb +0 -181
  138. data/lib/ferret/index/index.rb +0 -675
  139. data/lib/ferret/index/index_file_names.rb +0 -33
  140. data/lib/ferret/index/index_reader.rb +0 -503
  141. data/lib/ferret/index/index_writer.rb +0 -534
  142. data/lib/ferret/index/multi_reader.rb +0 -377
  143. data/lib/ferret/index/multiple_term_doc_pos_enum.rb +0 -98
  144. data/lib/ferret/index/segment_infos.rb +0 -130
  145. data/lib/ferret/index/segment_merge_info.rb +0 -49
  146. data/lib/ferret/index/segment_merge_queue.rb +0 -16
  147. data/lib/ferret/index/segment_merger.rb +0 -358
  148. data/lib/ferret/index/segment_reader.rb +0 -412
  149. data/lib/ferret/index/segment_term_enum.rb +0 -169
  150. data/lib/ferret/index/segment_term_vector.rb +0 -58
  151. data/lib/ferret/index/term.rb +0 -53
  152. data/lib/ferret/index/term_buffer.rb +0 -83
  153. data/lib/ferret/index/term_doc_enum.rb +0 -291
  154. data/lib/ferret/index/term_enum.rb +0 -52
  155. data/lib/ferret/index/term_info.rb +0 -37
  156. data/lib/ferret/index/term_infos_io.rb +0 -321
  157. data/lib/ferret/index/term_vector_offset_info.rb +0 -20
  158. data/lib/ferret/index/term_vectors_io.rb +0 -553
  159. data/lib/ferret/query_parser.rb +0 -312
  160. data/lib/ferret/query_parser/query_parser.tab.rb +0 -928
  161. data/lib/ferret/search.rb +0 -50
  162. data/lib/ferret/search/boolean_clause.rb +0 -100
  163. data/lib/ferret/search/boolean_query.rb +0 -299
  164. data/lib/ferret/search/boolean_scorer.rb +0 -294
  165. data/lib/ferret/search/caching_wrapper_filter.rb +0 -40
  166. data/lib/ferret/search/conjunction_scorer.rb +0 -99
  167. data/lib/ferret/search/disjunction_sum_scorer.rb +0 -205
  168. data/lib/ferret/search/exact_phrase_scorer.rb +0 -32
  169. data/lib/ferret/search/explanation.rb +0 -41
  170. data/lib/ferret/search/field_cache.rb +0 -215
  171. data/lib/ferret/search/field_doc.rb +0 -31
  172. data/lib/ferret/search/field_sorted_hit_queue.rb +0 -184
  173. data/lib/ferret/search/filter.rb +0 -11
  174. data/lib/ferret/search/filtered_query.rb +0 -130
  175. data/lib/ferret/search/filtered_term_enum.rb +0 -79
  176. data/lib/ferret/search/fuzzy_query.rb +0 -154
  177. data/lib/ferret/search/fuzzy_term_enum.rb +0 -247
  178. data/lib/ferret/search/hit_collector.rb +0 -34
  179. data/lib/ferret/search/hit_queue.rb +0 -11
  180. data/lib/ferret/search/index_searcher.rb +0 -200
  181. data/lib/ferret/search/match_all_query.rb +0 -104
  182. data/lib/ferret/search/multi_phrase_query.rb +0 -216
  183. data/lib/ferret/search/multi_searcher.rb +0 -261
  184. data/lib/ferret/search/multi_term_query.rb +0 -65
  185. data/lib/ferret/search/non_matching_scorer.rb +0 -22
  186. data/lib/ferret/search/phrase_positions.rb +0 -55
  187. data/lib/ferret/search/phrase_query.rb +0 -214
  188. data/lib/ferret/search/phrase_scorer.rb +0 -152
  189. data/lib/ferret/search/prefix_query.rb +0 -54
  190. data/lib/ferret/search/query.rb +0 -140
  191. data/lib/ferret/search/query_filter.rb +0 -51
  192. data/lib/ferret/search/range_filter.rb +0 -103
  193. data/lib/ferret/search/range_query.rb +0 -139
  194. data/lib/ferret/search/req_excl_scorer.rb +0 -125
  195. data/lib/ferret/search/req_opt_sum_scorer.rb +0 -70
  196. data/lib/ferret/search/score_doc.rb +0 -38
  197. data/lib/ferret/search/score_doc_comparator.rb +0 -114
  198. data/lib/ferret/search/scorer.rb +0 -91
  199. data/lib/ferret/search/similarity.rb +0 -278
  200. data/lib/ferret/search/sloppy_phrase_scorer.rb +0 -47
  201. data/lib/ferret/search/sort.rb +0 -112
  202. data/lib/ferret/search/sort_comparator.rb +0 -60
  203. data/lib/ferret/search/sort_field.rb +0 -91
  204. data/lib/ferret/search/spans.rb +0 -12
  205. data/lib/ferret/search/spans/near_spans_enum.rb +0 -304
  206. data/lib/ferret/search/spans/span_first_query.rb +0 -79
  207. data/lib/ferret/search/spans/span_near_query.rb +0 -108
  208. data/lib/ferret/search/spans/span_not_query.rb +0 -130
  209. data/lib/ferret/search/spans/span_or_query.rb +0 -176
  210. data/lib/ferret/search/spans/span_query.rb +0 -25
  211. data/lib/ferret/search/spans/span_scorer.rb +0 -74
  212. data/lib/ferret/search/spans/span_term_query.rb +0 -105
  213. data/lib/ferret/search/spans/span_weight.rb +0 -84
  214. data/lib/ferret/search/spans/spans_enum.rb +0 -44
  215. data/lib/ferret/search/term_query.rb +0 -128
  216. data/lib/ferret/search/term_scorer.rb +0 -183
  217. data/lib/ferret/search/top_docs.rb +0 -36
  218. data/lib/ferret/search/top_field_docs.rb +0 -17
  219. data/lib/ferret/search/weight.rb +0 -54
  220. data/lib/ferret/search/wildcard_query.rb +0 -26
  221. data/lib/ferret/search/wildcard_term_enum.rb +0 -61
  222. data/lib/ferret/stemmers.rb +0 -1
  223. data/lib/ferret/stemmers/porter_stemmer.rb +0 -218
  224. data/lib/ferret/store.rb +0 -5
  225. data/lib/ferret/store/buffered_index_io.rb +0 -190
  226. data/lib/ferret/store/directory.rb +0 -141
  227. data/lib/ferret/store/fs_store.rb +0 -381
  228. data/lib/ferret/store/index_io.rb +0 -245
  229. data/lib/ferret/store/ram_store.rb +0 -286
  230. data/lib/ferret/utils.rb +0 -8
  231. data/lib/ferret/utils/bit_vector.rb +0 -123
  232. data/lib/ferret/utils/date_tools.rb +0 -138
  233. data/lib/ferret/utils/number_tools.rb +0 -91
  234. data/lib/ferret/utils/parameter.rb +0 -41
  235. data/lib/ferret/utils/priority_queue.rb +0 -120
  236. data/lib/ferret/utils/string_helper.rb +0 -47
  237. data/lib/ferret/utils/thread_local.rb +0 -28
  238. data/lib/ferret/utils/weak_key_hash.rb +0 -60
  239. data/lib/rferret.rb +0 -37
  240. data/rake_utils/code_statistics.rb +0 -106
  241. data/test/benchmark/tb_ram_store.rb +0 -76
  242. data/test/benchmark/tb_rw_vint.rb +0 -26
  243. data/test/functional/thread_safety_index_test.rb +0 -81
  244. data/test/functional/thread_safety_test.rb +0 -137
  245. data/test/longrunning/tc_numbertools.rb +0 -60
  246. data/test/longrunning/tm_store.rb +0 -19
  247. data/test/unit/analysis/ctc_analyzer.rb +0 -532
  248. data/test/unit/analysis/data/wordfile +0 -6
  249. data/test/unit/analysis/rtc_letter_tokenizer.rb +0 -20
  250. data/test/unit/analysis/rtc_lower_case_filter.rb +0 -20
  251. data/test/unit/analysis/rtc_lower_case_tokenizer.rb +0 -27
  252. data/test/unit/analysis/rtc_per_field_analyzer_wrapper.rb +0 -39
  253. data/test/unit/analysis/rtc_porter_stem_filter.rb +0 -16
  254. data/test/unit/analysis/rtc_standard_analyzer.rb +0 -20
  255. data/test/unit/analysis/rtc_standard_tokenizer.rb +0 -20
  256. data/test/unit/analysis/rtc_stop_analyzer.rb +0 -20
  257. data/test/unit/analysis/rtc_stop_filter.rb +0 -14
  258. data/test/unit/analysis/rtc_white_space_analyzer.rb +0 -21
  259. data/test/unit/analysis/rtc_white_space_tokenizer.rb +0 -20
  260. data/test/unit/analysis/rtc_word_list_loader.rb +0 -32
  261. data/test/unit/analysis/tc_token.rb +0 -25
  262. data/test/unit/document/rtc_field.rb +0 -28
  263. data/test/unit/document/tc_document.rb +0 -47
  264. data/test/unit/document/tc_field.rb +0 -98
  265. data/test/unit/index/rtc_compound_file_io.rb +0 -107
  266. data/test/unit/index/rtc_field_infos.rb +0 -127
  267. data/test/unit/index/rtc_fields_io.rb +0 -167
  268. data/test/unit/index/rtc_multiple_term_doc_pos_enum.rb +0 -83
  269. data/test/unit/index/rtc_segment_infos.rb +0 -74
  270. data/test/unit/index/rtc_segment_term_docs.rb +0 -17
  271. data/test/unit/index/rtc_segment_term_enum.rb +0 -60
  272. data/test/unit/index/rtc_segment_term_vector.rb +0 -71
  273. data/test/unit/index/rtc_term_buffer.rb +0 -57
  274. data/test/unit/index/rtc_term_info.rb +0 -19
  275. data/test/unit/index/rtc_term_infos_io.rb +0 -192
  276. data/test/unit/index/rtc_term_vectors_io.rb +0 -108
  277. data/test/unit/index/tc_term.rb +0 -27
  278. data/test/unit/index/tc_term_voi.rb +0 -18
  279. data/test/unit/search/rtc_similarity.rb +0 -37
  280. data/test/unit/search/rtc_sort_field.rb +0 -14
  281. data/test/unit/search/tc_multi_searcher2.rb +0 -126
  282. data/test/unit/store/rtc_fs_store.rb +0 -62
  283. data/test/unit/store/rtc_ram_store.rb +0 -15
  284. data/test/unit/store/rtm_store.rb +0 -150
  285. data/test/unit/store/rtm_store_lock.rb +0 -2
  286. data/test/unit/ts_document.rb +0 -2
  287. data/test/unit/utils/rtc_bit_vector.rb +0 -73
  288. data/test/unit/utils/rtc_date_tools.rb +0 -50
  289. data/test/unit/utils/rtc_number_tools.rb +0 -59
  290. data/test/unit/utils/rtc_parameter.rb +0 -40
  291. data/test/unit/utils/rtc_priority_queue.rb +0 -62
  292. data/test/unit/utils/rtc_string_helper.rb +0 -21
  293. data/test/unit/utils/rtc_thread.rb +0 -61
  294. data/test/unit/utils/rtc_weak_key_hash.rb +0 -25
  295. data/test/utils/number_to_spoken.rb +0 -132
data/ext/helper.c CHANGED
@@ -3,9 +3,60 @@
3
3
  inline int hlp_string_diff(register const char *const s1,
4
4
  register const char *const s2)
5
5
  {
6
- register int i = 0;
7
- while (s1[i] && (s1[i] == s2[i])) {
8
- i++;
9
- }
10
- return i;
6
+ register int i = 0;
7
+ while (s1[i] && (s1[i] == s2[i])) {
8
+ i++;
9
+ }
10
+ return i;
11
+ }
12
+
13
+ f_i32 float2int(float f)
14
+ {
15
+ union { f_i32 i; float f; } tmp;
16
+ tmp.f = f;
17
+ return POSH_LittleU32(tmp.i);
18
+ }
19
+
20
+ float int2float(f_i32 i32)
21
+ {
22
+ union { f_i32 i; float f; } tmp;
23
+ tmp.i = POSH_LittleU32(i32);
24
+ return tmp.f;
25
+ }
26
+
27
+ float byte2float(unsigned char b)
28
+ {
29
+ if (b == 0) {
30
+ return 0.0;
31
+ }
32
+ else {
33
+ f_u32 mantissa = b & 0x07;
34
+ f_u32 exponent = (b >> 3) & 0x1f;
35
+
36
+ return int2float((mantissa << 21) | ((exponent + 48) << 24));
37
+ }
38
+ }
39
+
40
+ unsigned char float2byte(float f)
41
+ {
42
+ if (f <= 0.0) {
43
+ return 0;
44
+ }
45
+ else {
46
+ /* correctly order the bytes for encoding */
47
+ f_u32 i32 = float2int(f);
48
+ int mantissa = (i32 & 0xEf0000) >> 21;
49
+ int exponent = ((i32 >> 24) - 48);
50
+
51
+ if (exponent > 0x1f) {
52
+ exponent = 0x1f; /* 0x1f = 31 = 0b00011111 */
53
+ mantissa = 0x07; /* 0x07 = 7 = 0b00000111 */
54
+ }
55
+
56
+ if (exponent < 0) {
57
+ exponent = 0;
58
+ mantissa = 1;
59
+ }
60
+ return ((exponent<<3) | mantissa);
61
+ }
11
62
  }
data/ext/helper.h CHANGED
@@ -1,6 +1,13 @@
1
1
  #ifndef FRT_HELPER_H
2
2
  #define FRT_HELPER_H
3
3
 
4
+ #include "defines.h"
5
+
4
6
  extern inline int hlp_string_diff(register const char *const s1,
5
7
  register const char *const s2);
8
+ extern f_i32 float2int(float f);
9
+ extern float int2float(f_i32 i32);
10
+ extern float byte2float(unsigned char b);
11
+ extern unsigned char float2byte(float f);
12
+
6
13
  #endif
data/ext/inc/lang.h CHANGED
@@ -2,60 +2,40 @@
2
2
  #define FRT_LANG_H
3
3
 
4
4
  #include <ruby.h>
5
- #include "hash.h"
5
+ #include <stdarg.h>
6
6
 
7
- #define FERRET_EXT
7
+ #define frt_malloc xmalloc
8
+ #define frt_calloc(n) xcalloc(n, 1)
9
+ #define frt_realloc xrealloc
8
10
 
9
- #define MAX_ERROR_LEN 2048
11
+ #ifdef FRT_HAS_ISO_VARARGS
12
+ /* C99-compliant compiler */
10
13
 
11
- typedef LONG_LONG llong;
12
- typedef unsigned LONG_LONG ullong;
14
+ # define FRT_EXIT(...) frt_rb_raise(__FILE__, __LINE__, __func__, __VA_ARGS__)
15
+ extern void frt_rb_raise(const char *file, int line_num, const char *func,
16
+ const char *err_type, const char *fmt, ...);
13
17
 
14
- #ifdef WIN32
15
- # undef close
16
- # undef rename
17
- extern void eprintf(VALUE etype, const char *fmt, ...);
18
+ # define V_FRT_EXIT(err_type, fmt, args) \
19
+ vfrt_rb_raise(__FILE__, __LINE__, __func__, err_type, fmt, args)
20
+ extern void vfrt_rb_raise(const char *file, int line_num, const char *func,
21
+ const char *err_type, const char *fmt, va_list args);
22
+
23
+ #elif defined(FRT_HAS_GNUC_VARARGS)
24
+ /* gcc has an extension */
25
+
26
+ # define FRT_EXIT(args...) frt_rb_raise(__FILE__, __LINE__, __func__, ##args)
27
+ extern void frt_rb_raise(const char *file, int line_num, const char *func,
28
+ const char *err_type, const char *fmt, ...);
29
+
30
+ # define V_FRT_EXIT(err_type, fmt, args) \
31
+ vfrt_rb_raise(__FILE__, __LINE__, __func__, err_type, fmt, args)
32
+ extern void vfrt_rb_raise(const char *file, int line_num, const char *func,
33
+ const char *err_type, const char *fmt, va_list args);
18
34
  #else
19
- # define eprintf(...) ft_raise(__FILE__, __LINE__, __VA_ARGS__)
35
+ /* Can't do VARARGS */
36
+
37
+ extern void FRT_EXIT(const char *err_type, const char *fmt, ...);
38
+ extern void V_FRT_EXIT(const char *err_type, const char *fmt, va_list args);
20
39
  #endif
21
- extern void ft_raise(char *file, int line_num, VALUE etype, const char *fmt, ...);
22
- extern void weprintf(const char *fmt, ...);
23
- extern char *progname(void);
24
- extern void setprogname(const char *str);
25
-
26
- extern VALUE cQueryParseException;
27
-
28
- #define EXCEPTION_CODE rb_eStandardError
29
- //#define IO_ERROR rb_eIOError
30
- //#define ARG_ERROR rb_eArgError
31
- //#define EOF_ERROR rb_eEOFError
32
- //#define UNSUPPORTED_ERROR rb_eNotImpError
33
- //#define STATE_ERROR rb_eException
34
- //#define PARSE_ERROR cQueryParseException
35
- //#define MEM_ERROR rb_eNoMemError
36
-
37
- typedef void * mutex_t;
38
- typedef struct HshTable * thread_key_t;
39
- typedef int thread_once_t;
40
- #define MUTEX_INITIALIZER NULL
41
- #define MUTEX_RECURSIVE_INITIALIZER NULL
42
- #define THREAD_ONCE_INIT 1;
43
- #define mutex_init(a, b)
44
- #define mutex_lock(a)
45
- #define mutex_trylock(a)
46
- #define mutex_unlock(a)
47
- #define mutex_destroy(a)
48
- #define thread_key_create(a, b) frt_thread_key_create(a, b)
49
- #define thread_key_delete(a) frt_thread_key_delete(a)
50
- #define thread_setspecific(a, b) frt_thread_setspecific(a, b)
51
- #define thread_getspecific(a) frt_thread_getspecific(a)
52
- #define thread_exit(a)
53
- #define thread_once(a, b) frt_thread_once(a, b)
54
-
55
- void frt_thread_once(int *once_control, void (*init_routine) (void));
56
- void frt_thread_key_create(thread_key_t *key, void (*destr_function) (void *));
57
- void frt_thread_key_delete(thread_key_t key);
58
- void frt_thread_setspecific(thread_key_t key, const void *pointer);
59
- void *frt_thread_getspecific(thread_key_t key);
60
40
 
61
41
  #endif
@@ -0,0 +1,31 @@
1
+ #ifndef FRT_THREADING_H
2
+ #define FRT_THREADING_H
3
+
4
+ #include "hash.h"
5
+ #define UNTHREADED 1
6
+
7
+ typedef void * mutex_t;
8
+ typedef struct HashTable *thread_key_t;
9
+ typedef int thread_once_t;
10
+ #define MUTEX_INITIALIZER NULL
11
+ #define MUTEX_RECURSIVE_INITIALIZER NULL
12
+ #define THREAD_ONCE_INIT 1;
13
+ #define mutex_init(a, b)
14
+ #define mutex_lock(a)
15
+ #define mutex_trylock(a)
16
+ #define mutex_unlock(a)
17
+ #define mutex_destroy(a)
18
+ #define thread_key_create(a, b) frt_thread_key_create(a, b)
19
+ #define thread_key_delete(a) frt_thread_key_delete(a)
20
+ #define thread_setspecific(a, b) frt_thread_setspecific(a, b)
21
+ #define thread_getspecific(a) frt_thread_getspecific(a)
22
+ #define thread_exit(a)
23
+ #define thread_once(a, b) frt_thread_once(a, b)
24
+
25
+ void frt_thread_once(int *once_control, void (*init_routine)(void));
26
+ void frt_thread_key_create(thread_key_t *key, void (*destr_function)(void *));
27
+ void frt_thread_key_delete(thread_key_t key);
28
+ void frt_thread_setspecific(thread_key_t key, const void *pointer);
29
+ void *frt_thread_getspecific(thread_key_t key);
30
+
31
+ #endif
data/ext/ind.c CHANGED
@@ -1,4 +1,5 @@
1
- #include "search.h"
1
+ #include "ind.h"
2
+ #include "array.h"
2
3
  #include <string.h>
3
4
 
4
5
 
@@ -7,402 +8,411 @@ static char * const NON_UNIQUE_KEY_ERROR_MSG = "Tried to use a key that was not
7
8
  static const char *ID_STRING = "id";
8
9
 
9
10
  #define INDEX_CLOSE_READER(self) do {\
10
- if (self->sea) {\
11
- sea_close(self->sea);\
12
- self->sea = NULL;\
13
- self->ir = NULL;\
14
- } else if (self->ir) {\
15
- ir_close(self->ir);\
16
- self->ir = NULL;\
17
- }\
11
+ if (self->sea) {\
12
+ searcher_close(self->sea);\
13
+ self->sea = NULL;\
14
+ self->ir = NULL;\
15
+ } else if (self->ir) {\
16
+ ir_close(self->ir);\
17
+ self->ir = NULL;\
18
+ }\
18
19
  } while (0)
19
20
 
20
21
  #define AUTOFLUSH_IR if (self->auto_flush) ir_commit(self->ir);\
21
- else self->has_writes = true
22
+ else self->has_writes = true
22
23
 
23
24
  #define AUTOFLUSH_IW \
24
- if (self->auto_flush) {\
25
- iw_close(self->iw);\
26
- self->iw = NULL;\
27
- } else self->has_writes = true
25
+ if (self->auto_flush) {\
26
+ iw_close(self->iw);\
27
+ self->iw = NULL;\
28
+ } else self->has_writes = true
28
29
 
29
30
  void index_auto_flush_ir(Index *self)
30
31
  {
31
- AUTOFLUSH_IR;
32
+ AUTOFLUSH_IR;
32
33
  }
33
34
 
34
35
  void index_auto_flush_iw(Index *self)
35
36
  {
36
- AUTOFLUSH_IW;
37
+ AUTOFLUSH_IW;
37
38
  }
38
39
 
39
- Index *index_create(Store *store, Analyzer *analyzer, HashSet *def_fields,
40
- bool create)
40
+ Index *index_new(Store *store, Analyzer *analyzer, HashSet *def_fields,
41
+ bool create)
41
42
  {
42
- HashSet *all_fields = hs_str_create(&free);
43
- Index *self = ALLOC(Index);
44
- ZEROSET(self, Index, 1);
45
- mutex_init(&self->mutex, NULL);
46
- self->has_writes = false;
47
- if (store) {
48
- self->store = store;
49
- ref(store);
50
- } else {
51
- self->store = open_ram_store();
52
- create = true;
53
- }
54
- if (analyzer) {
55
- self->analyzer = analyzer;
56
- ref(analyzer);
57
- } else {
58
- self->analyzer = mb_standard_analyzer_create(true);
59
- }
60
- self->use_compound_file = true;
61
-
62
- if (create) {
63
- ref(self->analyzer);
64
- self->iw = iw_open(self->store, self->analyzer, create);
65
- iw_close(self->iw);
66
- self->iw = NULL;
67
- }
68
-
69
- /* options */
70
- self->key = NULL;
71
- self->id_field = (char *)ID_STRING;
72
- self->def_field = (char *)ID_STRING;
73
- self->auto_flush = false;
74
- self->check_latest = true;
75
-
76
- ref(self->analyzer);
77
- self->qp = qp_create(all_fields, def_fields, self->analyzer);
78
- /* Index is a convenience class so set qp convenience options */
79
- self->qp->allow_any_fields = true;
80
- self->qp->clean_str = true;
81
- self->qp->handle_parse_errors = true;
82
-
83
- return self;
43
+ HashSet *all_fields = hs_new_str(&free);
44
+ Index *self = ALLOC_AND_ZERO(Index);
45
+ self->config = default_config;
46
+ mutex_init(&self->mutex, NULL);
47
+ self->has_writes = false;
48
+ if (store) {
49
+ self->store = store;
50
+ REF(store);
51
+ } else {
52
+ self->store = open_ram_store();
53
+ create = true;
54
+ }
55
+ if (analyzer) {
56
+ self->analyzer = analyzer;
57
+ REF(analyzer);
58
+ } else {
59
+ self->analyzer = mb_standard_analyzer_new(true);
60
+ }
61
+
62
+ if (create) {
63
+ FieldInfos *fis = fis_new(STORE_YES, INDEX_YES,
64
+ TERM_VECTOR_WITH_POSITIONS_OFFSETS);
65
+ index_create(store, fis);
66
+ fis_deref(fis);
67
+ }
68
+
69
+ /* options */
70
+ self->key = NULL;
71
+ self->id_field = estrdup(ID_STRING);
72
+ self->def_field = estrdup(ID_STRING);
73
+ self->auto_flush = false;
74
+ self->check_latest = true;
75
+
76
+ REF(self->analyzer);
77
+ self->qp = qp_new(all_fields, def_fields, self->analyzer);
78
+ /* Index is a convenience class so set qp convenience options */
79
+ self->qp->allow_any_fields = true;
80
+ self->qp->clean_str = true;
81
+ self->qp->handle_parse_errors = true;
82
+
83
+ return self;
84
84
  }
85
85
 
86
86
  void index_destroy(Index *self)
87
87
  {
88
- mutex_destroy(&self->mutex);
89
- INDEX_CLOSE_READER(self);
90
- if (self->iw) iw_close(self->iw);
91
- store_deref(self->store);
92
- a_deref(self->analyzer);
93
- if (self->qp) qp_destroy(self->qp);
94
- if (self->id_field != ((char *)ID_STRING)) free(self->id_field);
95
- if (self->def_field != ((char *)ID_STRING)) free(self->def_field);
96
- if (self->key) hs_destroy_all(self->key);
97
- free(self);
88
+ mutex_destroy(&self->mutex);
89
+ INDEX_CLOSE_READER(self);
90
+ if (self->iw) iw_close(self->iw);
91
+ store_deref(self->store);
92
+ a_deref(self->analyzer);
93
+ if (self->qp) qp_destroy(self->qp);
94
+ if (self->key) hs_destroy(self->key);
95
+ free(self->id_field);
96
+ free(self->def_field);
97
+ free(self);
98
98
  }
99
99
 
100
100
  void index_flush(Index *self)
101
101
  {
102
- if (self->ir) {
103
- ir_commit(self->ir);
104
- } else if (self->iw) {
105
- iw_close(self->iw);
106
- self->iw = NULL;
107
- }
108
- self->has_writes = false;
102
+ if (self->ir) {
103
+ ir_commit(self->ir);
104
+ } else if (self->iw) {
105
+ iw_close(self->iw);
106
+ self->iw = NULL;
107
+ }
108
+ self->has_writes = false;
109
109
  }
110
110
 
111
111
  inline void ensure_writer_open(Index *self)
112
112
  {
113
- if (!self->iw) {
114
- INDEX_CLOSE_READER(self);
115
-
116
- /* make sure the analzyer isn't deleted by the IndexWriter */
117
- ref(self->analyzer);
118
- self->iw = iw_open(self->store, self->analyzer, false);
119
- self->iw->use_compound_file = self->use_compound_file;
120
- } else if (self->analyzer != self->iw->analyzer) {
121
- a_deref(self->iw->analyzer);
122
- ref(self->analyzer);
123
- self->iw->analyzer = self->analyzer; /* in case it has changed */
124
- }
113
+ if (!self->iw) {
114
+ INDEX_CLOSE_READER(self);
115
+
116
+ /* make sure the analzyer isn't deleted by the IndexWriter */
117
+ REF(self->analyzer);
118
+ self->iw = iw_open(self->store, self->analyzer, false);
119
+ self->iw->config.use_compound_file = self->config.use_compound_file;
120
+ } else if (self->analyzer != self->iw->analyzer) {
121
+ a_deref(self->iw->analyzer);
122
+ REF(self->analyzer);
123
+ self->iw->analyzer = self->analyzer; /* in case it has changed */
124
+ }
125
125
  }
126
126
 
127
127
  inline void ensure_reader_open(Index *self)
128
128
  {
129
- if (self->ir) {
130
- if (self->check_latest && !ir_is_latest(self->ir)) {
131
- INDEX_CLOSE_READER(self);
132
- self->ir = ir_open(self->store);
133
- }
134
- } else {
135
- if (self->iw) {
136
- iw_close(self->iw);
137
- self->iw = NULL;
129
+ if (self->ir) {
130
+ if (self->check_latest && !ir_is_latest(self->ir)) {
131
+ INDEX_CLOSE_READER(self);
132
+ self->ir = ir_open(self->store);
133
+ }
134
+ } else {
135
+ if (self->iw) {
136
+ iw_close(self->iw);
137
+ self->iw = NULL;
138
+ }
139
+ self->ir = ir_open(self->store);
138
140
  }
139
- self->ir = ir_open(self->store);
140
- }
141
141
  }
142
142
 
143
143
  inline void ensure_searcher_open(Index *self)
144
144
  {
145
- ensure_reader_open(self);
146
- if (!self->sea) {
147
- self->sea = sea_create(self->ir);
148
- }
145
+ ensure_reader_open(self);
146
+ if (!self->sea) {
147
+ self->sea = isea_new(self->ir);
148
+ }
149
149
  }
150
150
 
151
151
  int index_size(Index *self)
152
152
  {
153
- int size;
154
- mutex_lock(&self->store->ext_mutex);
155
- ensure_reader_open(self);
156
- size = self->ir->num_docs(self->ir);
157
- mutex_unlock(&self->store->ext_mutex);
158
- return size;
153
+ int size;
154
+ mutex_lock(&self->mutex);
155
+ ensure_reader_open(self);
156
+ size = self->ir->num_docs(self->ir);
157
+ mutex_unlock(&self->mutex);
158
+ return size;
159
159
  }
160
160
 
161
161
  void index_optimize(Index *self)
162
162
  {
163
- mutex_lock(&self->store->ext_mutex);
164
- ensure_writer_open(self);
165
- iw_optimize(self->iw);
166
- AUTOFLUSH_IW;
167
- mutex_unlock(&self->store->ext_mutex);
163
+ mutex_lock(&self->mutex);
164
+ ensure_writer_open(self);
165
+ iw_optimize(self->iw);
166
+ AUTOFLUSH_IW;
167
+ mutex_unlock(&self->mutex);
168
168
  }
169
169
 
170
170
  bool index_has_del(Index *self)
171
171
  {
172
- bool has_del;
173
- mutex_lock(&self->store->ext_mutex);
174
- ensure_reader_open(self);
175
- has_del = self->ir->has_deletions(self->ir);
176
- mutex_unlock(&self->store->ext_mutex);
177
- return has_del;
172
+ bool has_del;
173
+ mutex_lock(&self->mutex);
174
+ ensure_reader_open(self);
175
+ has_del = self->ir->has_deletions(self->ir);
176
+ mutex_unlock(&self->mutex);
177
+ return has_del;
178
178
  }
179
179
 
180
180
  bool index_is_deleted(Index *self, int doc_num)
181
181
  {
182
- bool is_del;
183
- mutex_lock(&self->store->ext_mutex);
184
- ensure_reader_open(self);
185
- is_del = self->ir->is_deleted(self->ir, doc_num);
186
- mutex_unlock(&self->store->ext_mutex);
187
- return is_del;
182
+ bool is_del;
183
+ mutex_lock(&self->mutex);
184
+ ensure_reader_open(self);
185
+ is_del = self->ir->is_deleted(self->ir, doc_num);
186
+ mutex_unlock(&self->mutex);
187
+ return is_del;
188
188
  }
189
189
 
190
- static void inline index_add_doc_i(Index *self, Document *doc)
190
+ static inline void index_add_doc_i(Index *self, Document *doc)
191
191
  {
192
- /* If there is a key specified delete the document with the same key */
193
- if (self->key) {
194
- int i;
195
- char *field;
196
- DocField *df;
197
- Query *q = bq_create(false);
198
- TopDocs *td;
199
- ensure_searcher_open(self);
200
- for (i = 0; i < self->key->size; i++) {
201
- field = self->key->elems[i];
202
- df = doc_get_field(doc, field);
203
- if (!df) continue;
204
- bq_add_query(q, tq_create(term_create(field, df->data)), BC_MUST);
205
- }
206
- td = sea_search(self->sea, q, 0, 1, NULL, NULL);
207
- if (td->total_hits > 1) {
208
- td_destroy(td);
209
- RAISE(ARG_ERROR, NON_UNIQUE_KEY_ERROR_MSG);
210
- } else if (td->total_hits == 1) {
211
- ir_delete_doc(self->ir, td->hits[0]->doc);
192
+ /* If there is a key specified delete the document with the same key */
193
+ if (self->key) {
194
+ int i;
195
+ char *field;
196
+ DocField *df;
197
+ if (self->key->size == 1) {
198
+ ensure_writer_open(self);
199
+ field = self->key->elems[0];
200
+ df = doc_get_field(doc, field);
201
+ if (df) {
202
+ iw_delete_term(self->iw, field, df->data[0]);
203
+ }
204
+ } else {
205
+ Query *q = bq_new(false);
206
+ TopDocs *td;
207
+ ensure_searcher_open(self);
208
+ for (i = 0; i < self->key->size; i++) {
209
+ field = self->key->elems[i];
210
+ df = doc_get_field(doc, field);
211
+ if (!df) continue;
212
+ bq_add_query(q, tq_new(field, df->data[0]), BC_MUST);
213
+ }
214
+ td = searcher_search(self->sea, q, 0, 1, NULL, NULL, NULL);
215
+ if (td->total_hits > 1) {
216
+ td_destroy(td);
217
+ RAISE(ARG_ERROR, NON_UNIQUE_KEY_ERROR_MSG);
218
+ } else if (td->total_hits == 1) {
219
+ ir_delete_doc(self->ir, td->hits[0]->doc);
220
+ }
221
+ q_deref(q);
222
+ td_destroy(td);
223
+ }
212
224
  }
213
- q_deref(q);
214
- td_destroy(td);
215
- }
216
- ensure_writer_open(self);
217
- iw_add_doc(self->iw, doc);
218
- AUTOFLUSH_IW;
225
+ ensure_writer_open(self);
226
+ iw_add_doc(self->iw, doc);
227
+ AUTOFLUSH_IW;
219
228
  }
220
229
 
221
230
  void index_add_doc_a(Index *self, Document *doc, Analyzer *analyzer)
222
231
  {
223
- Analyzer *tmp_analyzer;
224
- mutex_lock(&self->store->ext_mutex);
225
- if (analyzer != self->analyzer) {
226
- ref(analyzer);
227
- tmp_analyzer = self->analyzer;
228
- self->analyzer = analyzer;
229
- index_add_doc_i(self, doc);
230
- self->analyzer = tmp_analyzer;
231
- a_deref(analyzer);
232
- } else {
233
- index_add_doc_i(self, doc);
234
- }
235
- mutex_unlock(&self->store->ext_mutex);
232
+ Analyzer *tmp_analyzer;
233
+ mutex_lock(&self->mutex);
234
+ if (analyzer != self->analyzer) {
235
+ REF(analyzer);
236
+ tmp_analyzer = self->analyzer;
237
+ self->analyzer = analyzer;
238
+ index_add_doc_i(self, doc);
239
+ self->analyzer = tmp_analyzer;
240
+ a_deref(analyzer);
241
+ } else {
242
+ index_add_doc_i(self, doc);
243
+ }
244
+ mutex_unlock(&self->mutex);
236
245
  }
237
246
 
238
247
  void index_add_doc(Index *self, Document *doc)
239
248
  {
240
- mutex_lock(&self->store->ext_mutex);
241
- index_add_doc_i(self, doc);
242
- mutex_unlock(&self->store->ext_mutex);
249
+ mutex_lock(&self->mutex);
250
+ index_add_doc_i(self, doc);
251
+ mutex_unlock(&self->mutex);
243
252
  }
244
253
 
245
254
  void index_add_string(Index *self, char *str, Analyzer *analyzer)
246
255
  {
247
- Document *doc = doc_create();
248
- doc_add_field(doc, df_create(self->def_field, estrdup(str),
249
- DF_STORE_YES, DF_INDEX_TOKENIZED, DF_TERM_VECTOR_NO));
250
- if (analyzer) index_add_doc_a(self, doc, analyzer);
251
- else index_add_doc(self, doc);
252
- doc_destroy(doc);
256
+ Document *doc = doc_new();
257
+ doc_add_field(doc, df_add_data(df_new(self->def_field), estrdup(str)));
258
+ if (analyzer) index_add_doc_a(self, doc, analyzer);
259
+ else index_add_doc(self, doc);
260
+ doc_destroy(doc);
253
261
  }
254
262
 
255
- void index_add_array(Index *self, Array *ary, Analyzer *analyzer)
263
+ void index_add_array(Index *self, char **fields, Analyzer *analyzer)
256
264
  {
257
- int i;
258
- Document *doc = doc_create();
259
- for (i = 0; i < ary->size; i++) {
260
- doc_add_field(doc, df_create(self->def_field, estrdup(ary->elems[i]),
261
- DF_STORE_YES, DF_INDEX_TOKENIZED, DF_TERM_VECTOR_NO));
262
- }
263
- if (analyzer) index_add_doc_a(self, doc, analyzer);
264
- else index_add_doc(self, doc);
265
- doc_destroy(doc);
265
+ int i;
266
+ Document *doc = doc_new();
267
+ for (i = 0; i < ary_size(fields); i++) {
268
+ doc_add_field(doc, df_add_data(df_new(self->def_field),
269
+ estrdup(fields[i])));
270
+ }
271
+ if (analyzer) index_add_doc_a(self, doc, analyzer);
272
+ else index_add_doc(self, doc);
273
+ doc_destroy(doc);
266
274
  }
267
275
 
268
276
  Query *index_get_query(Index *self, char *qstr)
269
277
  {
270
- int i;
271
- HashSet *all_fields;
272
- ensure_searcher_open(self);
273
- all_fields = self->ir->get_field_names(self->ir, IR_ALL);
274
- for (i = 0; i < all_fields->size; i++)
275
- hs_add(self->qp->all_fields, estrdup(all_fields->elems[i]));
276
- hs_destroy(all_fields);
277
- return qp_parse(self->qp, qstr);
278
+ int i;
279
+ FieldInfos *fis;
280
+ ensure_searcher_open(self);
281
+ fis = self->ir->fis;
282
+ for (i = fis->size - 1; i >= 0; i--) {
283
+ char *field = fis->fields[i]->name;
284
+ hs_add(self->qp->all_fields, estrdup(field));
285
+ }
286
+ return qp_parse(self->qp, qstr);
278
287
  }
279
288
 
280
289
  TopDocs *index_search_str(Index *self, char *qstr, int first_doc,
281
- int num_docs, Filter *filter, Sort *sort)
290
+ int num_docs, Filter *filter, Sort *sort,
291
+ filter_ft filter_func)
282
292
  {
283
- Query *query;
284
- TopDocs *td;
285
- query = index_get_query(self, qstr); /* will ensure_searcher is open */
286
- //printf(">> %s <<\n", query->to_s(query, ""));
287
- td = sea_search(self->sea, query, first_doc, num_docs, filter, sort);
288
- q_deref(query);
289
- return td;
293
+ Query *query;
294
+ TopDocs *td;
295
+ query = index_get_query(self, qstr); /* will ensure_searcher is open */
296
+ td = searcher_search(self->sea, query, first_doc, num_docs,
297
+ filter, sort, filter_func);
298
+ q_deref(query);
299
+ return td;
290
300
  }
291
301
 
292
302
  Document *index_get_doc(Index *self, int doc_num)
293
303
  {
294
- Document *doc;
295
- ensure_reader_open(self);
296
- doc = self->ir->get_doc(self->ir, doc_num);
297
- return doc;
304
+ Document *doc;
305
+ ensure_reader_open(self);
306
+ doc = self->ir->get_doc(self->ir, doc_num);
307
+ return doc;
298
308
  }
299
309
 
300
310
  Document *index_get_doc_ts(Index *self, int doc_num)
301
311
  {
302
- Document *doc;
303
- mutex_lock(&self->store->ext_mutex);
304
- doc = index_get_doc(self, doc_num);
305
- mutex_unlock(&self->store->ext_mutex);
306
- return doc;
312
+ Document *doc;
313
+ mutex_lock(&self->mutex);
314
+ doc = index_get_doc(self, doc_num);
315
+ mutex_unlock(&self->mutex);
316
+ return doc;
307
317
  }
308
318
 
309
- int index_term_id(Index *self, Term *term)
319
+ int index_term_id(Index *self, const char *field, const char *term)
310
320
  {
311
- TermDocEnum *tde;
312
- int doc_num = -1;
313
- ensure_reader_open(self);
314
- tde = ir_term_docs_for(self->ir, term);
315
- if (tde->next(tde)) {
316
- doc_num = tde->doc_num(tde);
317
- }
318
- tde->close(tde);
319
- return doc_num;
321
+ TermDocEnum *tde;
322
+ int doc_num = -1;
323
+ ensure_reader_open(self);
324
+ tde = ir_term_docs_for(self->ir, field, term);
325
+ if (tde->next(tde)) {
326
+ doc_num = tde->doc_num(tde);
327
+ }
328
+ tde->close(tde);
329
+ return doc_num;
320
330
  }
321
331
 
322
- Document *index_get_doc_term(Index *self, Term *term)
332
+ Document *index_get_doc_term(Index *self, const char *field,
333
+ const char *term)
323
334
  {
324
- Document *doc = NULL;
325
- TermDocEnum *tde;
326
- mutex_lock(&self->store->ext_mutex);
327
- ensure_reader_open(self);
328
- tde = ir_term_docs_for(self->ir, term);
329
- if (tde->next(tde)) {
330
- doc = index_get_doc(self, tde->doc_num(tde));
331
- }
332
- tde->close(tde);
333
- mutex_unlock(&self->store->ext_mutex);
334
- return doc;
335
+ Document *doc = NULL;
336
+ TermDocEnum *tde;
337
+ mutex_lock(&self->mutex);
338
+ ensure_reader_open(self);
339
+ tde = ir_term_docs_for(self->ir, field, term);
340
+ if (tde->next(tde)) {
341
+ doc = index_get_doc(self, tde->doc_num(tde));
342
+ }
343
+ tde->close(tde);
344
+ mutex_unlock(&self->mutex);
345
+ return doc;
335
346
  }
336
347
 
337
- Document *index_get_doc_id(Index *self, char *id)
348
+ Document *index_get_doc_id(Index *self, const char *id)
338
349
  {
339
- Term t;
340
- t.field = self->id_field;
341
- t.text = id;
342
- return index_get_doc_term(self, &t);
350
+ return index_get_doc_term(self, self->id_field, id);
343
351
  }
344
352
 
345
353
  void index_delete(Index *self, int doc_num)
346
354
  {
347
- mutex_lock(&self->store->ext_mutex);
348
- ensure_reader_open(self);
349
- ir_delete_doc(self->ir, doc_num);
350
- AUTOFLUSH_IR;
351
- mutex_unlock(&self->store->ext_mutex);
355
+ mutex_lock(&self->mutex);
356
+ ensure_reader_open(self);
357
+ ir_delete_doc(self->ir, doc_num);
358
+ AUTOFLUSH_IR;
359
+ mutex_unlock(&self->mutex);
352
360
  }
353
361
 
354
- void index_delete_term(Index *self, Term *term)
362
+ void index_delete_term(Index *self, const char *field, const char *term)
355
363
  {
356
- TermDocEnum *tde;
357
- mutex_lock(&self->store->ext_mutex);
358
- ensure_reader_open(self);
359
- tde = ir_term_docs_for(self->ir, term);
360
- TRY
361
- while (tde->next(tde)) {
362
- ir_delete_doc(self->ir, tde->doc_num(tde));
363
- AUTOFLUSH_IR;
364
+ TermDocEnum *tde;
365
+ mutex_lock(&self->mutex);
366
+ if (self->ir) {
367
+ tde = ir_term_docs_for(self->ir, field, term);
368
+ TRY
369
+ while (tde->next(tde)) {
370
+ ir_delete_doc(self->ir, tde->doc_num(tde));
371
+ AUTOFLUSH_IR;
372
+ }
373
+ XFINALLY
374
+ tde->close(tde);
375
+ XENDTRY
376
+ } else {
377
+ ensure_writer_open(self);
378
+ iw_delete_term(self->iw, field, term);
364
379
  }
365
- XFINALLY
366
- tde->close(tde);
367
- XENDTRY
368
- mutex_unlock(&self->store->ext_mutex);
380
+ mutex_unlock(&self->mutex);
369
381
  }
370
382
 
371
- void index_delete_id(Index *self, char *id)
383
+ void index_delete_id(Index *self, const char *id)
372
384
  {
373
- Term t;
374
- t.field = self->id_field;
375
- t.text = id;
376
- index_delete_term(self, &t);
385
+ index_delete_term(self, self->id_field, id);
377
386
  }
378
387
 
379
388
  static void index_qdel_i(Searcher *sea, int doc_num, float score, void *arg)
380
389
  {
381
- ir_delete_doc(sea->ir, doc_num);
390
+ (void)score; (void)arg;
391
+ ir_delete_doc(((IndexSearcher *)sea)->ir, doc_num);
382
392
  }
383
393
 
384
- void index_delete_query(Index *self, Query *q, Filter *f)
394
+ void index_delete_query(Index *self, Query *q, Filter *f, filter_ft ff)
385
395
  {
386
- mutex_lock(&self->store->ext_mutex);
387
- ensure_searcher_open(self);
388
- sea_search_each(self->sea, q, f, &index_qdel_i, NULL);
389
- AUTOFLUSH_IR;
390
- mutex_unlock(&self->store->ext_mutex);
396
+ mutex_lock(&self->mutex);
397
+ ensure_searcher_open(self);
398
+ searcher_search_each(self->sea, q, f, ff, &index_qdel_i, NULL);
399
+ AUTOFLUSH_IR;
400
+ mutex_unlock(&self->mutex);
391
401
  }
392
402
 
393
- void index_delete_query_str(Index *self, char *qstr, Filter *f)
403
+ void index_delete_query_str(Index *self, char *qstr, Filter *f, filter_ft ff)
394
404
  {
395
- Query *q = index_get_query(self, qstr);
396
- index_delete_query(self, q, f);
397
- q_deref(q);
405
+ Query *q = index_get_query(self, qstr);
406
+ index_delete_query(self, q, f, ff);
407
+ q_deref(q);
398
408
  }
399
409
 
400
410
  Explanation *index_explain(Index *self, Query *q, int doc_num)
401
411
  {
402
- Explanation *expl;
403
- mutex_lock(&self->store->ext_mutex);
404
- ensure_searcher_open(self);
405
- expl = sea_explain(self->sea, q, doc_num);
406
- mutex_unlock(&self->store->ext_mutex);
407
- return expl;
412
+ Explanation *expl;
413
+ mutex_lock(&self->mutex);
414
+ ensure_searcher_open(self);
415
+ expl = searcher_explain(self->sea, q, doc_num);
416
+ mutex_unlock(&self->mutex);
417
+ return expl;
408
418
  }