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/ram_store.c CHANGED
@@ -1,466 +1,470 @@
1
+ #include "store.h"
1
2
  #include <string.h>
2
- #include <store.h>
3
-
4
- static char * const RENAME_ERROR_MSG = "tried to rename a file that doesn't exist";
5
- static char * const MISSING_RAMFILE_ERROR_MSG ="Couldn't open the ram file to read";
6
3
 
4
+ extern Store *store_new();
7
5
  extern void store_destroy(Store *store);
6
+ extern OutStream *os_new();
7
+ extern InStream *is_new();
8
+ extern int file_is_lock(char *filename);
8
9
 
9
- typedef struct RamFile {
10
- char *name;
11
- uchar **buffers;
12
- int bufcnt;
13
- int len;
14
- int ref_cnt;
15
- bool alive;
16
- } RamFile;
17
-
18
- RamFile *rf_create(const char *name)
10
+ static RAMFile *rf_new(const char *name)
19
11
  {
20
- RamFile *rf = ALLOC(RamFile);
21
- rf->buffers = ALLOC(uchar *);
22
- rf->buffers[0] = ALLOC_N(uchar, BUFFER_SIZE);
23
- rf->name = estrdup(name);
24
- rf->len = 0;
25
- rf->bufcnt = 1;
26
- rf->ref_cnt = 0;
27
- rf->alive = true;
28
- return rf;
12
+ RAMFile *rf = ALLOC(RAMFile);
13
+ rf->buffers = ALLOC(uchar *);
14
+ rf->buffers[0] = ALLOC_N(uchar, BUFFER_SIZE);
15
+ rf->name = estrdup(name);
16
+ rf->len = 0;
17
+ rf->bufcnt = 1;
18
+ rf->ref_cnt = 1;
19
+ return rf;
29
20
  }
30
21
 
31
- void rf_extend_if_necessary(RamFile *rf, int buf_num)
22
+ static void rf_extend_if_necessary(RAMFile *rf, int buf_num)
32
23
  {
33
- while (rf->bufcnt <= buf_num) {
34
- REALLOC_N(rf->buffers, uchar *, (rf->bufcnt + 1));
35
- rf->buffers[rf->bufcnt++] = ALLOC_N(uchar, BUFFER_SIZE);
36
- }
24
+ while (rf->bufcnt <= buf_num) {
25
+ REALLOC_N(rf->buffers, uchar *, (rf->bufcnt + 1));
26
+ rf->buffers[rf->bufcnt++] = ALLOC_N(uchar, BUFFER_SIZE);
27
+ }
37
28
  }
38
29
 
39
- void rf_close(void *p)
30
+ static void rf_close(void *p)
40
31
  {
41
- int i;
42
- RamFile *rf = (RamFile *)p;
43
- if (rf->ref_cnt > 0 || rf->alive) return;
44
- free(rf->name);
45
- for (i = 0; i < rf->bufcnt; i++) {
46
- free(rf->buffers[i]);
47
- }
48
- free(rf->buffers);
49
- free(rf);
32
+ int i;
33
+ RAMFile *rf = (RAMFile *)p;
34
+ if (rf->ref_cnt > 0) {
35
+ return;
36
+ }
37
+ free(rf->name);
38
+ for (i = 0; i < rf->bufcnt; i++) {
39
+ free(rf->buffers[i]);
40
+ }
41
+ free(rf->buffers);
42
+ free(rf);
50
43
  }
51
44
 
52
- void ram_touch(Store *store, char *filename)
45
+ static void ram_touch(Store *store, char *filename)
53
46
  {
54
- if (h_get(store->dir.ht, filename) == NULL)
55
- h_set(store->dir.ht, filename, rf_create(filename));
47
+ if (h_get(store->dir.ht, filename) == NULL) {
48
+ h_set(store->dir.ht, filename, rf_new(filename));
49
+ }
56
50
  }
57
51
 
