ferret 0.9.6 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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/filter.c CHANGED
@@ -7,66 +7,76 @@
7
7
  *
8
8
  ***************************************************************************/
9
9
 
10
- void filt_destroy(Filter *self)
10
+ void filt_destroy_i(Filter *filt)
11
11
  {
12
- h_destroy(self->cache);
13
- free(self->name);
14
- free(self);
12
+ h_destroy(filt->cache);
13
+ free(filt->name);
14
+ free(filt);
15
+ }
16
+ void filt_deref(Filter *filt)
17
+ {
18
+ if (--(filt->ref_cnt) == 0) {
19
+ filt->destroy_i(filt);
20
+ }
15
21
  }
16
22
 
17
- BitVector *filt_get_bv(Filter *self, IndexReader *ir)
23
+ BitVector *filt_get_bv(Filter *filt, IndexReader *ir)
18
24
  {
19
- CacheObject *co = h_get(self->cache, ir);
20
- if (!co) {
21
- BitVector *bv;
22
- if (!ir->cache) {
23
- ir_add_cache(ir);
25
+ CacheObject *co = h_get(filt->cache, ir);
26
+
27
+ if (!co) {
28
+ BitVector *bv;
29
+ if (!ir->cache) {
30
+ ir_add_cache(ir);
31
+ }
32
+ bv = filt->get_bv_i(filt, ir);
33
+ co = co_create(filt->cache, ir->cache, filt, ir,
34
+ (free_ft)&bv_destroy, (void *)bv);
24
35
  }
25
- bv = self->get_bv(self, ir);
26
- co = co_create(self->cache, ir->cache, self, ir,
27
- (free_ft)&bv_destroy, (void *)bv);
28
- }
29
- return (BitVector *)co->obj;
36
+ return (BitVector *)co->obj;
30
37
  }
31
38
 
32
- char *filt_to_s_i(Filter *self)
39
+ static char *filt_to_s_i(Filter *filt)
33
40
  {
34
- return estrdup(self->name);
41
+ return estrdup(filt->name);
35
42
  }
36
43
 
37
- uint filt_hash_dflt(Filter *self)
44
+ ulong filt_hash_default(Filter *filt)
38
45
  {
39
- return 0;
46
+ (void)filt;
47
+ return 0;
40
48
  }
41
49
 
42
- int filt_eq_dflt(Filter *self, Filter *o)
50
+ int filt_eq_default(Filter *filt, Filter *o)
43
51
  {
44
- return false;
52
+ (void)filt; (void)o;
53
+ return false;
45
54
  }
46
55
 
47
- Filter *filt_create(char *name)
56
+ Filter *filt_create(size_t size, const char *name)
48
57
  {
49
- Filter *self = ALLOC(Filter);
50
- self->cache = co_hsh_create();
51
- self->name = estrdup(name);
52
- self->to_s = &filt_to_s_i;
53
- self->hash = &filt_hash_dflt;
54
- self->eq = &filt_eq_dflt;
55
- self->destroy = &filt_destroy;
56
- return self;
58
+ Filter *filt = (Filter *)emalloc(size);
59
+ filt->cache = co_hash_create();
60
+ filt->name = estrdup(name);
61
+ filt->to_s = &filt_to_s_i;
62
+ filt->hash = &filt_hash_default;
63
+ filt->eq = &filt_eq_default;
64
+ filt->destroy_i = &filt_destroy_i;
65
+ filt->ref_cnt = 1;
66
+ return filt;
57
67
  }
58
68
 
59
- uint filt_hash(Filter *self)
69
+ ulong filt_hash(Filter *filt)
60
70
  {
61
- return str_hash(self->name) ^ self->hash(self);
71
+ return str_hash(filt->name) ^ filt->hash(filt);
62
72
  }
63
73
 
64
- int filt_eq(Filter *self, Filter *o)
74
+ int filt_eq(Filter *filt, Filter *o)
65
75
  {
66
- return ((self == o) ||
67
- ((strcmp(self->name, o->name) == 0) &&
68
- (self->eq == o->eq) &&
69
- (self->eq(self, o))));
76
+ return ((filt == o)
77
+ || ((strcmp(filt->name, o->name) == 0)
78
+ && (filt->eq == o->eq)
79
+ && (filt->eq(filt, o))));
70
80
  }
71
81
 
72
82
  /***************************************************************************
@@ -75,67 +85,72 @@ int filt_eq(Filter *self, Filter *o)
75
85
  *
76
86
  ***************************************************************************/
77
87
 
78
- char *qfilt_to_s(Filter *self)
88
+ #define QF(filt) ((QueryFilter *)(filt))
89
+ typedef struct QueryFilter
90
+ {
91
+ Filter super;
92
+ Query *query;
93
+ } QueryFilter;
94
+
95
+ static char *qfilt_to_s(Filter *filt)
79
96
  {
80
- QueryFilter *qf = (QueryFilter *)self->data;
81
- Query *query = (Query *)qf->query;
82
- char *query_str = query->to_s(query, "");
83
- char *filter_str = strfmt("QueryFilter< %s >", query_str);
84
- free(query_str);
85
- return filter_str;
97
+ Query *query = QF(filt)->query;
98
+ char *query_str = query->to_s(query, "");
99
+ char *filter_str = strfmt("QueryFilter< %s >", query_str);
100
+ free(query_str);
101
+ return filter_str;
86
102
  }
87
103
 
88
- BitVector *qfilt_get_bv(Filter *filt, IndexReader *ir)
104
+ static BitVector *qfilt_get_bv_i(Filter *filt, IndexReader *ir)
89
105
  {
90
- BitVector *bv = bv_create_size(ir->max_doc(ir));
91
- QueryFilter *qfilt = (QueryFilter *)filt->data;
92
- Searcher *sea = sea_create(ir);
93
- Weight *weight = q_weight(qfilt->query, sea);
94
- Scorer *scorer = weight->scorer(weight, ir);
95
- if (scorer) {
96
- while (scorer->next(scorer)) {
97
- bv_set(bv, scorer->doc);
106
+ BitVector *bv = bv_new_capa(ir->max_doc(ir));
107
+ Searcher *sea = isea_new(ir);
108
+ Weight *weight = q_weight(QF(filt)->query, sea);
109
+ Scorer *scorer = weight->scorer(weight, ir);
110
+ if (scorer) {
111
+ while (scorer->next(scorer)) {
112
+ bv_set(bv, scorer->doc);
113
+ }
114
+ scorer->destroy(scorer);
98
115
  }
99
- scorer->destroy(scorer);
100
- }
101
- weight->destroy(weight);
102
- free(sea);
103
- return bv;
116
+ weight->destroy(weight);
117
+ free(sea);
118
+ return bv;
104
119
  }
105
120
 
106
- uint qfilt_hash(Filter *self)
121
+ static ulong qfilt_hash(Filter *filt)
107
122
  {
108
- Query *query = (Query *)((QueryFilter *)self->data)->query;
109
- return q_hash(query);
123
+ return q_hash(QF(filt)->query);
110
124
  }
111
125
 
112
- int qfilt_eq(Filter *self, Filter *o)
126
+ static int qfilt_eq(Filter *filt, Filter *o)
113
127
  {
114
- Query *query1 = (Query *)((QueryFilter *)self->data)->query;
115
- Query *query2 = (Query *)((QueryFilter *)o->data)->query;
116
- return q_eq(query1, query2);
128
+ return q_eq(QF(filt)->query, QF(o)->query);
117
129
  }
118
130
 
119
- void qfilt_destroy(Filter *self)
131
+ static void qfilt_destroy_i(Filter *filt)
120
132
  {
121
- Query *query = (Query *)((QueryFilter *)self->data)->query;
122
- q_deref(query);
123
- free(self->data);
124
- filt_destroy(self);
133
+ Query *query = QF(filt)->query;
134
+ q_deref(query);
135
+ filt_destroy_i(filt);
125
136
  }
126
137
 
127
- Filter *qfilt_create(Query *query)
138
+ Filter *qfilt_new_nr(Query *query)
128
139
  {
129
- Filter *self;
130
- QueryFilter *qfilt = ALLOC(QueryFilter);
131
- qfilt->query = query;
140
+ Filter *filt = filt_new(QueryFilter);
132
141
 
133
- self = filt_create("QueryFilter");
134
- self->data = qfilt;
135
- self->get_bv = &qfilt_get_bv;
136
- self->hash = &qfilt_hash;
137
- self->eq = &qfilt_eq;
138
- self->to_s = &qfilt_to_s;
139
- self->destroy = &qfilt_destroy;
140
- return self;
142
+ QF(filt)->query = query;
143
+
144
+ filt->get_bv_i = &qfilt_get_bv_i;
145
+ filt->hash = &qfilt_hash;
146
+ filt->eq = &qfilt_eq;
147
+ filt->to_s = &qfilt_to_s;
148
+ filt->destroy_i = &qfilt_destroy_i;
149
+ return filt;
150
+ }
151
+
152
+ Filter *qfilt_new(Query *query)
153
+ {
154
+ REF(query);
155
+ return qfilt_new_nr(query);
141
156
  }
data/ext/fs_store.c CHANGED
@@ -1,478 +1,459 @@
1
1
  #include "store.h"
2
- #include "frtio.h"
3
- #ifdef WIN32
4
- # ifndef S_IRUSR
5
- # define S_IRUSR _S_IREAD
6
- # endif
7
- # ifndef S_IWUSR
8
- # define S_IWUSR _S_IWRITE
9
- # endif
10
- # include <io.h>
11
- #else
12
- #include <unistd.h>
13
- # define _close close
14
- # define _open open
15
- # define _creat creat
16
- # define _lseek lseek
17
- # define _read read
18
- # define _stat stat
19
- # define _fstat fstat
20
- #endif
21
2
  #include <sys/types.h>
22
3
  #include <fcntl.h>
23
4
  #include <sys/stat.h>
24
5
  #include <errno.h>
25
6
  #include <string.h>
26
7
  #include <stdio.h>
8
+ #ifdef POSH_OS_WIN32
9
+ # include <io.h>
10
+ # include "win32.h"
11
+ # ifndef sleep
12
+ # define sleep _sleep
13
+ # endif
14
+ # ifndef DIR_SEPARATOR
15
+ # define DIR_SEPARATOR "\\"
16
+ # endif
17
+ # ifndef S_IRUSR
18
+ # define S_IRUSR _S_IREAD
19
+ # endif
20
+ # ifndef S_IWUSR
21
+ # define S_IWUSR _S_IWRITE
22
+ # endif
23
+ #else
24
+ # define DIR_SEPARATOR "/"
25
+ # include <unistd.h>
26
+ # include <dirent.h>
27
+ #endif
28
+ #ifndef O_BINARY
29
+ # define O_BINARY 0
30
+ #endif
27
31
 
28
-
29
- static char * const FILE_OPEN_ERROR_MSG = "Couldn't open the file to read";
30
- static char * const SEEK_ERROR_MSG = "Seek error message";
31
- static char * const WRITE_ERROR_MSG = "Write error message";
32
-
32
+ extern Store *store_new();
33
33
  extern void store_destroy(Store *store);
34
+ extern OutStream *os_new();
35
+ extern InStream *is_new();
36
+ extern int file_is_lock(char *filename);
34
37
 
35
38
  /**
36
- * Create the file +filename+ in the +store+.
37
- *
38
- * @param store the store to create the file in
39
- * @param filename the name of the file to create
40
- * @throws IO_ERROR if the file cannot be created
39
+ * Create a filepath for a file in the store using the operating systems
40
+ * default file seperator.
41
41
  */
42
+ static char *join_path(char *buf, const char *base, const char *filename)
43
+ {
44
+ sprintf(buf, "%s"DIR_SEPARATOR"%s", base, filename);
45
+ return buf;
46
+ }
47
+
42
48
  static void fs_touch(Store *store, char *filename)
43
49
  {
44
- int f;
45
- char path[MAX_FILE_PATH];
46
- join_path(path, store->dir.path, filename);
47
- if ((f = _creat(path, S_IRUSR|S_IWUSR)) == 0) {
48
- RAISE(IO_ERROR, strerror(errno));
49
- }
50
- _close(f);
50
+ int f;
51
+ char path[MAX_FILE_PATH];
52
+ join_path(path, store->dir.path, filename);
53
+ if ((f = creat(path, S_IRUSR | S_IWUSR)) == 0) {
54
+ RAISE(IO_ERROR, "couldn't create file %s: <%s>", path,
55
+ strerror(errno));
56
+ }
57
+ close(f);
51
58
  }
52
59
 
53
- /**
54
- * Return true if a file of name +filename+ exists in +store+.
55
- *
56
- * @param store the store to check in
57
- * @param filename the name of the file to check for
58
- * @returns true if the file exists
59
- * @throws IO_ERROR if there is an error checking for the files existance
60
- */
61
- int fs_exists(Store *store, char *filename)
60
+ static int fs_exists(Store *store, char *filename)
62
61
  {
63
- char buf[MAX_FILE_PATH];
64
- return exists(join_path(buf, store->dir.path, filename));
62
+ int fd;
63
+ char path[MAX_FILE_PATH];
64
+ join_path(path, store->dir.path, filename);
65
+ fd = open(path, 0);
66
+ if (fd < 0) {
67
+ if (errno != ENOENT) {
68
+ RAISE(IO_ERROR, "checking existance of %s: <%s>", path,
69
+ strerror(errno));
70
+ }
71
+ return false;
72
+ }
73
+ close(fd);
74
+ return true;
65
75
  }
66
76
 
67
- /**
68
- * Remove the file +filename+ from the +store+
69
- *
70
- * @param store the store to remove from
71
- * @param filename the name of the file to remove
72
- * @returns On success, zero is returned. On error, -1 is returned, and errno
73
- * is set appropriately.
74
- */
75
- int fs_remove(Store *store, char *filename)
77
+ static int fs_remove(Store *store, char *filename)
76
78
  {
77
- char buf[MAX_FILE_PATH];
78
- return remove(join_path(buf, store->dir.path, filename));
79
+ char path[MAX_FILE_PATH];
80
+ return remove(join_path(path, store->dir.path, filename));
79
81
  }
80
82
 
81
- /**
82
- * Rename the file in the +store+ from the name +from+ to the name +to+.
83
- *
84
- * @param store the store to rename the file in
85
- * @param from the name of the file to rename
86
- * @param to the new name of the file
87
- * @returns On success, zero is returned. On error, -1 is returned, and errno
88
- * is set appropriately.
89
- */
90
- int fs_rename(Store *store, char *from, char *to)
83
+ static void fs_rename(Store *store, char *from, char *to)
91
84
  {
92
- char buf1[MAX_FILE_PATH], buf2[MAX_FILE_PATH];
85
+ char path1[MAX_FILE_PATH], path2[MAX_FILE_PATH];
93
86
 
94
- #ifdef WIN32
95
- remove(join_path(buf1, store->dir.path, to));
87
+ #ifdef POSH_OS_WIN32
88
+ remove(join_path(path1, store->dir.path, to));
96
89
  #endif
97
90
 
98
- if (rename(join_path(buf1, store->dir.path, from),
99
- join_path(buf2, store->dir.path, to)) < 0) {
100
- RAISE(IO_ERROR, strerror(errno));
101
- }
102
- return true;
91
+ if (rename(join_path(path1, store->dir.path, from),
92
+ join_path(path2, store->dir.path, to)) < 0) {
93
+ RAISE(IO_ERROR, "couldn't rename file \"%s\" to \"%s\": <%s>",
94
+ path1, path2, strerror(errno));
95
+ }
103
96
  }
104
97
 
105
- /**
106
- * Returns the number of files in the store.
107
- *
108
- * @param store the store to count the files in
109
- * @return the number of files in the store
110
- * @throws IO_ERROR if there is an error opening the directory
111
- */
112
- int fs_count(Store *store)
98
+ static int fs_count(Store *store)
113
99
  {
114
- return fcount(store->dir.path);
100
+ int cnt = 0;
101
+ struct dirent *de;
102
+ DIR *d = opendir(store->dir.path);
103
+
104
+ if (!d) {
105
+ RAISE(IO_ERROR, "counting files in %s: <%s>",
106
+ store->dir.path, strerror(errno));
107
+ }
108
+
109
+ while ((de = readdir(d)) != NULL) {
110
+ if (de->d_name[0] > '/') { /* skip ., .., / and '\0'*/
111
+ cnt++;
112
+ }
113
+ }
114
+ closedir(d);
115
+
116
+ return cnt;
115
117
  }
116
118
 
117
- /**
118
- * Call the function +func+ with each filename in the store and the arg that
119
- * you passed. If you need to open the file you should pass the store as the
120
- * argument. If you need to pass more than one argument, you should pass a
121
- * struct.
122
- *
123
- * @param store the store to grab the files from
124
- * @param func the function to call with each files name and the +arg+ passed
125
- * @param arg the argument to pass to the function
126
- * @throws IO_ERROR if there is an error opening the directory
127
- */
128
- void fs_each(Store *store, void (*func)(char *fname, void *arg), void *arg)
119
+ static void fs_each(Store *store, void (*func)(char *fname, void *arg), void *arg)
120
+ {
121
+ struct dirent *de;
122
+ DIR *d = opendir(store->dir.path);
123
+
124
+ if (!d) {
125
+ RAISE(IO_ERROR, "doing 'each' in %s: <%s>",
126
+ store->dir.path, strerror(errno));
127
+ }
128
+
129
+ while ((de = readdir(d)) != NULL) {
130
+ if (de->d_name[0] > '/' /* skip ., .., / and '\0'*/
131
+ && !file_is_lock(de->d_name)) {
132
+ func(de->d_name, arg);
133
+ }
134
+ }
135
+ closedir(d);
136
+ }
137
+
138
+ static void fs_clear_locks(Store *store)
129
139
  {
130
- dir_each(store->dir.path, func, arg);
140
+ struct dirent *de;
141
+ DIR *d = opendir(store->dir.path);
142
+
143
+ if (!d) {
144
+ RAISE(IO_ERROR, "clearing locks in %s: <%s>",
145
+ store->dir.path, strerror(errno));
146
+ }
147
+
148
+ while ((de = readdir(d)) != NULL) {
149
+ if (file_is_lock(de->d_name)) {
150
+ char path[MAX_FILE_PATH];
151
+ remove(join_path(path, store->dir.path, de->d_name));
152
+ }
153
+ }
154
+ closedir(d);
155
+ }
156
+
157
+ static void fs_clear(Store *store)
158
+ {
159
+ struct dirent *de;
160
+ DIR *d = opendir(store->dir.path);
161
+
162
+ if (!d) {
163
+ RAISE(IO_ERROR, "clearing files in %s: <%s>",
164
+ store->dir.path, strerror(errno));
165
+ }
166
+
167
+ while ((de = readdir(d)) != NULL) {
168
+ if (de->d_name[0] > '/' /* skip ., .., / and '\0'*/
169
+ && !file_is_lock(de->d_name)) {
170
+ char path[MAX_FILE_PATH];
171
+ remove(join_path(path, store->dir.path, de->d_name));
172
+ }
173
+ }
174
+ closedir(d);
175
+ }
176
+
177
+ static void fs_clear_all(Store *store)
178
+ {
179
+ struct dirent *de;
180
+ DIR *d = opendir(store->dir.path);
181
+
182
+ if (!d) {
183
+ RAISE(IO_ERROR, "clearing all files in %s: <%s>",
184
+ store->dir.path, strerror(errno));
185
+ }
186
+
187
+ while ((de = readdir(d)) != NULL) {
188
+ if (de->d_name[0] > '/') { /* skip ., .., / and '\0'*/
189
+ char path[MAX_FILE_PATH];
190
+ remove(join_path(path, store->dir.path, de->d_name));
191
+ }
192
+ }
193
+ closedir(d);
131
194
  }
132
195
 
133
196
  /**
134
197
  * Destroy the store.
135
198
  *
136
199
  * @param p the store to destroy
137
- * @throws IO_ERROR if there is an error deleting the locks
200
+ * @raise IO_ERROR if there is an error deleting the locks
138
201
  */
139
- void fs_destroy(Store *store)
202
+ static void fs_destroy(Store *store)
140
203
  {
141
- fs_clear_locks(store);
142
- free(store->dir.path);
143
- store_destroy(store);
204
+ fs_clear_locks(store);
205
+ free(store->dir.path);
206
+ store_destroy(store);
144
207
  }
145
208
 
146
- /**
147
- * Return the length of the file +filename+ in +store+
148
- *
149
- * @param store the store to use
150
- * @param the name of the file to check the length of
151
- * @return the length of the file in bytes
152
- * @throws IO_ERROR if there is an error checking the file length
153
- */
154
- int fs_length(Store *store, char *filename)
209
+ static off_t fs_length(Store *store, char *filename)
155
210
  {
156
- char buf[MAX_FILE_PATH];
157
- struct stat stt;
211
+ char path[MAX_FILE_PATH];
212
+ struct stat stt;
158
213
 
159
- if (stat(join_path(buf, store->dir.path, filename), &stt))
160
- RAISE(IO_ERROR, strerror(errno));
214
+ if (stat(join_path(path, store->dir.path, filename), &stt)) {
215
+ RAISE(IO_ERROR, "getting lenth of %s: <%s>", path,
216
+ strerror(errno));
217
+ }
161
218
 
162
- return stt.st_size;
219
+ return stt.st_size;
163
220
  }
164
221
 
165
- /**
166
- * Flush +len+ characters from +src+ to the output stream +os+
167
- *
168
- * @param os the output stream to write to
169
- * @param src the characters to write to the output stream
170
- * @param len the number of characters to write
171
- * @throws IO_ERROR if there is an error writing the characters
172
- */
173
- void fso_flush_internal(OutStream *os, uchar *src, int len)
222
+ static void fso_flush_i(OutStream *os, uchar *src, int len)
174
223
  {
175
- if (len != fwrite(src, sizeof(uchar), len, (FILE *)os->file))
176
- RAISE(IO_ERROR, WRITE_ERROR_MSG);
224
+ if (len != write(os->file.fd, src, len)) {
225
+ RAISE(IO_ERROR, "flushing src of length %d", len);
226
+ }
177
227
  }
178
228
 
179
- /**
180
- * Seek +pos+ in the output stream
181
- *
182
- * @param os the output stream to seek in
183
- * @param pos the position to seek in the stream
184
- * @throws IO_ERROR if there is an error seeking in the output stream
185
- */
186
- void fso_seek_internal(OutStream *os, int pos)
229
+ static void fso_seek_i(OutStream *os, off_t pos)
187
230
  {
188
- if (fseek((FILE *)os->file, pos, SEEK_SET))
189
- RAISE(IO_ERROR, strerror(errno));
231
+ if (lseek(os->file.fd, pos, SEEK_SET) < 0) {
232
+ RAISE(IO_ERROR, "seeking position %"F_OFF_T_PFX"d: <%s>",
233
+ pos, strerror(errno));
234
+ }
190
235
  }
191
236
 
192
- /**
193
- * Close any resources used by the output stream +os+
194
- *
195
- * @param os the output stream to seek in
196
- * @throws IO_ERROR if there is an closing the file
197
- */
198
- void fso_close_internal(OutStream *os)
237
+ static void fso_close_i(OutStream *os)
199
238
  {
200
- if (fclose((FILE *)os->file))
201
- RAISE(IO_ERROR, strerror(errno));
239
+ if (close(os->file.fd)) {
240
+ RAISE(IO_ERROR, "closing file: <%s>", strerror(errno));
241
+ }
202
242
  }
203
243
 
204
- /**
205
- * Allocate the resources needed for the output stream in the +store+ with the
206
- * name +filename+
207
- *
208
- * @param store the store to create the output stream in.
209
- * @param filename the name of the output stream
210
- * @return a newly allocated filestream
211
- * @throws IO_ERROR if there is an error opening the output stream resources
212
- */
213
- OutStream *fs_create_output(Store *store, const char *filename)
244
+ const struct OutStreamMethods FS_OUT_STREAM_METHODS = {
245
+ fso_flush_i,
246
+ fso_seek_i,
247
+ fso_close_i
248
+ };
249
+
250
+ static OutStream *fs_new_output(Store *store, const char *filename)
214
251
  {
215
- char buf[MAX_FILE_PATH];
216
- FILE *f = fopen(join_path(buf, store->dir.path, filename), "wb");
217
- OutStream *os;
218
- if (!f) RAISE(IO_ERROR, strerror(errno));
219
-
220
- os = os_create();
221
- os->file = f;
222
- os->flush_internal = &fso_flush_internal;
223
- os->seek_internal = &fso_seek_internal;
224
- os->close_internal = &fso_close_internal;
225
- return os;
252
+ char path[MAX_FILE_PATH];
253
+ int fd = open(join_path(path, store->dir.path, filename),
254
+ O_WRONLY | O_CREAT | O_BINARY, S_IRUSR | S_IWUSR);
255
+ OutStream *os;
256
+ if (fd < 0) {
257
+ RAISE(IO_ERROR, "couldn't create OutStream %s: <%s>",
258
+ path, strerror(errno));
259
+ }
260
+
261
+ os = os_new();
262
+ os->file.fd = fd;
263
+ os->m = &FS_OUT_STREAM_METHODS;
264
+ return os;
226
265
  }
227
266
 
228
- /**
229
- * Read +len+ characters from the input stream into the +offset+ position in
230
- * +b+, an array of unsigned characters.
231
- *
232
- * @param is the input stream to read from
233
- * @param b an array of characters which must be allocated with at least
234
- * +offset+ + +len+ bytes
235
- * @param offset the position in +b+ to start writing the bytes read
236
- * @param len the number of bytes to read
237
- * @throws IO_ERROR if there is an error reading from the input stream
238
- */
239
- void fsi_read_internal(InStream *is, uchar *b, int offset, int len)
267
+ static void fsi_read_i(InStream *is, uchar *path, int len)
240
268
  {
241
- int fd = (int)is->file;
242
- int pos = is_pos(is);
243
- if (pos != _lseek(fd, 0, SEEK_CUR)) {
244
- _lseek(fd, pos, SEEK_SET);
245
- }
246
- if (_read(fd, b, len) != len) {
247
- /* win: the wrong value can be returned for some reason so double check */
248
- if (_lseek(fd, 0, SEEK_CUR) != (pos + len)) {
249
- RAISE(EOF_ERROR, strerror(errno));
269
+ int fd = is->file.fd;
270
+ int pos = is_pos(is);
271
+ if (pos != lseek(fd, 0, SEEK_CUR)) {
272
+ lseek(fd, pos, SEEK_SET);
273
+ }
274
+ if (read(fd, path, len) != len) {
275
+ /* win: the wrong value can be returned for some reason so double check */
276
+ if (lseek(fd, 0, SEEK_CUR) != (pos + len)) {
277
+ RAISE(IO_ERROR, "couldn't read %d chars from %s: <%s>",
278
+ len, path, strerror(errno));
279
+ }
250
280
  }
251
- }
252
281
  }
253
282
 
254
- /**
255
- * Seek position +pos+ in input stream +is+
256
- *
257
- * @param is the input stream to seek in
258
- * @param pos the position to seek
259
- * @throws IO_ERROR if the seek fails
260
- */
261
- void fsi_seek_internal(InStream *is, int pos)
283
+ static void fsi_seek_i(InStream *is, off_t pos)
262
284
  {
263
- if (_lseek((int)is->file, pos, SEEK_SET) < 0) {
264
- RAISE(IO_ERROR, strerror(errno));
265
- }
285
+ if (lseek(is->file.fd, pos, SEEK_SET) < 0) {
286
+ RAISE(IO_ERROR, "seeking pos %"F_OFF_T_PFX"d: <%s>",
287
+ pos, strerror(errno));
288
+ }
266
289
  }
267
290
 
268
- /**
269
- * Close the resources allocated to the inputstream +is+
270
- *
271
- * @param is the input stream to close
272
- * @throws IO_ERROR if the close fails
273
- */
274
- void fsi_close_internal(InStream *is)
291
+ static void fsi_close_i(InStream *is)
275
292
  {
276
- if (!is->is_clone) {
277
- if (_close((int)is->file)) {
278
- RAISE(IO_ERROR, strerror(errno));
293
+ if (close(is->file.fd)) {
294
+ RAISE(IO_ERROR, strerror(errno));
279
295
  }
280
296
  free(is->d.path);
281
- }
282
297
  }
283
298
 
284
- /**
285
- * Returns the length of the input stream +is+
286
- *
287
- * @param is the input stream to get the length of
288
- * @throws IO_ERROR if there is an error getting the file length
289
- */
290
- int fsi_length(InStream *is)
299
+ static off_t fsi_length_i(InStream *is)
291
300
  {
292
- struct _stat stt;
293
- if (_fstat((int)is->file, &stt)) {
294
- RAISE(IO_ERROR, strerror(errno));
295
- }
296
- return stt.st_size;
301
+ struct stat stt;
302
+ if (fstat(is->file.fd, &stt)) {
303
+ RAISE(IO_ERROR, "fstat failed: <%s>", strerror(errno));
304
+ }
305
+ return stt.st_size;
297
306
  }
298
307
 
299
- /**
300
- * Clone the input stream. Nothing to do for a file system input stream
301
- */
302
- void fsi_clone_internal(InStream *is, InStream *new_is)
303
- { }
308
+ static const struct InStreamMethods FS_IN_STREAM_METHODS = {
309
+ fsi_read_i,
310
+ fsi_seek_i,
311
+ fsi_length_i,
312
+ fsi_close_i
313
+ };
304
314
 
305
- /**
306
- * Open an input stream in the +store+ with the name +filename+
307
- *
308
- * @param store the store to create the input stream in
309
- * @param filename the name of the input stream
310
- * @throws IO_ERROR if the input stream cannot be opened
311
- */
312
- InStream *fs_open_input(Store *store, const char *filename)
315
+ static InStream *fs_open_input(Store *store, const char *filename)
313
316
  {
314
- InStream *is;
315
- char buf[MAX_FILE_PATH];
316
- int fd = _open(join_path(buf, store->dir.path, filename), O_RDONLY);
317
- if (fd < 0) {
318
- RAISE(IO_ERROR, FILE_OPEN_ERROR_MSG);
319
- }
320
-
321
- is = is_create();
322
- is->file = (void *)fd;
323
- is->d.path = estrdup(buf);
324
- is->is_clone = false;
325
- is->read_internal = &fsi_read_internal;
326
- is->seek_internal = &fsi_seek_internal;
327
- is->close_internal = &fsi_close_internal;
328
- is->clone_internal = &fsi_clone_internal;
329
- is->length_internal= &fsi_length;
330
- return is;
317
+ InStream *is;
318
+ char path[MAX_FILE_PATH];
319
+ int fd = open(join_path(path, store->dir.path, filename), O_RDONLY | O_BINARY);
320
+ if (fd < 0) {
321
+ RAISE(IO_ERROR, "couldn't create InStream %s: <%s>",
322
+ path, strerror(errno));
323
+ }
324
+ is = is_new();
325
+ is->file.fd = fd;
326
+ is->d.path = estrdup(path);
327
+ is->m = &FS_IN_STREAM_METHODS;
328
+ return is;
331
329
  }
332
330
 
333
331
  #define LOCK_OBTAIN_TIMEOUT 5
334
332
 
335
- /**
336
- * Obtain a lock on the lock +lock+
337
- *
338
- * @param lock the lock to obtain
339
- */
340
- int fs_lock_obtain(Lock *lock)
333
+ static int fs_lock_obtain(Lock *lock)
341
334
  {
342
- int f;
343
- int trys = LOCK_OBTAIN_TIMEOUT;
344
- while (((f = _open(lock->name, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) &&
345
- (trys > 0)) {
346
- trys--;
347
- }
348
- if (f >= 0) {
349
- _close(f);
350
- return true;
351
- } else {
352
- return false;
353
- }
335
+ int f;
336
+ int trys = LOCK_OBTAIN_TIMEOUT;
337
+ while (((f =
338
+ open(lock->name, O_CREAT | O_EXCL | O_RDWR,
339
+ S_IRUSR | S_IWUSR)) < 0) && (trys > 0)) {
340
+ trys--;
341
+ /* FIXME:: implement sleep properly to sleep in milliseconds
342
+ * sleep(1); */
343
+ }
344
+ if (f >= 0) {
345
+ close(f);
346
+ return true;
347
+ }
348
+ else {
349
+ return false;
350
+ }
354
351
  }
355
352
 
356
- /**
357
- * Returns true if +lock+ is locked. To test if the file is locked:wq
358
- *
359
- * @param lock the lock to test
360
- * @throws
361
- */
362
- int fs_lock_is_locked(Lock *lock)
353
+ static int fs_lock_is_locked(Lock *lock)
363
354
  {
364
- int f = _open(lock->name, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
365
- if (f >= 0) {
366
- if (_close(f) || remove(lock->name)) {
367
- RAISE(IO_ERROR, strerror(errno));
355
+ int f = open(lock->name, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
356
+ if (f >= 0) {
357
+ if (close(f) || remove(lock->name)) {
358
+ RAISE(IO_ERROR, "couldn't close lock \"%s\": <%s>", lock->name,
359
+ strerror(errno));
360
+ }
361
+ return false;
362
+ }
363
+ else {
364
+ return true;
368
365
  }
369
- return false;
370
- } else {
371
- return true;
372
- }
373
366
  }
374
367
 
375
368
  void fs_lock_release(Lock *lock)
376
369
  {
377
- remove(lock->name);
370
+ remove(lock->name);
378
371
  }
379
372
 
380
- Lock *fs_open_lock(Store *store, char *lockname)
373
+ static Lock *fs_open_lock(Store *store, char *lockname)
381
374
  {
382
- Lock *lock = ALLOC(Lock);
383
- char lname[100];
384
- char buf[MAX_FILE_PATH];
385
- sprintf(lname, "%s%s.lck", LOCK_PREFIX, lockname);
386
- lock->name = estrdup(join_path(buf, store->dir.path, lname));
387
- lock->obtain = &fs_lock_obtain;
388
- lock->release = &fs_lock_release;
389
- lock->is_locked = &fs_lock_is_locked;
390
- return lock;
375
+ Lock *lock = ALLOC(Lock);
376
+ char lname[100];
377
+ char path[MAX_FILE_PATH];
378
+ sprintf(lname, "%s%s.lck", LOCK_PREFIX, lockname);
379
+ lock->name = estrdup(join_path(path, store->dir.path, lname));
380
+ lock->store = store;
381
+ lock->obtain = &fs_lock_obtain;
382
+ lock->release = &fs_lock_release;
383
+ lock->is_locked = &fs_lock_is_locked;
384
+ return lock;
391
385
  }
392
386
 
393
- void fs_close_lock(Lock *lock)
387
+ static void fs_close_lock(Lock *lock)
394
388
  {
395
- remove(lock->name);
396
- free(lock->name);
397
- free(lock);
389
+ remove(lock->name);
390
+ free(lock->name);
391
+ free(lock);
398
392
  }
399
393
 
400
- #ifdef WIN32
401
- static HshTable stores = {
402
- /* fill */0,
403
- /* used */0,
404
- /* mask */Hsh_MINSIZE - 1,
405
- /* table */stores.smalltable,
406
- /* smalltable */{0},
407
- /* lookup */&h_lookup_str,
408
- /* hash */NULL,
409
- /* eq */NULL,
410
- /* free_key */(free_ft)&dummy_free,
411
- /* free_value */(free_ft)&fs_destroy
412
- };
413
- #else
414
- static HshTable stores = {
415
- fill:0,
416
- used:0,
417
- mask:Hsh_MINSIZE - 1,
418
- table:stores.smalltable,
419
- lookup:&h_lookup_str,
420
- hash:NULL,
421
- eq:NULL,
422
- free_key:(free_ft)&dummy_free,
423
- free_value:(free_ft)&fs_destroy
394
+ static HashTable stores = {
395
+ /* fill */ 0,
396
+ /* used */ 0,
397
+ /* mask */ HASH_MINSIZE - 1,
398
+ /* table */ stores.smalltable,
399
+ /* smalltable */ {{0, NULL, NULL}},
400
+ /* lookup */ (h_lookup_ft)&h_lookup_str,
401
+ /* hash */ NULL,
402
+ /* eq */ NULL,
403
+ /* free_key */ (free_ft)&dummy_free,
404
+ /* free_value */ (free_ft)&fs_destroy
424
405
  };
425
- #endif
426
406
 
427
- #ifndef FERRET_EXT
407
+ #ifndef UNTHREADED
428
408
  static mutex_t stores_mutex = MUTEX_INITIALIZER;
429
409
  #endif
430
410
 
431
- void fs_close_i(Store *store)
411
+ static void fs_close_i(Store *store)
432
412
  {
433
- mutex_lock(&stores_mutex);
434
- h_del(&stores, store->dir.path);
435
- mutex_unlock(&stores_mutex);
413
+ mutex_lock(&stores_mutex);
414
+ h_del(&stores, store->dir.path);
415
+ mutex_unlock(&stores_mutex);
436
416
  }
437
417
 
438
- Store *fs_store_create(const char *pathname)
418
+ static Store *fs_store_new(const char *pathname)
439
419
  {
440
- Store *new_store = store_create();
441
-
442
- new_store->dir.path = estrdup(pathname);
443
- new_store->touch = &fs_touch;
444
- new_store->exists = &fs_exists;
445
- new_store->remove = &fs_remove;
446
- new_store->rename = &fs_rename;
447
- new_store->count = &fs_count;
448
- new_store->close_i = &fs_close_i;
449
- new_store->clear = &fs_clear;
450
- new_store->clear_all = &fs_clear_all;
451
- new_store->clear_locks = &fs_clear_locks;
452
- new_store->length = &fs_length;
453
- new_store->each = &fs_each;
454
- new_store->create_output = &fs_create_output;
455
- new_store->open_input = &fs_open_input;
456
- new_store->open_lock = &fs_open_lock;
457
- new_store->close_lock = &fs_close_lock;
458
- return new_store;
420
+ Store *new_store = store_new();
421
+
422
+ new_store->dir.path = estrdup(pathname);
423
+ new_store->touch = &fs_touch;
424
+ new_store->exists = &fs_exists;
425
+ new_store->remove = &fs_remove;
426
+ new_store->rename = &fs_rename;
427
+ new_store->count = &fs_count;
428
+ new_store->close_i = &fs_close_i;
429
+ new_store->clear = &fs_clear;
430
+ new_store->clear_all = &fs_clear_all;
431
+ new_store->clear_locks = &fs_clear_locks;
432
+ new_store->length = &fs_length;
433
+ new_store->each = &fs_each;
434
+ new_store->new_output = &fs_new_output;
435
+ new_store->open_input = &fs_open_input;
436
+ new_store->open_lock = &fs_open_lock;
437
+ new_store->close_lock = &fs_close_lock;
438
+ return new_store;
459
439
  }
460
440
 
461
441
  Store *open_fs_store(const char *pathname)
462
442
  {
463
- Store *store = NULL;
464
-
465
- mutex_lock(&stores_mutex);
466
- store = h_get(&stores, pathname);
467
- if (store) {
468
- mutex_lock(&store->mutex);
469
- store->ref_cnt++;
470
- mutex_unlock(&store->mutex);
471
- } else {
472
- store = fs_store_create(pathname);
473
- h_set(&stores, store->dir.path, store);
474
- }
475
- mutex_unlock(&stores_mutex);
476
-
477
- return store;
443
+ Store *store = NULL;
444
+
445
+ mutex_lock(&stores_mutex);
446
+ store = h_get(&stores, pathname);
447
+ if (store) {
448
+ mutex_lock(&store->mutex);
449
+ store->ref_cnt++;
450
+ mutex_unlock(&store->mutex);
451
+ }
452
+ else {
453
+ store = fs_store_new(pathname);
454
+ h_set(&stores, store->dir.path, store);
455
+ }
456
+ mutex_unlock(&stores_mutex);
457
+
458
+ return store;
478
459
  }