ferret 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -5
- data/Rakefile +34 -13
- data/TODO +1 -0
- data/TUTORIAL +1 -1
- data/ext/analysis.c +87 -70
- data/ext/analysis.h +18 -6
- data/ext/array.c +1 -2
- data/ext/array.h +1 -1
- data/ext/bitvector.c +10 -6
- data/ext/bitvector.h +2 -2
- data/ext/compound_io.c +30 -27
- data/ext/document.c +15 -15
- data/ext/document.h +5 -5
- data/ext/except.c +2 -0
- data/ext/except.h +25 -23
- data/ext/extconf.rb +1 -0
- data/ext/ferret.c +10 -8
- data/ext/ferret.h +9 -8
- data/ext/field.c +29 -25
- data/ext/filter.c +52 -14
- data/ext/frtio.h +13 -0
- data/ext/fs_store.c +115 -170
- data/ext/global.c +9 -8
- data/ext/global.h +17 -13
- data/ext/hash.c +13 -19
- data/ext/hash.h +11 -11
- data/ext/hashset.c +5 -7
- data/ext/hashset.h +9 -8
- data/ext/helper.c +1 -1
- data/ext/helper.h +2 -1
- data/ext/inc/except.h +25 -23
- data/ext/inc/lang.h +11 -1
- data/ext/ind.c +33 -21
- data/ext/index.h +44 -39
- data/ext/index_io.c +61 -57
- data/ext/index_rw.c +418 -361
- data/ext/lang.c +10 -0
- data/ext/lang.h +11 -1
- data/ext/nix_io.c +135 -0
- data/ext/priorityqueue.c +16 -16
- data/ext/priorityqueue.h +9 -6
- data/ext/q_boolean.c +128 -76
- data/ext/q_const_score.c +20 -20
- data/ext/q_filtered_query.c +20 -20
- data/ext/q_fuzzy.c +37 -23
- data/ext/q_match_all.c +15 -19
- data/ext/q_multi_phrase.c +87 -46
- data/ext/q_parser.c +247 -119
- data/ext/q_phrase.c +86 -52
- data/ext/q_prefix.c +25 -14
- data/ext/q_range.c +59 -14
- data/ext/q_span.c +263 -172
- data/ext/q_term.c +62 -51
- data/ext/q_wildcard.c +24 -13
- data/ext/r_analysis.c +328 -80
- data/ext/r_doc.c +11 -6
- data/ext/r_index_io.c +40 -32
- data/ext/r_qparser.c +15 -14
- data/ext/r_search.c +270 -152
- data/ext/r_store.c +32 -17
- data/ext/ram_store.c +38 -22
- data/ext/search.c +617 -87
- data/ext/search.h +227 -163
- data/ext/similarity.c +54 -45
- data/ext/similarity.h +3 -3
- data/ext/sort.c +132 -53
- data/ext/store.c +21 -2
- data/ext/store.h +14 -14
- data/ext/tags +4322 -232
- data/ext/term.c +140 -109
- data/ext/termdocs.c +74 -60
- data/ext/vector.c +181 -152
- data/ext/w32_io.c +150 -0
- data/lib/ferret.rb +1 -1
- data/lib/ferret/analysis/standard_tokenizer.rb +4 -3
- data/lib/ferret/document/field.rb +1 -1
- data/lib/ferret/index/field_infos.rb +1 -1
- data/lib/ferret/index/term.rb +1 -1
- data/lib/ferret/query_parser/query_parser.tab.rb +8 -24
- data/lib/ferret/search.rb +1 -0
- data/lib/ferret/search/boolean_query.rb +0 -4
- data/lib/ferret/search/index_searcher.rb +21 -8
- data/lib/ferret/search/multi_phrase_query.rb +7 -0
- data/lib/ferret/search/multi_searcher.rb +261 -0
- data/lib/ferret/search/phrase_query.rb +1 -1
- data/lib/ferret/search/query.rb +34 -5
- data/lib/ferret/search/sort.rb +7 -3
- data/lib/ferret/search/sort_field.rb +8 -4
- data/lib/ferret/store/fs_store.rb +13 -6
- data/lib/ferret/store/index_io.rb +0 -14
- data/lib/ferret/store/ram_store.rb +3 -2
- data/lib/rferret.rb +1 -1
- data/test/unit/analysis/ctc_analyzer.rb +131 -0
- data/test/unit/analysis/ctc_tokenstream.rb +98 -9
- data/test/unit/index/tc_index.rb +40 -1
- data/test/unit/index/tc_term.rb +7 -0
- data/test/unit/index/th_doc.rb +8 -0
- data/test/unit/query_parser/tc_query_parser.rb +6 -4
- data/test/unit/search/rtc_sort_field.rb +6 -6
- data/test/unit/search/tc_index_searcher.rb +8 -0
- data/test/unit/search/tc_multi_searcher.rb +275 -0
- data/test/unit/search/tc_multi_searcher2.rb +126 -0
- data/test/unit/search/tc_search_and_sort.rb +66 -0
- metadata +31 -26
- data/test/unit/query_parser/rtc_query_parser.rb +0 -138
data/ext/frtio.h
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef FRT_IO_H
|
2
|
+
#define FRT_IO_H
|
3
|
+
|
4
|
+
extern char *join_path(char *buf, const char *base, const char *filename);
|
5
|
+
extern bool exists(char *path);
|
6
|
+
extern int fcount(char *path);
|
7
|
+
extern void dir_each(char *path, void (*func)(char *fname, void *arg), void *arg);
|
8
|
+
extern void fs_clear_locks(Store *store);
|
9
|
+
extern void fs_clear(Store *store);
|
10
|
+
extern void fs_clear_all(Store *store);
|
11
|
+
|
12
|
+
#endif
|
13
|
+
|
data/ext/fs_store.c
CHANGED
@@ -1,28 +1,36 @@
|
|
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
|
1
21
|
#include <sys/types.h>
|
2
|
-
#include <sys/dir.h>
|
3
|
-
#include <sys/stat.h>
|
4
|
-
#include <dirent.h>
|
5
22
|
#include <fcntl.h>
|
6
|
-
#include <
|
7
|
-
|
23
|
+
#include <sys/stat.h>
|
8
24
|
#include <errno.h>
|
9
25
|
#include <string.h>
|
10
26
|
#include <stdio.h>
|
11
|
-
|
27
|
+
|
12
28
|
|
13
29
|
static char * const FILE_OPEN_ERROR_MSG = "Couldn't open the file to read";
|
14
30
|
static char * const SEEK_ERROR_MSG = "Seek error message";
|
15
31
|
static char * const WRITE_ERROR_MSG = "Write error message";
|
16
32
|
|
17
|
-
|
18
|
-
* Create a filepath for a file in the store using the operating systems
|
19
|
-
* default file seperator.
|
20
|
-
*/
|
21
|
-
static char *join_path(char *buf, const char *base, const char *filename)
|
22
|
-
{
|
23
|
-
sprintf(buf, "%s/%s", base, filename);
|
24
|
-
return buf;
|
25
|
-
}
|
33
|
+
extern void store_destroy(Store *store);
|
26
34
|
|
27
35
|
/**
|
28
36
|
* Create the file +filename+ in the +store+.
|
@@ -31,13 +39,15 @@ static char *join_path(char *buf, const char *base, const char *filename)
|
|
31
39
|
* @param filename the name of the file to create
|
32
40
|
* @throws IO_ERROR if the file cannot be created
|
33
41
|
*/
|
34
|
-
void fs_touch(Store *store, char *filename)
|
42
|
+
static void fs_touch(Store *store, char *filename)
|
35
43
|
{
|
36
|
-
|
37
|
-
|
38
|
-
|
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) {
|
39
48
|
RAISE(IO_ERROR, strerror(errno));
|
40
|
-
|
49
|
+
}
|
50
|
+
_close(f);
|
41
51
|
}
|
42
52
|
|
43
53
|
/**
|
@@ -50,15 +60,8 @@ void fs_touch(Store *store, char *filename)
|
|
50
60
|
*/
|
51
61
|
int fs_exists(Store *store, char *filename)
|
52
62
|
{
|
53
|
-
char buf[
|
54
|
-
|
55
|
-
if (fd < 0) {
|
56
|
-
if (errno != ENOENT)
|
57
|
-
RAISE(IO_ERROR, strerror(errno));
|
58
|
-
return false;
|
59
|
-
}
|
60
|
-
close(fd);
|
61
|
-
return true;
|
63
|
+
char buf[MAX_FILE_PATH];
|
64
|
+
return exists(join_path(buf, store->dir.path, filename));
|
62
65
|
}
|
63
66
|
|
64
67
|
/**
|
@@ -71,7 +74,7 @@ int fs_exists(Store *store, char *filename)
|
|
71
74
|
*/
|
72
75
|
int fs_remove(Store *store, char *filename)
|
73
76
|
{
|
74
|
-
char buf[
|
77
|
+
char buf[MAX_FILE_PATH];
|
75
78
|
return remove(join_path(buf, store->dir.path, filename));
|
76
79
|
}
|
77
80
|
|
@@ -86,10 +89,17 @@ int fs_remove(Store *store, char *filename)
|
|
86
89
|
*/
|
87
90
|
int fs_rename(Store *store, char *from, char *to)
|
88
91
|
{
|
89
|
-
char buf1[
|
92
|
+
char buf1[MAX_FILE_PATH], buf2[MAX_FILE_PATH];
|
93
|
+
|
94
|
+
#ifdef WIN32
|
95
|
+
remove(join_path(buf1, store->dir.path, to));
|
96
|
+
#endif
|
90
97
|
|
91
|
-
|
92
|
-
|
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;
|
93
103
|
}
|
94
104
|
|
95
105
|
/**
|
@@ -101,20 +111,7 @@ int fs_rename(Store *store, char *from, char *to)
|
|
101
111
|
*/
|
102
112
|
int fs_count(Store *store)
|
103
113
|
{
|
104
|
-
|
105
|
-
struct dirent *de;
|
106
|
-
DIR *d = opendir(store->dir.path);
|
107
|
-
|
108
|
-
if (!d) RAISE(IO_ERROR, strerror(errno));
|
109
|
-
|
110
|
-
while ((de = readdir(d)) != NULL) {
|
111
|
-
if (de->d_name[0] != '.') {
|
112
|
-
cnt++;
|
113
|
-
}
|
114
|
-
}
|
115
|
-
closedir(d);
|
116
|
-
|
117
|
-
return cnt;
|
114
|
+
return fcount(store->dir.path);
|
118
115
|
}
|
119
116
|
|
120
117
|
/**
|
@@ -130,39 +127,7 @@ int fs_count(Store *store)
|
|
130
127
|
*/
|
131
128
|
void fs_each(Store *store, void (*func)(char *fname, void *arg), void *arg)
|
132
129
|
{
|
133
|
-
|
134
|
-
DIR *d = opendir(store->dir.path);
|
135
|
-
|
136
|
-
if (!d) RAISE(IO_ERROR, strerror(errno));
|
137
|
-
|
138
|
-
while ((de = readdir(d)) != NULL) {
|
139
|
-
if ((strncmp(de->d_name, LOCK_PREFIX, strlen(LOCK_PREFIX)) == 0) ||
|
140
|
-
(de->d_name[0] == '.'))
|
141
|
-
continue;
|
142
|
-
func(de->d_name, arg);
|
143
|
-
}
|
144
|
-
closedir(d);
|
145
|
-
}
|
146
|
-
|
147
|
-
/**
|
148
|
-
* Clear all the locks in the store.
|
149
|
-
*
|
150
|
-
* @param store the store to clear the locks from
|
151
|
-
* @throws IO_ERROR if there is an error opening the directory
|
152
|
-
*/
|
153
|
-
void fs_clear_locks(Store *store)
|
154
|
-
{
|
155
|
-
struct dirent *de;
|
156
|
-
DIR *d = opendir(store->dir.path);
|
157
|
-
|
158
|
-
if (!d) RAISE(IO_ERROR, strerror(errno));
|
159
|
-
|
160
|
-
while ((de = readdir(d)) != NULL) {
|
161
|
-
if (file_is_lock(de->d_name)) {
|
162
|
-
fs_remove(store, de->d_name);
|
163
|
-
}
|
164
|
-
}
|
165
|
-
closedir(d);
|
130
|
+
dir_each(store->dir.path, func, arg);
|
166
131
|
}
|
167
132
|
|
168
133
|
/**
|
@@ -171,54 +136,13 @@ void fs_clear_locks(Store *store)
|
|
171
136
|
* @param p the store to destroy
|
172
137
|
* @throws IO_ERROR if there is an error deleting the locks
|
173
138
|
*/
|
174
|
-
void fs_destroy(
|
139
|
+
void fs_destroy(Store *store)
|
175
140
|
{
|
176
|
-
Store *store = (Store *)p;
|
177
141
|
fs_clear_locks(store);
|
178
142
|
free(store->dir.path);
|
179
143
|
store_destroy(store);
|
180
144
|
}
|
181
145
|
|
182
|
-
/**
|
183
|
-
* Clear all files from the store except the lock files.
|
184
|
-
*
|
185
|
-
* @param store the store to clear all the files from
|
186
|
-
* @throws IO_ERROR if there is an error deleting the files
|
187
|
-
*/
|
188
|
-
void fs_clear(Store *store)
|
189
|
-
{
|
190
|
-
struct dirent *de;
|
191
|
-
DIR *d = opendir(store->dir.path);
|
192
|
-
|
193
|
-
if (!d) RAISE(IO_ERROR, strerror(errno));
|
194
|
-
|
195
|
-
while ((de = readdir(d)) != NULL) {
|
196
|
-
if (de->d_name[0] != '.' && !file_is_lock(de->d_name)) {
|
197
|
-
fs_remove(store, de->d_name);
|
198
|
-
}
|
199
|
-
}
|
200
|
-
closedir(d);
|
201
|
-
}
|
202
|
-
|
203
|
-
/**
|
204
|
-
* Clear all files from the store including the lock files.
|
205
|
-
*
|
206
|
-
* @param store the store to clear all the files from
|
207
|
-
* @throws IO_ERROR if there is an error deleting the files
|
208
|
-
*/
|
209
|
-
void fs_clear_all(Store *store)
|
210
|
-
{
|
211
|
-
struct dirent *de;
|
212
|
-
DIR *d = opendir(store->dir.path);
|
213
|
-
|
214
|
-
while ((de = readdir(d)) != NULL) {
|
215
|
-
if (de->d_name[0] != '.') {
|
216
|
-
fs_remove(store, de->d_name);
|
217
|
-
}
|
218
|
-
}
|
219
|
-
closedir(d);
|
220
|
-
}
|
221
|
-
|
222
146
|
/**
|
223
147
|
* Return the length of the file +filename+ in +store+
|
224
148
|
*
|
@@ -229,7 +153,7 @@ void fs_clear_all(Store *store)
|
|
229
153
|
*/
|
230
154
|
int fs_length(Store *store, char *filename)
|
231
155
|
{
|
232
|
-
char buf[
|
156
|
+
char buf[MAX_FILE_PATH];
|
233
157
|
struct stat stt;
|
234
158
|
|
235
159
|
if (stat(join_path(buf, store->dir.path, filename), &stt))
|
@@ -288,11 +212,12 @@ void fso_close_internal(OutStream *os)
|
|
288
212
|
*/
|
289
213
|
OutStream *fs_create_output(Store *store, const char *filename)
|
290
214
|
{
|
291
|
-
char buf[
|
215
|
+
char buf[MAX_FILE_PATH];
|
292
216
|
FILE *f = fopen(join_path(buf, store->dir.path, filename), "wb");
|
217
|
+
OutStream *os;
|
293
218
|
if (!f) RAISE(IO_ERROR, strerror(errno));
|
294
219
|
|
295
|
-
|
220
|
+
os = os_create();
|
296
221
|
os->file = f;
|
297
222
|
os->flush_internal = &fso_flush_internal;
|
298
223
|
os->seek_internal = &fso_seek_internal;
|
@@ -315,11 +240,14 @@ void fsi_read_internal(InStream *is, uchar *b, int offset, int len)
|
|
315
240
|
{
|
316
241
|
int fd = (int)is->file;
|
317
242
|
int pos = is_pos(is);
|
318
|
-
if (pos !=
|
319
|
-
|
243
|
+
if (pos != _lseek(fd, 0, SEEK_CUR)) {
|
244
|
+
_lseek(fd, pos, SEEK_SET);
|
320
245
|
}
|
321
|
-
if (
|
322
|
-
|
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));
|
250
|
+
}
|
323
251
|
}
|
324
252
|
}
|
325
253
|
|
@@ -332,8 +260,9 @@ void fsi_read_internal(InStream *is, uchar *b, int offset, int len)
|
|
332
260
|
*/
|
333
261
|
void fsi_seek_internal(InStream *is, int pos)
|
334
262
|
{
|
335
|
-
if (
|
263
|
+
if (_lseek((int)is->file, pos, SEEK_SET) < 0) {
|
336
264
|
RAISE(IO_ERROR, strerror(errno));
|
265
|
+
}
|
337
266
|
}
|
338
267
|
|
339
268
|
/**
|
@@ -345,18 +274,13 @@ void fsi_seek_internal(InStream *is, int pos)
|
|
345
274
|
void fsi_close_internal(InStream *is)
|
346
275
|
{
|
347
276
|
if (!is->is_clone) {
|
348
|
-
if (
|
277
|
+
if (_close((int)is->file)) {
|
349
278
|
RAISE(IO_ERROR, strerror(errno));
|
279
|
+
}
|
350
280
|
free(is->d.path);
|
351
281
|
}
|
352
282
|
}
|
353
283
|
|
354
|
-
/**
|
355
|
-
* Clone the input stream. Nothing to do for a file system input stream
|
356
|
-
*/
|
357
|
-
void fsi_clone_internal(InStream *is, InStream *new_is)
|
358
|
-
{ }
|
359
|
-
|
360
284
|
/**
|
361
285
|
* Returns the length of the input stream +is+
|
362
286
|
*
|
@@ -365,12 +289,19 @@ void fsi_clone_internal(InStream *is, InStream *new_is)
|
|
365
289
|
*/
|
366
290
|
int fsi_length(InStream *is)
|
367
291
|
{
|
368
|
-
struct
|
369
|
-
if (
|
292
|
+
struct _stat stt;
|
293
|
+
if (_fstat((int)is->file, &stt)) {
|
370
294
|
RAISE(IO_ERROR, strerror(errno));
|
295
|
+
}
|
371
296
|
return stt.st_size;
|
372
297
|
}
|
373
298
|
|
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
|
+
{ }
|
304
|
+
|
374
305
|
/**
|
375
306
|
* Open an input stream in the +store+ with the name +filename+
|
376
307
|
*
|
@@ -380,11 +311,14 @@ int fsi_length(InStream *is)
|
|
380
311
|
*/
|
381
312
|
InStream *fs_open_input(Store *store, const char *filename)
|
382
313
|
{
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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();
|
388
322
|
is->file = (void *)fd;
|
389
323
|
is->d.path = estrdup(buf);
|
390
324
|
is->is_clone = false;
|
@@ -407,11 +341,12 @@ int fs_lock_obtain(Lock *lock)
|
|
407
341
|
{
|
408
342
|
int f;
|
409
343
|
int trys = LOCK_OBTAIN_TIMEOUT;
|
410
|
-
while (((f =
|
411
|
-
|
344
|
+
while (((f = _open(lock->name, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR)) < 0) &&
|
345
|
+
(trys > 0)) {
|
412
346
|
trys--;
|
347
|
+
}
|
413
348
|
if (f >= 0) {
|
414
|
-
|
349
|
+
_close(f);
|
415
350
|
return true;
|
416
351
|
} else {
|
417
352
|
return false;
|
@@ -426,10 +361,11 @@ int fs_lock_obtain(Lock *lock)
|
|
426
361
|
*/
|
427
362
|
int fs_lock_is_locked(Lock *lock)
|
428
363
|
{
|
429
|
-
int f =
|
364
|
+
int f = _open(lock->name, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
|
430
365
|
if (f >= 0) {
|
431
|
-
if (
|
366
|
+
if (_close(f) || remove(lock->name)) {
|
432
367
|
RAISE(IO_ERROR, strerror(errno));
|
368
|
+
}
|
433
369
|
return false;
|
434
370
|
} else {
|
435
371
|
return true;
|
@@ -445,7 +381,7 @@ Lock *fs_open_lock(Store *store, char *lockname)
|
|
445
381
|
{
|
446
382
|
Lock *lock = ALLOC(Lock);
|
447
383
|
char lname[100];
|
448
|
-
char buf[
|
384
|
+
char buf[MAX_FILE_PATH];
|
449
385
|
sprintf(lname, "%s%s.lck", LOCK_PREFIX, lockname);
|
450
386
|
lock->name = estrdup(join_path(buf, store->dir.path, lname));
|
451
387
|
lock->obtain = &fs_lock_obtain;
|
@@ -461,6 +397,20 @@ void fs_close_lock(Lock *lock)
|
|
461
397
|
free(lock);
|
462
398
|
}
|
463
399
|
|
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
|
464
414
|
static HshTable stores = {
|
465
415
|
fill:0,
|
466
416
|
used:0,
|
@@ -469,38 +419,33 @@ static HshTable stores = {
|
|
469
419
|
lookup:&h_lookup_str,
|
470
420
|
hash:NULL,
|
471
421
|
eq:NULL,
|
472
|
-
free_key:dummy_free,
|
473
|
-
free_value
|
422
|
+
free_key:(free_ft)&dummy_free,
|
423
|
+
free_value:(free_ft)&fs_destroy
|
474
424
|
};
|
425
|
+
#endif
|
475
426
|
|
476
427
|
#ifndef FERRET_EXT
|
477
428
|
static mutex_t stores_mutex = MUTEX_INITIALIZER;
|
478
429
|
#endif
|
479
430
|
|
480
|
-
void
|
431
|
+
void fs_close_i(Store *store)
|
481
432
|
{
|
482
|
-
mutex_lock(&
|
483
|
-
|
484
|
-
|
485
|
-
h_del(&stores, store->dir.path);
|
486
|
-
mutex_unlock(&stores_mutex);
|
487
|
-
} else {
|
488
|
-
mutex_unlock(&store->mutex);
|
489
|
-
}
|
433
|
+
mutex_lock(&stores_mutex);
|
434
|
+
h_del(&stores, store->dir.path);
|
435
|
+
mutex_unlock(&stores_mutex);
|
490
436
|
}
|
491
437
|
|
492
438
|
Store *fs_store_create(const char *pathname)
|
493
439
|
{
|
494
440
|
Store *new_store = store_create();
|
495
|
-
|
496
|
-
new_store->ref_cnt = 0;
|
441
|
+
|
497
442
|
new_store->dir.path = estrdup(pathname);
|
498
443
|
new_store->touch = &fs_touch;
|
499
444
|
new_store->exists = &fs_exists;
|
500
445
|
new_store->remove = &fs_remove;
|
501
446
|
new_store->rename = &fs_rename;
|
502
447
|
new_store->count = &fs_count;
|
503
|
-
new_store->
|
448
|
+
new_store->close_i = &fs_close_i;
|
504
449
|
new_store->clear = &fs_clear;
|
505
450
|
new_store->clear_all = &fs_clear_all;
|
506
451
|
new_store->clear_locks = &fs_clear_locks;
|
@@ -519,15 +464,15 @@ Store *open_fs_store(const char *pathname)
|
|
519
464
|
|
520
465
|
mutex_lock(&stores_mutex);
|
521
466
|
store = h_get(&stores, pathname);
|
522
|
-
if (
|
467
|
+
if (store) {
|
468
|
+
mutex_lock(&store->mutex);
|
469
|
+
store->ref_cnt++;
|
470
|
+
mutex_unlock(&store->mutex);
|
471
|
+
} else {
|
523
472
|
store = fs_store_create(pathname);
|
524
|
-
h_set(&stores,
|
473
|
+
h_set(&stores, store->dir.path, store);
|
525
474
|
}
|
526
475
|
mutex_unlock(&stores_mutex);
|
527
476
|
|
528
|
-
mutex_lock(&store->mutex);
|
529
|
-
store->ref_cnt++;
|
530
|
-
mutex_unlock(&store->mutex);
|
531
|
-
|
532
477
|
return store;
|
533
478
|
}
|