58
- int ram_exists(Store *store, char *filename)
52
+ static int ram_exists(Store *store, char *filename)
59
53
  {
60
- if (h_get(store->dir.ht, filename) != NULL)
61
- return true;
62
- else
63
- return false;
54
+ if (h_get(store->dir.ht, filename) != NULL) {
55
+ return true;
56
+ }
57
+ else {
58
+ return false;
59
+ }
64
60
  }
65
61
 
66
- int ram_remove(Store *store, char *filename)
62
+ static int ram_remove(Store *store, char *filename)
67
63
  {
68
- RamFile *rf = h_rem(store->dir.ht, filename, false);
69
- if (rf != NULL) {
70
- rf->alive = false;
71
- rf_close(rf);
72
- return true;
73
- } else {
74
- return false;
75
- }
64
+ RAMFile *rf = h_rem(store->dir.ht, filename, false);
65
+ if (rf != NULL) {
66
+ DEREF(rf);
67
+ rf_close(rf);
68
+ return true;
69
+ }
70
+ else {
71
+ return false;
72
+ }
76
73
  }
77
74
 
78
- int ram_rename(Store *store, char *from, char *to)
75
+ static void ram_rename(Store *store, char *from, char *to)
79
76
  {
80
- RamFile *rf = (RamFile *)h_rem(store->dir.ht, from, false);
81
- RamFile *tmp;
77
+ RAMFile *rf = (RAMFile *)h_rem(store->dir.ht, from, false);
78
+ RAMFile *tmp;
82
79
 
83
- if (rf == NULL) {
84
- RAISE(IO_ERROR, RENAME_ERROR_MSG);
85
- }
80
+ if (rf == NULL) {
81
+ RAISE(IO_ERROR, "couldn't rename \"%s\" to \"%s\". \"%s\""
82
+ " doesn't exist", from, to, from);
83
+ }
86
84
 
87
- free(rf->name);
85
+ free(rf->name);
88
86
 
89
- rf->name = estrdup(to);
87
+ rf->name = estrdup(to);
90
88
 
91
- /* clean up the file we are overwriting */
92
- tmp = (RamFile *)h_get(store->dir.ht, to);
93
- if (tmp != NULL) {
94
- tmp->alive = false;
95
- }
89
+ /* clean up the file we are overwriting */
90
+ tmp = (RAMFile *)h_get(store->dir.ht, to);
91
+ if (tmp != NULL) {
92
+ DEREF(tmp);
93
+ }
96
94
 
97
- h_set(store->dir.ht, rf->name, rf);
98
- return true;
95
+ h_set(store->dir.ht, rf->name, rf);
99
96
  }
100
97
 
101
- int ram_count(Store *store)
98
+ static int ram_count(Store *store)
102
99
  {
103
- return store->dir.ht->used;
100
+ return store->dir.ht->size;
104
101
  }
105
102
 
