isomorfeus-ferret 0.13.7 → 0.13.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -4
  3. data/ext/isomorfeus_ferret_ext/bm_store.c +3 -3
  4. data/ext/isomorfeus_ferret_ext/frb_analysis.c +7 -4
  5. data/ext/isomorfeus_ferret_ext/frb_index.c +18 -24
  6. data/ext/isomorfeus_ferret_ext/frb_qparser.c +2 -1
  7. data/ext/isomorfeus_ferret_ext/frb_search.c +23 -19
  8. data/ext/isomorfeus_ferret_ext/frb_store.c +34 -36
  9. data/ext/isomorfeus_ferret_ext/frt_analysis.c +4 -4
  10. data/ext/isomorfeus_ferret_ext/frt_analysis.h +9 -9
  11. data/ext/isomorfeus_ferret_ext/frt_bitvector.c +1 -1
  12. data/ext/isomorfeus_ferret_ext/frt_bitvector.h +1 -1
  13. data/ext/isomorfeus_ferret_ext/frt_compound_io.c +41 -66
  14. data/ext/isomorfeus_ferret_ext/frt_config.h +8 -0
  15. data/ext/isomorfeus_ferret_ext/frt_except.c +1 -0
  16. data/ext/isomorfeus_ferret_ext/frt_field_index.c +1 -1
  17. data/ext/isomorfeus_ferret_ext/frt_filter.c +2 -4
  18. data/ext/isomorfeus_ferret_ext/frt_fs_store.c +24 -19
  19. data/ext/isomorfeus_ferret_ext/frt_global.c +6 -4
  20. data/ext/isomorfeus_ferret_ext/frt_global.h +1 -1
  21. data/ext/isomorfeus_ferret_ext/frt_hash.c +40 -48
  22. data/ext/isomorfeus_ferret_ext/frt_hash.h +14 -16
  23. data/ext/isomorfeus_ferret_ext/frt_ind.c +3 -4
  24. data/ext/isomorfeus_ferret_ext/frt_index.c +152 -222
  25. data/ext/isomorfeus_ferret_ext/frt_index.h +31 -31
  26. data/ext/isomorfeus_ferret_ext/frt_lang.c +1 -4
  27. data/ext/isomorfeus_ferret_ext/frt_multimapper.c +8 -9
  28. data/ext/isomorfeus_ferret_ext/frt_multimapper.h +1 -1
  29. data/ext/isomorfeus_ferret_ext/frt_q_boolean.c +7 -7
  30. data/ext/isomorfeus_ferret_ext/frt_q_fuzzy.c +1 -1
  31. data/ext/isomorfeus_ferret_ext/frt_q_match_all.c +8 -3
  32. data/ext/isomorfeus_ferret_ext/frt_q_multi_term.c +2 -2
  33. data/ext/isomorfeus_ferret_ext/frt_q_parser.c +1742 -1742
  34. data/ext/isomorfeus_ferret_ext/frt_q_phrase.c +2 -3
  35. data/ext/isomorfeus_ferret_ext/frt_q_prefix.c +1 -1
  36. data/ext/isomorfeus_ferret_ext/frt_q_range.c +1 -1
  37. data/ext/isomorfeus_ferret_ext/frt_q_span.c +12 -11
  38. data/ext/isomorfeus_ferret_ext/frt_q_term.c +2 -2
  39. data/ext/isomorfeus_ferret_ext/frt_q_wildcard.c +1 -1
  40. data/ext/isomorfeus_ferret_ext/frt_ram_store.c +24 -40
  41. data/ext/isomorfeus_ferret_ext/frt_search.c +30 -29
  42. data/ext/isomorfeus_ferret_ext/frt_search.h +18 -19
  43. data/ext/isomorfeus_ferret_ext/frt_sort.c +1 -1
  44. data/ext/isomorfeus_ferret_ext/frt_store.c +47 -40
  45. data/ext/isomorfeus_ferret_ext/frt_store.h +45 -47
  46. data/ext/isomorfeus_ferret_ext/frt_threading.h +12 -5
  47. data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +4 -3
  48. data/ext/isomorfeus_ferret_ext/test_1710.c +1 -2
  49. data/ext/isomorfeus_ferret_ext/test_compound_io.c +8 -8
  50. data/ext/isomorfeus_ferret_ext/test_fields.c +7 -7
  51. data/ext/isomorfeus_ferret_ext/test_file_deleter.c +1 -1
  52. data/ext/isomorfeus_ferret_ext/test_filter.c +5 -4
  53. data/ext/isomorfeus_ferret_ext/test_fs_store.c +1 -1
  54. data/ext/isomorfeus_ferret_ext/test_highlighter.c +4 -2
  55. data/ext/isomorfeus_ferret_ext/test_index.c +63 -63
  56. data/ext/isomorfeus_ferret_ext/test_q_const_score.c +3 -2
  57. data/ext/isomorfeus_ferret_ext/test_q_filtered.c +4 -3
  58. data/ext/isomorfeus_ferret_ext/test_q_fuzzy.c +4 -2
  59. data/ext/isomorfeus_ferret_ext/test_q_span.c +9 -2
  60. data/ext/isomorfeus_ferret_ext/test_ram_store.c +4 -4
  61. data/ext/isomorfeus_ferret_ext/test_search.c +10 -5
  62. data/ext/isomorfeus_ferret_ext/test_segments.c +4 -3
  63. data/ext/isomorfeus_ferret_ext/test_sort.c +18 -10
  64. data/ext/isomorfeus_ferret_ext/test_store.c +1 -1
  65. data/ext/isomorfeus_ferret_ext/test_term.c +5 -3
  66. data/ext/isomorfeus_ferret_ext/test_term_vectors.c +2 -2
  67. data/ext/isomorfeus_ferret_ext/test_threading.c +5 -4
  68. data/lib/isomorfeus/ferret/index/index.rb +8 -3
  69. data/lib/isomorfeus/ferret/version.rb +1 -1
  70. metadata +16 -2
@@ -1,7 +1,7 @@
1
1
  #include "frt_index.h"
2
2
  #include "frt_array.h"
3
3
 
4
- extern void frt_store_destroy(FrtStore *store);
4
+ extern void frt_store_close(FrtStore *store);
5
5
  extern FrtInStream *frt_is_new();
6
6
  extern FrtStore *frt_store_new();
7
7
 
@@ -12,49 +12,41 @@ extern FrtStore *frt_store_new();
12
12
  ****************************************************************************/
13
13
 
14
14
  typedef struct FileEntry {
15
- off_t offset;
16
- off_t length;
15
+ frt_off_t offset;
16
+ frt_off_t length;
17
17
  } FileEntry;
18
18
 
19
- static void cmpd_touch(FrtStore *store, const char *file_name)
20
- {
19
+ static void cmpd_touch(FrtStore *store, const char *file_name) {
21
20
  store->dir.cmpd->store->touch(store->dir.cmpd->store, file_name);
22
21
  }
23
22
 
24
- static int cmpd_exists(FrtStore *store, const char *file_name)
25
- {
23
+ static int cmpd_exists(FrtStore *store, const char *file_name) {
26
24
  if (frt_h_get(store->dir.cmpd->entries, file_name) != NULL) {
27
25
  return true;
28
- }
29
- else {
26
+ } else {
30
27
  return false;
31
28
  }
32
29
  }
33
30
 
34
- static int cmpd_remove(FrtStore *store, const char *file_name)
35
- {
31
+ static int cmpd_remove(FrtStore *store, const char *file_name) {
36
32
  (void)store;
37
33
  (void)file_name;
38
34
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
39
35
  return 0;
40
36
  }
41
37
 
42
- static void cmpd_rename(FrtStore *store, const char *from, const char *to)
43
- {
38
+ static void cmpd_rename(FrtStore *store, const char *from, const char *to) {
44
39
  (void)store;
45
40
  (void)from;
46
41
  (void)to;
47
42
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
48
43
  }
49
44
 
50
- static int cmpd_count(FrtStore *store)
51
- {
45
+ static int cmpd_count(FrtStore *store) {
52
46
  return store->dir.cmpd->entries->size;
53
47
  }
54
48
 
55
- static void cmpd_each(FrtStore *store,
56
- void (*func)(const char *fname, void *arg), void *arg)
57
- {
49
+ static void cmpd_each(FrtStore *store, void (*func)(const char *fname, void *arg), void *arg) {
58
50
  FrtHash *ht = store->dir.cmpd->entries;
59
51
  int i;
60
52
  for (i = 0; i <= ht->mask; i++) {
@@ -65,15 +57,12 @@ static void cmpd_each(FrtStore *store,
65
57
  }
66
58
  }
67
59
 
68
-
69
- static void cmpd_clear(FrtStore *store)
70
- {
60
+ static void cmpd_clear(FrtStore *store) {
71
61
  (void)store;
72
62
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
73
63
  }
74
64
 
75
- static void cmpd_close_i(FrtStore *store)
76
- {
65
+ static void cmpd_close_i(FrtStore *store) {
77
66
  FrtCompoundStore *cmpd = store->dir.cmpd;
78
67
  if (cmpd->stream == NULL) {
79
68
  FRT_RAISE(FRT_IO_ERROR, "Tried to close already closed compound store");
@@ -83,44 +72,39 @@ static void cmpd_close_i(FrtStore *store)
83
72
 
84
73
  frt_is_close(cmpd->stream);
85
74
  cmpd->stream = NULL;
75
+ frt_store_close(cmpd->store);
86
76
  free(store->dir.cmpd);
87
- frt_store_destroy(store);
88
77
  }
89
78
 
90
- static off_t cmpd_length(FrtStore *store, const char *file_name)
91
- {
79
+ static frt_off_t cmpd_length(FrtStore *store, const char *file_name) {
92
80
  FileEntry *fe = (FileEntry *)frt_h_get(store->dir.cmpd->entries, file_name);
93
81
  if (fe != NULL) {
94
82
  return fe->length;
95
- }
96
- else {
83
+ } else {
97
84
  return 0;
98
85
  }
99
86
  }
100
87
 
101
- static void cmpdi_seek_i(FrtInStream *is, off_t pos)
102
- {
88
+ static void cmpdi_seek_i(FrtInStream *is, frt_off_t pos) {
103
89
  (void)is;
104
90
  (void)pos;
105
91
  }
106
92
 
107
- static void cmpdi_close_i(FrtInStream *is)
108
- {
93
+ static void cmpdi_close_i(FrtInStream *is) {
94
+ frt_is_close(is->d.cis->sub);
109
95
  free(is->d.cis);
110
96
  }
111
97
 
112
- static off_t cmpdi_length_i(FrtInStream *is)
113
- {
98
+ static frt_off_t cmpdi_length_i(FrtInStream *is) {
114
99
  return (is->d.cis->length);
115
100
  }
116
101
 
117
102
  /*
118
103
  * raises: FRT_EOF_ERROR
119
104
  */
120
- static void cmpdi_read_i(FrtInStream *is, frt_uchar *b, int len)
121
- {
105
+ static void cmpdi_read_i(FrtInStream *is, frt_uchar *b, int len) {
122
106
  FrtCompoundInStream *cis = is->d.cis;
123
- off_t start = frt_is_pos(is);
107
+ frt_off_t start = frt_is_pos(is);
124
108
 
125
109
  if ((start + len) > cis->length) {
126
110
  FRT_RAISE(FRT_EOF_ERROR, "Tried to read past end of file. File length is "
@@ -139,12 +123,12 @@ static const struct FrtInStreamMethods CMPD_IN_STREAM_METHODS = {
139
123
  cmpdi_close_i
140
124
  };
141
125
 
142
- static FrtInStream *cmpd_create_input(FrtInStream *sub_is, off_t offset, off_t length)
143
- {
126
+ static FrtInStream *cmpd_create_input(FrtInStream *sub_is, frt_off_t offset, frt_off_t length) {
144
127
  FrtInStream *is = frt_is_new();
145
128
  FrtCompoundInStream *cis = FRT_ALLOC(FrtCompoundInStream);
146
129
 
147
130
  cis->sub = sub_is;
131
+ FRT_REF(sub_is);
148
132
  cis->offset = offset;
149
133
  cis->length = length;
150
134
  is->d.cis = cis;
@@ -153,8 +137,7 @@ static FrtInStream *cmpd_create_input(FrtInStream *sub_is, off_t offset, off_t l
153
137
  return is;
154
138
  }
155
139
 
156
- static FrtInStream *cmpd_open_input(FrtStore *store, const char *file_name)
157
- {
140
+ static FrtInStream *cmpd_open_input(FrtStore *store, const char *file_name) {
158
141
  FileEntry *entry;
159
142
  FrtCompoundStore *cmpd = store->dir.cmpd;
160
143
  FrtInStream *is;
@@ -178,32 +161,28 @@ static FrtInStream *cmpd_open_input(FrtStore *store, const char *file_name)
178
161
  return is;
179
162
  }
180
163
 
181
- static FrtOutStream *cmpd_new_output(FrtStore *store, const char *file_name)
182
- {
164
+ static FrtOutStream *cmpd_new_output(FrtStore *store, const char *file_name) {
183
165
  (void)store;
184
166
  (void)file_name;
185
167
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
186
168
  return NULL;
187
169
  }
188
170
 
189
- static FrtLock *cmpd_open_lock_i(FrtStore *store, const char *lock_name)
190
- {
171
+ static FrtLock *cmpd_open_lock_i(FrtStore *store, const char *lock_name) {
191
172
  (void)store;
192
173
  (void)lock_name;
193
174
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
194
175
  return NULL;
195
176
  }
196
177
 
197
- static void cmpd_close_lock_i(FrtLock *lock)
198
- {
178
+ static void cmpd_close_lock_i(FrtLock *lock) {
199
179
  (void)lock;
200
180
  FRT_RAISE(FRT_UNSUPPORTED_ERROR, "%s", FRT_UNSUPPORTED_ERROR_MSG);
201
181
  }
202
182
 
203
- FrtStore *frt_open_cmpd_store(FrtStore *store, const char *name)
204
- {
183
+ FrtStore *frt_open_cmpd_store(FrtStore *store, const char *name) {
205
184
  int count, i;
206
- off_t offset;
185
+ frt_off_t offset;
207
186
  char *fname;
208
187
  FileEntry *volatile entry = NULL;
209
188
  FrtStore *new_store = NULL;
@@ -214,6 +193,7 @@ FrtStore *frt_open_cmpd_store(FrtStore *store, const char *name)
214
193
  cmpd = FRT_ALLOC_AND_ZERO(FrtCompoundStore);
215
194
 
216
195
  cmpd->store = store;
196
+ FRT_REF(store);
217
197
  cmpd->name = name;
218
198
  cmpd->entries = frt_h_new_str(&free, &free);
219
199
  is = cmpd->stream = store->open_input(store, cmpd->name);
@@ -235,6 +215,7 @@ FrtStore *frt_open_cmpd_store(FrtStore *store, const char *name)
235
215
  frt_h_set(cmpd->entries, fname, entry);
236
216
  }
237
217
  FRT_XCATCHALL
218
+ frt_store_close(store);
238
219
  if (is) frt_is_close(is);
239
220
  if (cmpd->entries) frt_h_destroy(cmpd->entries);
240
221
  free(cmpd);
@@ -270,18 +251,17 @@ FrtStore *frt_open_cmpd_store(FrtStore *store, const char *name)
270
251
  *
271
252
  ****************************************************************************/
272
253
 
273
- FrtCompoundWriter *frt_open_cw(FrtStore *store, char *name)
274
- {
254
+ FrtCompoundWriter *frt_open_cw(FrtStore *store, char *name) {
275
255
  FrtCompoundWriter *cw = FRT_ALLOC(FrtCompoundWriter);
276
256
  cw->store = store;
257
+ FRT_REF(store);
277
258
  cw->name = name;
278
259
  cw->ids = frt_hs_new_str(&free);
279
260
  cw->file_entries = frt_ary_new_type_capa(FrtCWFileEntry, FRT_CW_INIT_CAPA);
280
261
  return cw;
281
262
  }
282
263
 
283
- void frt_cw_add_file(FrtCompoundWriter *cw, char *id)
284
- {
264
+ void frt_cw_add_file(FrtCompoundWriter *cw, char *id) {
285
265
  id = frt_estrdup(id);
286
266
  if (frt_hs_add(cw->ids, id) != FRT_HASH_KEY_DOES_NOT_EXIST) {
287
267
  FRT_RAISE(FRT_IO_ERROR, "Tried to add file \"%s\" which has already been "
@@ -292,11 +272,10 @@ void frt_cw_add_file(FrtCompoundWriter *cw, char *id)
292
272
  frt_ary_last(cw->file_entries).name = id;
293
273
  }
294
274
 
295
- static void cw_copy_file(FrtCompoundWriter *cw, FrtCWFileEntry *src, FrtOutStream *os)
296
- {
297
- off_t start_ptr = frt_os_pos(os);
298
- off_t end_ptr;
299
- off_t remainder, length, len;
275
+ static void cw_copy_file(FrtCompoundWriter *cw, FrtCWFileEntry *src, FrtOutStream *os) {
276
+ frt_off_t start_ptr = frt_os_pos(os);
277
+ frt_off_t end_ptr;
278
+ frt_off_t remainder, length, len;
300
279
  frt_uchar buffer[FRT_BUFFER_SIZE];
301
280
 
302
281
  FrtInStream *is = cw->store->open_input(cw->store, src->name);
@@ -329,8 +308,7 @@ static void cw_copy_file(FrtCompoundWriter *cw, FrtCWFileEntry *src, FrtOutStrea
329
308
  frt_is_close(is);
330
309
  }
331
310
 
332
- void frt_cw_close(FrtCompoundWriter *cw, FrtDeleter *dlr)
333
- {
311
+ void frt_cw_close(FrtCompoundWriter *cw, FrtDeleter *dlr) {
334
312
  FrtOutStream *os = NULL;
335
313
  int i;
336
314
 
@@ -366,12 +344,9 @@ void frt_cw_close(FrtCompoundWriter *cw, FrtDeleter *dlr)
366
344
  frt_os_seek(os, cw->file_entries[i].dir_offset);
367
345
  frt_os_write_u64(os, cw->file_entries[i].data_offset);
368
346
  }
369
-
370
- if (os) {
371
- frt_os_close(os);
372
- }
373
-
347
+ frt_os_close(os);
374
348
  frt_hs_destroy(cw->ids);
375
349
  frt_ary_free(cw->file_entries);
350
+ frt_store_close(cw->store);
376
351
  free(cw);
377
352
  }
@@ -1,6 +1,8 @@
1
1
  #ifndef FRT_DEFINES_H
2
2
  #define FRT_DEFINES_H
3
3
 
4
+ #define _FILE_OFFSET_BITS 64
5
+
4
6
  #include <sys/types.h>
5
7
  #include <limits.h>
6
8
  #include "frt_posh.h"
@@ -24,6 +26,12 @@ typedef posh_i32_t frt_i32;
24
26
  typedef posh_u64_t frt_u64;
25
27
  typedef posh_i64_t frt_i64;
26
28
 
29
+ #if defined POSH_OS_WIN64
30
+ typedef off64_t frt_off_t;
31
+ #else
32
+ typedef off_t frt_off_t;
33
+ #endif
34
+
27
35
  #if ( LONG_MAX == 2147483647 ) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
28
36
  #define FRT_OFF_T_PFX "ll"
29
37
  #else
@@ -33,6 +33,7 @@ static frt_thread_once_t exception_stack_key_once = FRT_THREAD_ONCE_INIT;
33
33
 
34
34
  static void exception_stack_alloc(void) {
35
35
  frt_thread_key_create(&exception_stack_key, NULL);
36
+ frt_thread_setspecific(exception_stack_key, NULL);
36
37
  }
37
38
 
38
39
  void frt_xpush_context(frt_xcontext_t *context) {
@@ -1,7 +1,7 @@
1
1
  #include <string.h>
2
2
  #include "frt_field_index.h"
3
3
 
4
- #undef close
4
+ // #undef close
5
5
 
6
6
  /***************************************************************************
7
7
  *
@@ -14,9 +14,7 @@ void frt_filt_destroy_i(FrtFilter *filt) {
14
14
  }
15
15
 
16
16
  void frt_filt_deref(FrtFilter *filt) {
17
- if (--(filt->ref_cnt) == 0) {
18
- filt->destroy_i(filt);
19
- }
17
+ if (FRT_DEREF(filt) == 0) filt->destroy_i(filt);
20
18
  }
21
19
 
22
20
  FrtBitVector *frt_filt_get_bv(FrtFilter *filt, FrtIndexReader *ir) {
@@ -97,7 +95,7 @@ static FrtBitVector *qfilt_get_bv_i(FrtFilter *filt, FrtIndexReader *ir) {
97
95
  scorer->destroy(scorer);
98
96
  }
99
97
  weight->destroy(weight);
100
- free(sea);
98
+ frt_searcher_close(sea);
101
99
  return bv;
102
100
  }
103
101
 
@@ -223,10 +223,9 @@ static void fs_destroy(FrtStore *store)
223
223
  FRT_HANDLED();
224
224
  FRT_XENDTRY
225
225
  free(store->dir.path);
226
- frt_store_destroy(store);
227
226
  }
228
227
 
229
- static off_t fs_length(FrtStore *store, const char *filename)
228
+ static frt_off_t fs_length(FrtStore *store, const char *filename)
230
229
  {
231
230
  char path[FRT_MAX_FILE_PATH];
232
231
  struct stat stt;
@@ -248,9 +247,12 @@ static void fso_flush_i(FrtOutStream *os, const frt_uchar *src, int len)
248
247
  }
249
248
  }
250
249
 
251
- static void fso_seek_i(FrtOutStream *os, off_t pos)
252
- {
250
+ static void fso_seek_i(FrtOutStream *os, frt_off_t pos) {
251
+ #if (defined POSH_OS_WIN32 || defined POSH_OS_WIN64)
252
+ if (_lseeki64(os->file.fd, pos, SEEK_SET) < 0) {
253
+ #else
253
254
  if (lseek(os->file.fd, pos, SEEK_SET) < 0) {
255
+ #endif
254
256
  FRT_RAISE(FRT_IO_ERROR, "seeking position %"FRT_OFF_T_PFX"d: <%s>",
255
257
  pos, strerror(errno));
256
258
  }
@@ -286,8 +288,8 @@ static FrtOutStream *fs_new_output(FrtStore *store, const char *filename)
286
288
 
287
289
  static void fsi_read_i(FrtInStream *is, frt_uchar *path, int len)
288
290
  {
289
- int fd = is->file.fd;
290
- off_t pos = frt_is_pos(is);
291
+ int fd = is->f->file.fd;
292
+ frt_off_t pos = frt_is_pos(is);
291
293
  if (pos != lseek(fd, 0, SEEK_CUR)) {
292
294
  lseek(fd, pos, SEEK_SET);
293
295
  }
@@ -300,9 +302,12 @@ static void fsi_read_i(FrtInStream *is, frt_uchar *path, int len)
300
302
  }
301
303
  }
302
304
 
303
- static void fsi_seek_i(FrtInStream *is, off_t pos)
304
- {
305
- if (lseek(is->file.fd, pos, SEEK_SET) < 0) {
305
+ static void fsi_seek_i(FrtInStream *is, frt_off_t pos) {
306
+ #if (defined POSH_OS_WIN32 || defined POSH_OS_WIN64)
307
+ if (_lseeki64(is->f->file.fd, pos, SEEK_SET) < 0) {
308
+ #else
309
+ if (lseek(is->f->file.fd, pos, SEEK_SET) < 0) {
310
+ #endif
306
311
  FRT_RAISE(FRT_IO_ERROR, "seeking pos %"FRT_OFF_T_PFX"d: <%s>",
307
312
  pos, strerror(errno));
308
313
  }
@@ -310,16 +315,16 @@ static void fsi_seek_i(FrtInStream *is, off_t pos)
310
315
 
311
316
  static void fsi_close_i(FrtInStream *is)
312
317
  {
313
- if (close(is->file.fd)) {
318
+ if (close(is->f->file.fd)) {
314
319
  FRT_RAISE(FRT_IO_ERROR, "%s", strerror(errno));
315
320
  }
316
- free(is->d.path);
321
+ if (is->d.path) free(is->d.path);
317
322
  }
318
323
 
319
- static off_t fsi_length_i(FrtInStream *is)
324
+ static frt_off_t fsi_length_i(FrtInStream *is)
320
325
  {
321
326
  struct stat stt;
322
- if (fstat(is->file.fd, &stt)) {
327
+ if (fstat(is->f->file.fd, &stt)) {
323
328
  FRT_RAISE(FRT_IO_ERROR, "fstat failed: <%s>", strerror(errno));
324
329
  }
325
330
  return stt.st_size;
@@ -343,7 +348,8 @@ static FrtInStream *fs_open_input(FrtStore *store, const char *filename)
343
348
  path, strerror(errno));
344
349
  }
345
350
  is = frt_is_new();
346
- is->file.fd = fd;
351
+ is->f->file.fd = fd;
352
+ is->f->ref_cnt = 1;
347
353
  is->d.path = frt_estrdup(path);
348
354
  is->m = &FS_IN_STREAM_METHODS;
349
355
  return is;
@@ -400,6 +406,7 @@ static FrtLock *fs_open_lock_i(FrtStore *store, const char *lockname)
400
406
  snprintf(lname, 100, "%s%s.lck", FRT_LOCK_PREFIX, lockname);
401
407
  lock->name = frt_estrdup(join_path(path, store->dir.path, lname));
402
408
  lock->store = store;
409
+ FRT_REF(store);
403
410
  lock->obtain = &fs_lock_obtain;
404
411
  lock->release = &fs_lock_release;
405
412
  lock->is_locked = &fs_lock_is_locked;
@@ -409,6 +416,7 @@ static FrtLock *fs_open_lock_i(FrtStore *store, const char *lockname)
409
416
 
410
417
  static void fs_close_lock_i(FrtLock *lock)
411
418
  {
419
+ frt_store_close(lock->store);
412
420
  remove(lock->name);
413
421
  free(lock->name);
414
422
  free(lock);
@@ -486,11 +494,8 @@ FrtStore *frt_open_fs_store(const char *pathname)
486
494
  frt_mutex_lock(&stores_mutex);
487
495
  store = (FrtStore *)frt_h_get(stores, pathname);
488
496
  if (store) {
489
- frt_mutex_lock(&store->mutex);
490
- store->ref_cnt++;
491
- frt_mutex_unlock(&store->mutex);
492
- }
493
- else {
497
+ FRT_REF(store);
498
+ } else {
494
499
  store = fs_store_new(pathname);
495
500
  frt_h_set(stores, store->dir.path, store);
496
501
  }
@@ -116,13 +116,15 @@ char *frt_estrdup(const char *s) {
116
116
  char *frt_dbl_to_s(char *buf, double num) {
117
117
  char *p, *e;
118
118
 
119
- #ifdef FRT_IS_C99
120
119
  if (isinf(num)) {
121
- return frt_estrdup(num < 0 ? "-Infinity" : "Infinity");
120
+ if (num < 0) {
121
+ return strcpy(buf, "-Infinity");
122
+ } else {
123
+ return strcpy(buf, "Infinity");
124
+ }
122
125
  } else if (isnan(num)) {
123
- return frt_estrdup("NaN");
126
+ return strcpy(buf, "NaN");
124
127
  }
125
- #endif
126
128
 
127
129
  sprintf(buf, FRT_DBL2S, num);
128
130
  if (!(e = strchr(buf, 'e'))) {
@@ -49,7 +49,7 @@ typedef void (*frt_free_ft)(void *key);
49
49
  #define FRT_ALLOC_AND_ZERO_N(type,n) (type*)frt_ecalloc(sizeof(type)*(n))
50
50
 
51
51
  #define FRT_REF(a) (a)->ref_cnt++
52
- #define FRT_DEREF(a) (a)->ref_cnt--
52
+ #define FRT_DEREF(a) --((a)->ref_cnt)
53
53
 
54
54
  #define FRT_NEXT_NUM(index, size) (((index) + 1) % (size))
55
55
  #define FRT_PREV_NUM(index, size) (((index) + (size) - 1) % (size))