106
- void ram_each(Store *store, void (*func)(char *fname, void *arg), void *arg)
103
+ static void ram_each(Store *store,
104
+ void (*func)(char *fname, void *arg), void *arg)
107
105
  {
108
- HshTable *ht = store->dir.ht;
109
- RamFile *rf;
110
- int i;
111
- for (i = 0; i <= ht->mask; i++) {
112
- rf = (RamFile *)ht->table[i].value;
113
- if (rf) {
114
- if (strncmp(rf->name, LOCK_PREFIX, strlen(LOCK_PREFIX)) == 0)
115
- continue;
116
- func(rf->name, arg);
106
+ HashTable *ht = store->dir.ht;
107
+ int i;
108
+ for (i = 0; i <= ht->mask; i++) {
109
+ RAMFile *rf = (RAMFile *)ht->table[i].value;
110
+ if (rf) {
111
+ if (strncmp(rf->name, LOCK_PREFIX, strlen(LOCK_PREFIX)) == 0) {
112
+ continue;
113
+ }
114
+ func(rf->name, arg);
115
+ }
117
116
  }
118
- }
119
117
  }
120
118
 
121
- void ram_close_i(Store *store)
119
+ static void ram_close_i(Store *store)
122
120
  {
123
- HshTable *ht = store->dir.ht;
124
- RamFile *rf;
125
- int i;
126
- for (i = 0; i <= ht->mask; i++) {
127
- rf = (RamFile *)ht->table[i].value;
128
- if (rf) rf->alive = false;
129
- }
130
- h_destroy(store->dir.ht);
131
- store_destroy(store);
121
+ HashTable *ht = store->dir.ht;
122
+ int i;
123
+ for (i = 0; i <= ht->mask; i++) {
124
+ RAMFile *rf = (RAMFile *)ht->table[i].value;
125
+ if (rf) {
126
+ DEREF(rf);
127
+ }
128
+ }
129
+ h_destroy(store->dir.ht);
130
+ store_destroy(store);
132
131
  }
133
132
 
134
133
  /*
135
134
  * Be sure to keep the locks
136
135
  */
137
- void ram_clear(Store *store)
138
- {
139
- int i;
140
- HshTable *ht = store->dir.ht;
141
- RamFile *rf;
142
- for (i = 0; i <= ht->mask; i++) {
143
- rf = (RamFile *)ht->table[i].value;
144
- if (rf && !file_is_lock(rf->name)) {
145
- rf->alive = false;
146
- h_del(ht, rf->name);
136
+ static void ram_clear(Store *store)
137
+ {
138
+ int i;
139
+ HashTable *ht = store->dir.ht;
140
+ for (i = 0; i <= ht->mask; i++) {
141
+ RAMFile *rf = (RAMFile *)ht->table[i].value;
142
+ if (rf && !file_is_lock(rf->name)) {
143
+ DEREF(rf);
144
+ h_del(ht, rf->name);
145
+ }
147
146
  }
148
- }
149
147
  }
150
148
 
151
- void ram_clear_locks(Store *store)
149
+ static void ram_clear_locks(Store *store)
152
150
  {
153
- int i;
154
- HshTable *ht = store->dir.ht;
155
- RamFile *rf;
156
- for (i = 0; i <= ht->mask; i++) {
157
- rf = (RamFile *)ht->table[i].value;
158
- if (rf && file_is_lock(rf->name)) {
159
- rf->alive = false;
160
- h_del(ht, rf->name);
151
+ int i;
152
+ HashTable *ht = store->dir.ht;
153
+ for (i = 0; i <= ht->mask; i++) {
154
+ RAMFile *rf = (RAMFile *)ht->table[i].value;
155
+ if (rf && file_is_lock(rf->name)) {
156
+ DEREF(rf);
157
+ h_del(ht, rf->name);
158
+ }
161
159
  }
162
- }
163
- }
164
- void ram_clear_all(Store *store)
165
- {
166
- int i;
167
- HshTable *ht = store->dir.ht;
168
- RamFile *rf;
169
- for (i = 0; i <= ht->mask; i++) {
170
- rf = (RamFile *)ht->table[i].value;
171
- if (rf) {
172
- rf->alive = false;
173
- h_del(ht, rf->name);
160
+ }
161
+
162
+ static void ram_clear_all(Store *store)
163
+ {
164
+ int i;
165
+ HashTable *ht = store->dir.ht;
166
+ for (i = 0; i <= ht->mask; i++) {
167
+ RAMFile *rf = (RAMFile *)ht->table[i].value;
168
+ if (rf) {
169
+ DEREF(rf);
170
+ h_del(ht, rf->name);
171
+ }
174
172
  }
175
- }
176
173
  }
177
174
 
178
- int ram_length(Store *store, char *filename)
175
+ static off_t ram_length(Store *store, char *filename)
179
176
  {
180
- RamFile *rf = (RamFile *)h_get(store->dir.ht, filename);
181
- if (rf != NULL)
182
- return rf->len;
183
- else
184
- return 0;
177
+ RAMFile *rf = (RAMFile *)h_get(store->dir.ht, filename);
178
+ if (rf != NULL) {
179
+ return rf->len;
180
+ }
181
+ else {
182
+ return 0;
183
+ }
185
184
  }
186
185
 
187
- int ramo_length(OutStream *os)
186
+ off_t ramo_length(OutStream *os)
188
187
  {
189
- return ((RamFile *)os->file)->len;
188
+ return os->file.rf->len;
190
189
  }
191
190
 
192
- void ramo_flush_internal(OutStream *os, uchar *src, int len)
191
+ static void ramo_flush_i(OutStream *os, uchar *src, int len)
193
192
  {
194
- uchar *buffer;
195
- RamFile *rf = (RamFile *)os->file;
196
- int buffer_number, buffer_offset, bytes_in_buffer, bytes_to_copy;
197
- int src_offset;
198
- int pointer = os->pointer;
199
-
200
- buffer_number = (int)(pointer / BUFFER_SIZE);
201
- buffer_offset = pointer % BUFFER_SIZE;
202
- bytes_in_buffer = BUFFER_SIZE - buffer_offset;
203
- bytes_to_copy = bytes_in_buffer < len ? bytes_in_buffer : len;
193
+ uchar *buffer;
194
+ RAMFile *rf = os->file.rf;
195
+ int buffer_number, buffer_offset, bytes_in_buffer, bytes_to_copy;
196
+ int src_offset;
197
+ off_t pointer = os->pointer;
204
198
 
205
- rf_extend_if_necessary(rf, buffer_number);
199
+ buffer_number = (int)(pointer / BUFFER_SIZE);
200
+ buffer_offset = pointer % BUFFER_SIZE;
201
+ bytes_in_buffer = BUFFER_SIZE - buffer_offset;
202
+ bytes_to_copy = bytes_in_buffer < len ? bytes_in_buffer : len;
206
203
 
207
- buffer = rf->buffers[buffer_number];
208
- memcpy(buffer + buffer_offset, src, bytes_to_copy);
209
-
210
- if (bytes_to_copy < len) {
211
- src_offset = bytes_to_copy;
212
- bytes_to_copy = len - bytes_to_copy;
213
- buffer_number += 1;
214
204
  rf_extend_if_necessary(rf, buffer_number);
205
+
215
206
  buffer = rf->buffers[buffer_number];
207
+ memcpy(buffer + buffer_offset, src, bytes_to_copy);
216
208
 
217
- memcpy(buffer, src + src_offset, bytes_to_copy);
218
- }
219
- os->pointer += len;
209
+ if (bytes_to_copy < len) {
210
+ src_offset = bytes_to_copy;
211
+ bytes_to_copy = len - bytes_to_copy;
212
+ buffer_number += 1;
213
+ rf_extend_if_necessary(rf, buffer_number);
214
+ buffer = rf->buffers[buffer_number];
220
215
 
221
- if (os->pointer > rf->len)
222
- rf->len = os->pointer;
216
+ memcpy(buffer, src + src_offset, bytes_to_copy);
217
+ }
218
+ os->pointer += len;
219
+
220
+ if (os->pointer > rf->len) {
221
+ rf->len = os->pointer;
222
+ }
223
223
  }
224
224
 
225
- void ramo_seek_internal(OutStream *os, int pos)
225
+ static void ramo_seek_i(OutStream *os, off_t pos)
226
226
  {
227
- os->pointer = pos;
227
+ os->pointer = pos;
228
228
  }
229
229
 
230
230
  void ramo_reset(OutStream *os)
231
231
  {
232
- RamFile *rf = (RamFile *)os->file;
233
- os_seek(os, 0);
234
- rf->len = 0;
232
+ os_seek(os, 0);
233
+ os->file.rf->len = 0;
235
234
  }
236
235
 
237
- void ramo_close_internal(OutStream *os)
236
+ static void ramo_close_i(OutStream *os)
238
237
  {
239
- RamFile *rf = (RamFile *)os->file;
240
- rf->ref_cnt--;
241
- rf_close(rf);
238
+ RAMFile *rf = os->file.rf;
239
+ DEREF(rf);
240
+ rf_close(rf);
242
241
  }
243
242
 
244
243
  void ramo_write_to(OutStream *os, OutStream *other_o)
245
244
  {
246
- int i, len;
247
- RamFile *rf = (RamFile *)os->file;
248
- int last_buffer_number;
249
- int last_buffer_offset;
250
-
251
- os_flush(os);
252
- last_buffer_number = (int)(rf->len / BUFFER_SIZE);
253
- last_buffer_offset = rf->len % BUFFER_SIZE;
254
- for (i = 0; i <= last_buffer_number; i++) {
255
- len = (i == last_buffer_number ? last_buffer_offset : BUFFER_SIZE);
256
- os_write_bytes(other_o, rf->buffers[i], len);
257
- }
245
+ int i, len;
246
+ RAMFile *rf = os->file.rf;
247
+ int last_buffer_number;
248
+ int last_buffer_offset;
249
+
250
+ os_flush(os);
251
+ last_buffer_number = (int) (rf->len / BUFFER_SIZE);
252
+ last_buffer_offset = rf->len % BUFFER_SIZE;
253
+ for (i = 0; i <= last_buffer_number; i++) {
254
+ len = (i == last_buffer_number ? last_buffer_offset : BUFFER_SIZE);
255
+ os_write_bytes(other_o, rf->buffers[i], len);
256
+ }
258
257
  }
259
258
 
260
- OutStream *ram_create_buffer()
259
+ const struct OutStreamMethods RAM_OUT_STREAM_METHODS = {
260
+ ramo_flush_i,
261
+ ramo_seek_i,
262
+ ramo_close_i
263
+ };
264
+
265
+ OutStream *ram_new_buffer()
261
266
  {
262
- RamFile *rf = rf_create("");
263
- OutStream *os = os_create();
267
+ RAMFile *rf = rf_new("");
268
+ OutStream *os = os_new();
264
269
 
265
- rf->alive = false;
266
- os->file = rf;
267
- os->pointer = 0;
268
- os->flush_internal = &ramo_flush_internal;
269
- os->seek_internal = &ramo_seek_internal;
270
- os->close_internal = &ramo_close_internal;
271
- return os;
270
+ DEREF(rf);
271
+ os->file.rf = rf;
272
+ os->pointer = 0;
273
+ os->m = &RAM_OUT_STREAM_METHODS;
274
+ return os;
272
275
  }
273
276
 
274
277
  void ram_destroy_buffer(OutStream *os)
275
278
  {
276
- rf_close(os->file);
277
- free(os);
279
+ rf_close(os->file.rf);
280
+ free(os);
278
281
  }
279
282
 
280
- OutStream *ram_create_output(Store *store, const char *filename)
283
+ static OutStream *ram_new_output(Store *store, const char *filename)
281
284
  {
282
- RamFile *rf = (RamFile *)h_get(store->dir.ht, filename);
283
- OutStream *os = os_create();
285
+ RAMFile *rf = (RAMFile *)h_get(store->dir.ht, filename);
286
+ OutStream *os = os_new();
284
287
 
285
- if (rf == NULL) {
286
- rf = rf_create(filename);
287
- h_set(store->dir.ht, rf->name, rf);
288
- }
289
- rf->ref_cnt++;
290
- os->pointer = 0;
291
- os->file = rf;
292
- os->flush_internal = &ramo_flush_internal;
293
- os->seek_internal = &ramo_seek_internal;
294
- os->close_internal = &ramo_close_internal;
295
- return os;
296
- }
297
-
298
- void rami_read_internal(InStream *is, uchar *b, int offset, int len)
299
- {
300
- RamFile *rf = (RamFile *)is->file;
301
-
302
- int buffer_number, buffer_offset, bytes_in_buffer, bytes_to_copy;
303
- int remainder = len;
304
- int start = is->d.pointer;
305
- uchar *buffer;
306
-
307
- while (remainder > 0) {
308
- buffer_number = (int)(start / BUFFER_SIZE);
309
- buffer_offset = start % BUFFER_SIZE;
310
- bytes_in_buffer = BUFFER_SIZE - buffer_offset;
311
-
312
- if (bytes_in_buffer >= remainder) {
313
- bytes_to_copy = remainder;
314
- } else {
315
- bytes_to_copy = bytes_in_buffer;
288
+ if (rf == NULL) {
289
+ rf = rf_new(filename);
290
+ h_set(store->dir.ht, rf->name, rf);
291
+ }
292
+ REF(rf);
293
+ os->pointer = 0;
294
+ os->file.rf = rf;
295
+ os->m = &RAM_OUT_STREAM_METHODS;
296
+ return os;
297
+ }
298
+
299
+ static void rami_read_i(InStream *is, uchar *b, int len)
300
+ {
301
+ RAMFile *rf = is->file.rf;
302
+
303
+ int offset = 0;
304
+ int buffer_number, buffer_offset, bytes_in_buffer, bytes_to_copy;
305
+ int remainder = len;
306
+ off_t start = is->d.pointer;
307
+ uchar *buffer;
308
+
309
+ while (remainder > 0) {
310
+ buffer_number = (int) (start / BUFFER_SIZE);
311
+ buffer_offset = start % BUFFER_SIZE;
312
+ bytes_in_buffer = BUFFER_SIZE - buffer_offset;
313
+
314
+ if (bytes_in_buffer >= remainder) {
315
+ bytes_to_copy = remainder;
316
+ }
317
+ else {
318
+ bytes_to_copy = bytes_in_buffer;
319
+ }
320
+ buffer = rf->buffers[buffer_number];
321
+ memcpy(b + offset, buffer + buffer_offset, bytes_to_copy);
322
+ offset += bytes_to_copy;
323
+ start += bytes_to_copy;
324
+ remainder -= bytes_to_copy;
316
325
  }
317
- buffer = rf->buffers[buffer_number];
318
- memcpy(b + offset, buffer + buffer_offset, bytes_to_copy);
319
- offset += bytes_to_copy;
320
- start += bytes_to_copy;
321
- remainder -= bytes_to_copy;
322
- }
323
-
324
- is->d.pointer += len;
325
- }
326
326
 
327
- int rami_length(InStream *is)
328
- {
329
- return ((RamFile *)is->file)->len;
327
+ is->d.pointer += len;
330
328
  }
331
329
 
332
- void rami_seek_internal(InStream *is, int pos)
330
+ static off_t rami_length_i(InStream *is)
333
331
  {
334
- is->d.pointer = pos;
332
+ return is->file.rf->len;
335
333
  }
336
334
 
337
- void rami_close_internal(InStream *is)
335
+ static void rami_seek_i(InStream *is, off_t pos)
338
336
  {
339
- RamFile *rf = (RamFile *)is->file;
340
- rf->ref_cnt--;
341
- rf_close(rf);
337
+ is->d.pointer = pos;
342
338
  }
343
339
 
344
- void rami_clone_internal(InStream *is, InStream *new_index_i)
340
+ static void rami_close_i(InStream *is)
345
341
  {
346
- ((RamFile *)is->file)->ref_cnt++;
342
+ RAMFile *rf = is->file.rf;
343
+ DEREF(rf);
344
+ rf_close(rf);
347
345
  }
348
346
 
349
- InStream *ram_open_input(Store *store, const char *filename)
347
+ static const struct InStreamMethods RAM_IN_STREAM_METHODS = {
348
+ rami_read_i,
349
+ rami_seek_i,
350
+ rami_length_i,
351
+ rami_close_i
352
+ };
353
+
354
+ static InStream *ram_open_input(Store *store, const char *filename)
350
355
  {
351
- RamFile *rf = (RamFile *)h_get(store->dir.ht, filename);
352
- InStream *is = is_create();
356
+ RAMFile *rf = (RAMFile *)h_get(store->dir.ht, filename);
357
+ InStream *is = is_new();
353
358
 
354
- if (rf == NULL) {
355
- RAISE(IO_ERROR, MISSING_RAMFILE_ERROR_MSG);
356
- }
357
- rf->ref_cnt++;
358
- is->file = rf;
359
- is->d.pointer = 0;
360
- is->is_clone = false;
361
- is->read_internal = &rami_read_internal;
362
- is->seek_internal = &rami_seek_internal;
363
- is->close_internal = &rami_close_internal;
364
- is->clone_internal = &rami_clone_internal;
365
- is->length_internal = &rami_length;
366
- return is;
359
+ if (rf == NULL) {
360
+ RAISE(IO_ERROR, "tried to open \"%s\" but it doesn't exist", filename);
361
+ }
362
+ REF(rf);
363
+
364
+ is->file.rf = rf;
365
+ is->d.pointer = 0;
366
+ is->m = &RAM_IN_STREAM_METHODS;
367
+
368
+ return is;
367
369
  }
368
370
 
369
371
  #define LOCK_OBTAIN_TIMEOUT 5
370
372
 
371
- int ram_lock_obtain(Lock *lock)
373
+ static int ram_lock_obtain(Lock *lock)
372
374
  {
373
- int ret = true;
374
- if (ram_exists(lock->store, lock->name))
375
- ret = false;
376
- ram_touch(lock->store, lock->name);
377
- return ret;
375
+ int ret = true;
376
+ if (ram_exists(lock->store, lock->name))
377
+ ret = false;
378
+ ram_touch(lock->store, lock->name);
379
+ return ret;
378
380
  }
379
381
 
380
- int ram_lock_is_locked(Lock *lock)
382
+ static int ram_lock_is_locked(Lock *lock)
381
383
  {
382
- return ram_exists(lock->store, lock->name);
384
+ return ram_exists(lock->store, lock->name);
383
385
  }
384
386
 
385
- void ram_lock_release(Lock *lock)
387
+ static void ram_lock_release(Lock *lock)
386
388
  {
387
- ram_remove(lock->store, lock->name);
389
+ ram_remove(lock->store, lock->name);
388
390
  }
389
391
 
390
- Lock *ram_open_lock(Store *store, char *lockname)
392
+ static Lock *ram_open_lock(Store *store, char *lockname)
391
393
  {
392
- Lock *lock = ALLOC(Lock);
393
- char lname[100];
394
- sprintf(lname, "%s%s.lck", LOCK_PREFIX, lockname);
395
- lock->name = estrdup(lname);
396
- lock->store = store;
397
- lock->obtain = &ram_lock_obtain;
398
- lock->release = &ram_lock_release;
399
- lock->is_locked = &ram_lock_is_locked;
400
- return lock;
394
+ Lock *lock = ALLOC(Lock);
395
+ char lname[100];
396
+ sprintf(lname, "%s%s.lck", LOCK_PREFIX, lockname);
397
+ lock->name = estrdup(lname);
398
+ lock->store = store;
399
+ lock->obtain = &ram_lock_obtain;
400
+ lock->release = &ram_lock_release;
401
+ lock->is_locked = &ram_lock_is_locked;
402
+ return lock;
401
403
  }
402
404
 
403
- void ram_close_lock(Lock *lock)
405
+ static void ram_close_lock(Lock *lock)
404
406
  {
405
- free(lock->name);
406
- free(lock);
407
+ free(lock->name);
408
+ free(lock);
407
409
  }
408
410
 
409
411
 
410
412
  Store *open_ram_store()
411
413
  {
412
- Store *new_store = store_create();
413
-
414
- new_store->dir.ht = h_new_str(NULL, rf_close);
415
- new_store->touch = &ram_touch;
416
- new_store->exists = &ram_exists;
417
- new_store->remove = &ram_remove;
418
- new_store->rename = &ram_rename;
419
- new_store->count = &ram_count;
420
- new_store->clear = &ram_clear;
421
- new_store->clear_all = &ram_clear_all;
422
- new_store->clear_locks = &ram_clear_locks;
423
- new_store->length = &ram_length;
424
- new_store->each = &ram_each;
425
- new_store->create_output = &ram_create_output;
426
- new_store->open_input = &ram_open_input;
427
- new_store->open_lock = &ram_open_lock;
428
- new_store->close_lock = &ram_close_lock;
429
- new_store->close_i = &ram_close_i;
430
- return new_store;
431
- }
432
-
433
- struct CopyFileArg {
434
- Store *to_store, *from_store;
414
+ Store *new_store = store_new();
415
+
416
+ new_store->dir.ht = h_new_str(NULL, rf_close);
417
+ new_store->touch = &ram_touch;
418
+ new_store->exists = &ram_exists;
419
+ new_store->remove = &ram_remove;
420
+ new_store->rename = &ram_rename;
421
+ new_store->count = &ram_count;
422
+ new_store->clear = &ram_clear;
423
+ new_store->clear_all = &ram_clear_all;
424
+ new_store->clear_locks = &ram_clear_locks;
425
+ new_store->length = &ram_length;
426
+ new_store->each = &ram_each;
427
+ new_store->new_output = &ram_new_output;
428
+ new_store->open_input = &ram_open_input;
429
+ new_store->open_lock = &ram_open_lock;
430
+ new_store->close_lock = &ram_close_lock;
431
+ new_store->close_i = &ram_close_i;
432
+ return new_store;
433
+ }
434
+
435
+ struct CopyFileArg
436
+ {
437
+ Store *to_store, *from_store;
435
438
  };
436
439
 
437
440
  static void copy_files(char *fname, void *arg)
438
441
  {
439
- struct CopyFileArg *cfa = (struct CopyFileArg *)arg;
440
- OutStream *os = cfa->to_store->create_output(cfa->to_store, fname);
441
- InStream *is = cfa->from_store->open_input(cfa->from_store, fname);
442
- int len = is_length(is);
443
- uchar *buffer = ALLOC_N(uchar, len+1);
444
-
445
- is_read_bytes(is, buffer, 0, len);
446
- os_write_bytes(os, buffer, len);
442
+ struct CopyFileArg *cfa = (struct CopyFileArg *)arg;
443
+ OutStream *os = cfa->to_store->new_output(cfa->to_store, fname);
444
+ InStream *is = cfa->from_store->open_input(cfa->from_store, fname);
445
+ int len = (int)is_length(is);
446
+ uchar *buffer = ALLOC_N(uchar, len + 1);
447
447
 
448
- is_close(is);
449
- os_close(os);
450
- free(buffer);
448
+ is_read_bytes(is, buffer, len);
449
+ os_write_bytes(os, buffer, len);
450
+
451
+ is_close(is);
452
+ os_close(os);
453
+ free(buffer);
451
454
  }
452
455
 
453
456
  Store *open_ram_store_and_copy(Store *from_store, bool close_dir)
454
457
  {
455
- Store *store = open_ram_store();
456
- struct CopyFileArg cfa;
457
- cfa.to_store = store;
458
- cfa.from_store = from_store;
458
+ Store *store = open_ram_store();
459
+ struct CopyFileArg cfa;
460
+ cfa.to_store = store;
461
+ cfa.from_store = from_store;
459
462
 
460
- from_store->each(from_store, &copy_files, &cfa);
463
+ from_store->each(from_store, &copy_files, &cfa);
461
464
 
462
- if (close_dir)
463
- store_deref(from_store);
465
+ if (close_dir) {
466
+ store_deref(from_store);
467
+ }
464
468
 
465
- return store;
469
+ return store;
466
470
  }