ferret 0.10.6 → 0.10.7
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/analysis.c +136 -107
- data/ext/analysis.h +4 -0
- data/ext/bitvector.c +2 -2
- data/ext/bitvector.h +1 -1
- data/ext/compound_io.c +4 -4
- data/ext/defines.h +0 -2
- data/ext/filter.c +3 -3
- data/ext/fs_store.c +4 -4
- data/ext/hash.c +29 -18
- data/ext/hash.h +34 -16
- data/ext/hashset.c +6 -3
- data/ext/hashset.h +1 -1
- data/ext/index.c +22 -20
- data/ext/q_boolean.c +3 -3
- data/ext/q_const_score.c +1 -1
- data/ext/q_fuzzy.c +1 -1
- data/ext/q_match_all.c +1 -1
- data/ext/q_multi_term.c +2 -2
- data/ext/q_parser.c +21 -6
- data/ext/q_phrase.c +2 -2
- data/ext/q_prefix.c +1 -1
- data/ext/q_range.c +3 -3
- data/ext/q_span.c +8 -8
- data/ext/q_term.c +1 -1
- data/ext/q_wildcard.c +1 -1
- data/ext/r_analysis.c +10 -4
- data/ext/r_index.c +89 -12
- data/ext/r_qparser.c +67 -4
- data/ext/r_search.c +11 -1
- data/ext/r_store.c +51 -35
- data/ext/ram_store.c +18 -18
- data/ext/search.c +1 -1
- data/ext/search.h +25 -23
- data/ext/similarity.c +1 -1
- data/ext/sort.c +1 -1
- data/ext/store.c +22 -3
- data/ext/store.h +8 -2
- data/lib/ferret/index.rb +14 -4
- data/lib/ferret_version.rb +1 -1
- data/test/test_helper.rb +3 -0
- data/test/unit/analysis/tc_analyzer.rb +5 -5
- data/test/unit/analysis/tc_token_stream.rb +3 -3
- data/test/unit/index/tc_index_writer.rb +1 -1
- data/test/unit/query_parser/tc_query_parser.rb +7 -5
- data/test/unit/search/tc_filter.rb +1 -1
- data/test/unit/search/tc_fuzzy_query.rb +1 -1
- data/test/unit/search/tc_index_searcher.rb +1 -1
- data/test/unit/search/tc_multi_searcher.rb +1 -1
- data/test/unit/search/tc_search_and_sort.rb +1 -1
- data/test/unit/search/tc_spans.rb +1 -1
- metadata +4 -3
data/ext/r_search.c
CHANGED
@@ -2234,7 +2234,7 @@ typedef struct CWrappedFilter
|
|
2234
2234
|
} CWrappedFilter;
|
2235
2235
|
#define CWF(filt) ((CWrappedFilter *)(filt))
|
2236
2236
|
|
2237
|
-
static
|
2237
|
+
static unsigned long
|
2238
2238
|
cwfilt_hash(Filter *filt)
|
2239
2239
|
{
|
2240
2240
|
return NUM2ULONG(rb_funcall(CWF(filt)->rfilter, id_hash, 0));
|
@@ -2676,6 +2676,10 @@ frt_ms_init(int argc, VALUE *argv, VALUE self)
|
|
2676
2676
|
*
|
2677
2677
|
****************************************************************************/
|
2678
2678
|
|
2679
|
+
/* rdochack
|
2680
|
+
cTopDocs = rb_define_class_under(mSearch, "TopDocs", rb_cObject);
|
2681
|
+
*/
|
2682
|
+
|
2679
2683
|
/*
|
2680
2684
|
* Document-class: Ferret::Search::Hit
|
2681
2685
|
*
|
@@ -2691,6 +2695,9 @@ static void
|
|
2691
2695
|
Init_Hit(void)
|
2692
2696
|
{
|
2693
2697
|
const char *hit_class = "Hit";
|
2698
|
+
/* rdochack
|
2699
|
+
cHit = rb_define_class_under(mSearch, "Hit", rb_cObject);
|
2700
|
+
*/
|
2694
2701
|
cHit = rb_struct_define(hit_class, "doc", "score", NULL);
|
2695
2702
|
rb_set_class_path(cHit, mSearch, hit_class);
|
2696
2703
|
rb_const_set(mSearch, rb_intern(hit_class), cHit);
|
@@ -2720,6 +2727,9 @@ static void
|
|
2720
2727
|
Init_TopDocs(void)
|
2721
2728
|
{
|
2722
2729
|
const char *td_class = "TopDocs";
|
2730
|
+
/* rdochack
|
2731
|
+
cTopDocs = rb_define_class_under(mSearch, "TopDocs", rb_cObject);
|
2732
|
+
*/
|
2723
2733
|
cTopDocs = rb_struct_define(td_class,
|
2724
2734
|
"total_hits",
|
2725
2735
|
"hits",
|
data/ext/r_store.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "ferret.h"
|
2
2
|
#include "store.h"
|
3
3
|
|
4
|
+
static ID id_ref_cnt;
|
4
5
|
VALUE cLock;
|
5
6
|
VALUE cLockError;
|
6
7
|
VALUE cDirectory;
|
@@ -13,16 +14,26 @@ VALUE cFSDirectory;
|
|
13
14
|
*
|
14
15
|
****************************************************************************/
|
15
16
|
|
17
|
+
void
|
18
|
+
frt_unwrap_locks(Store *store)
|
19
|
+
{
|
20
|
+
int i;
|
21
|
+
for (i = 0; i < store->locks->size; i++) {
|
22
|
+
void *lock = store->locks->elems[i];
|
23
|
+
VALUE rlock = object_get(lock);
|
24
|
+
object_del(lock);
|
25
|
+
if (rlock != Qnil) {
|
26
|
+
Frt_Unwrap_Struct(rlock);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
16
31
|
void
|
17
32
|
frt_lock_free(void *p)
|
18
33
|
{
|
19
34
|
Lock *lock = (Lock *)p;
|
20
|
-
|
21
|
-
|
22
|
-
} else {
|
23
|
-
free(lock->name);
|
24
|
-
free(lock);
|
25
|
-
}
|
35
|
+
object_del(p);
|
36
|
+
close_lock(lock);
|
26
37
|
}
|
27
38
|
|
28
39
|
void
|
@@ -141,11 +152,11 @@ frt_lock_release(VALUE self)
|
|
141
152
|
void
|
142
153
|
frt_dir_free(Store *store)
|
143
154
|
{
|
155
|
+
frt_unwrap_locks(store);
|
144
156
|
object_del(store);
|
145
157
|
store_deref(store);
|
146
158
|
}
|
147
159
|
|
148
|
-
#define GET_STORE(store, self) Data_Get_Struct(self, Store, store)
|
149
160
|
/*
|
150
161
|
* call-seq:
|
151
162
|
* dir.close() -> nil
|
@@ -157,13 +168,15 @@ frt_dir_free(Store *store)
|
|
157
168
|
static VALUE
|
158
169
|
frt_dir_close(VALUE self)
|
159
170
|
{
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
171
|
+
Store *store = DATA_PTR(self);
|
172
|
+
int ref_cnt = FIX2INT(rb_ivar_get(self, id_ref_cnt)) - 1;
|
173
|
+
rb_ivar_set(self, id_ref_cnt, INT2FIX(ref_cnt));
|
174
|
+
if (ref_cnt < 0) {
|
175
|
+
Frt_Unwrap_Struct(self);
|
176
|
+
object_del(store);
|
177
|
+
frt_unwrap_locks(store);
|
178
|
+
store_deref(store);
|
179
|
+
}
|
167
180
|
return Qnil;
|
168
181
|
}
|
169
182
|
|
@@ -176,8 +189,7 @@ frt_dir_close(VALUE self)
|
|
176
189
|
static VALUE
|
177
190
|
frt_dir_exists(VALUE self, VALUE rfname)
|
178
191
|
{
|
179
|
-
Store *store;
|
180
|
-
GET_STORE(store, self);
|
192
|
+
Store *store = DATA_PTR(self);
|
181
193
|
StringValue(rfname);
|
182
194
|
return store->exists(store, RSTRING(rfname)->ptr) ? Qtrue : Qfalse;
|
183
195
|
}
|
@@ -191,8 +203,7 @@ frt_dir_exists(VALUE self, VALUE rfname)
|
|
191
203
|
static VALUE
|
192
204
|
frt_dir_touch(VALUE self, VALUE rfname)
|
193
205
|
{
|
194
|
-
Store *store;
|
195
|
-
GET_STORE(store, self);
|
206
|
+
Store *store = DATA_PTR(self);
|
196
207
|
StringValue(rfname);
|
197
208
|
store->touch(store, RSTRING(rfname)->ptr);
|
198
209
|
return Qnil;
|
@@ -207,8 +218,7 @@ frt_dir_touch(VALUE self, VALUE rfname)
|
|
207
218
|
static VALUE
|
208
219
|
frt_dir_delete(VALUE self, VALUE rfname)
|
209
220
|
{
|
210
|
-
Store *store;
|
211
|
-
GET_STORE(store, self);
|
221
|
+
Store *store = DATA_PTR(self);
|
212
222
|
StringValue(rfname);
|
213
223
|
return (store->remove(store, RSTRING(rfname)->ptr) == 0) ? Qtrue : Qfalse;
|
214
224
|
}
|
@@ -222,8 +232,7 @@ frt_dir_delete(VALUE self, VALUE rfname)
|
|
222
232
|
static VALUE
|
223
233
|
frt_dir_file_count(VALUE self)
|
224
234
|
{
|
225
|
-
Store *store;
|
226
|
-
GET_STORE(store, self);
|
235
|
+
Store *store = DATA_PTR(self);
|
227
236
|
return INT2FIX(store->count(store));
|
228
237
|
}
|
229
238
|
|
@@ -236,8 +245,7 @@ frt_dir_file_count(VALUE self)
|
|
236
245
|
static VALUE
|
237
246
|
frt_dir_refresh(VALUE self)
|
238
247
|
{
|
239
|
-
Store *store;
|
240
|
-
GET_STORE(store, self);
|
248
|
+
Store *store = DATA_PTR(self);
|
241
249
|
store->clear_all(store);
|
242
250
|
return self;
|
243
251
|
}
|
@@ -252,8 +260,7 @@ frt_dir_refresh(VALUE self)
|
|
252
260
|
static VALUE
|
253
261
|
frt_dir_rename(VALUE self, VALUE rfrom, VALUE rto)
|
254
262
|
{
|
255
|
-
Store *store;
|
256
|
-
GET_STORE(store, self);
|
263
|
+
Store *store = DATA_PTR(self);
|
257
264
|
StringValue(rfrom);
|
258
265
|
StringValue(rto);
|
259
266
|
store->rename(store, RSTRING(rfrom)->ptr, RSTRING(rto)->ptr);
|
@@ -272,11 +279,14 @@ frt_dir_rename(VALUE self, VALUE rfrom, VALUE rto)
|
|
272
279
|
static VALUE
|
273
280
|
frt_dir_make_lock(VALUE self, VALUE rlock_name)
|
274
281
|
{
|
275
|
-
|
276
|
-
|
282
|
+
VALUE rlock;
|
283
|
+
Lock *lock;
|
284
|
+
Store *store = DATA_PTR(self);
|
277
285
|
StringValue(rlock_name);
|
278
|
-
|
279
|
-
|
286
|
+
lock = open_lock(store, RSTRING(rlock_name)->ptr);
|
287
|
+
rlock = Data_Wrap_Struct(cLock, &frt_lock_mark, &frt_lock_free, lock);
|
288
|
+
object_add(lock, rlock);
|
289
|
+
return rlock;
|
280
290
|
}
|
281
291
|
|
282
292
|
/****************************************************************************
|
@@ -311,8 +321,9 @@ frt_ramdir_init(int argc, VALUE *argv, VALUE self)
|
|
311
321
|
}
|
312
322
|
default: store = open_ram_store();
|
313
323
|
}
|
314
|
-
Frt_Wrap_Struct(self, NULL, frt_dir_free, store);
|
324
|
+
Frt_Wrap_Struct(self, NULL, &frt_dir_free, store);
|
315
325
|
object_add(store, self);
|
326
|
+
rb_ivar_set(self, id_ref_cnt, INT2FIX(0));
|
316
327
|
return self;
|
317
328
|
}
|
318
329
|
|
@@ -350,16 +361,20 @@ frt_fsdir_new(int argc, VALUE *argv, VALUE klass)
|
|
350
361
|
frt_create_dir(rpath);
|
351
362
|
}
|
352
363
|
if (!rb_funcall(rb_cFile, id_is_directory, 1, rpath)) {
|
353
|
-
rb_raise(rb_eIOError, "
|
354
|
-
"create one.", RSTRING(rpath)->ptr);
|
364
|
+
rb_raise(rb_eIOError, "No directory <%s> found. Use :create => true"
|
365
|
+
" to create one.", RSTRING(rpath)->ptr);
|
355
366
|
}
|
356
367
|
store = open_fs_store(RSTRING(rpath)->ptr);
|
357
368
|
if (create) store->clear_all(store);
|
358
369
|
if ((self = object_get(store)) == Qnil) {
|
359
370
|
self = Data_Wrap_Struct(klass, NULL, &frt_dir_free, store);
|
360
371
|
object_add(store, self);
|
361
|
-
|
362
|
-
|
372
|
+
rb_ivar_set(self, id_ref_cnt, INT2FIX(0));
|
373
|
+
}
|
374
|
+
else {
|
375
|
+
int ref_cnt = FIX2INT(rb_ivar_get(self, id_ref_cnt)) + 1;
|
376
|
+
rb_ivar_set(self, id_ref_cnt, INT2FIX(ref_cnt));
|
377
|
+
DEREF(store);
|
363
378
|
}
|
364
379
|
return self;
|
365
380
|
}
|
@@ -489,6 +504,7 @@ extern VALUE mFerret = rb_define_module("Ferret");
|
|
489
504
|
void
|
490
505
|
Init_Store(void)
|
491
506
|
{
|
507
|
+
id_ref_cnt = rb_intern("@id_ref_cnt");
|
492
508
|
mStore = rb_define_module_under(mFerret, "Store");
|
493
509
|
Init_Directory();
|
494
510
|
Init_Lock();
|
data/ext/ram_store.c
CHANGED
@@ -389,7 +389,7 @@ static void ram_lock_release(Lock *lock)
|
|
389
389
|
ram_remove(lock->store, lock->name);
|
390
390
|
}
|
391
391
|
|
392
|
-
static Lock *
|
392
|
+
static Lock *ram_open_lock_i(Store *store, char *lockname)
|
393
393
|
{
|
394
394
|
Lock *lock = ALLOC(Lock);
|
395
395
|
char lname[100];
|
@@ -402,7 +402,7 @@ static Lock *ram_open_lock(Store *store, char *lockname)
|
|
402
402
|
return lock;
|
403
403
|
}
|
404
404
|
|
405
|
-
static void
|
405
|
+
static void ram_close_lock_i(Lock *lock)
|
406
406
|
{
|
407
407
|
free(lock->name);
|
408
408
|
free(lock);
|
@@ -413,22 +413,22 @@ Store *open_ram_store()
|
|
413
413
|
{
|
414
414
|
Store *new_store = store_new();
|
415
415
|
|
416
|
-
new_store->dir.ht
|
417
|
-
new_store->touch
|
418
|
-
new_store->exists
|
419
|
-
new_store->remove
|
420
|
-
new_store->rename
|
421
|
-
new_store->count
|
422
|
-
new_store->clear
|
423
|
-
new_store->clear_all
|
424
|
-
new_store->clear_locks
|
425
|
-
new_store->length
|
426
|
-
new_store->each
|
427
|
-
new_store->new_output
|
428
|
-
new_store->open_input
|
429
|
-
new_store->
|
430
|
-
new_store->
|
431
|
-
new_store->close_i
|
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_i = &ram_open_lock_i;
|
430
|
+
new_store->close_lock_i = &ram_close_lock_i;
|
431
|
+
new_store->close_i = &ram_close_i;
|
432
432
|
return new_store;
|
433
433
|
}
|
434
434
|
|
data/ext/search.c
CHANGED
data/ext/search.h
CHANGED
@@ -99,14 +99,14 @@ extern char *td_to_s(TopDocs *td);
|
|
99
99
|
|
100
100
|
typedef struct Filter
|
101
101
|
{
|
102
|
-
char
|
103
|
-
HashTable
|
104
|
-
BitVector
|
105
|
-
char
|
106
|
-
|
107
|
-
int
|
108
|
-
void
|
109
|
-
int
|
102
|
+
char *name;
|
103
|
+
HashTable *cache;
|
104
|
+
BitVector *(*get_bv_i)(struct Filter *self, IndexReader *ir);
|
105
|
+
char *(*to_s)(struct Filter *self);
|
106
|
+
unsigned long (*hash)(struct Filter *self);
|
107
|
+
int (*eq)(struct Filter *self, struct Filter *o);
|
108
|
+
void (*destroy_i)(struct Filter *self);
|
109
|
+
int ref_cnt;
|
110
110
|
} Filter;
|
111
111
|
|
112
112
|
#define filt_new(type) filt_create(sizeof(type), #type)
|
@@ -114,7 +114,7 @@ extern Filter *filt_create(size_t size, const char *name);
|
|
114
114
|
extern BitVector *filt_get_bv(Filter *filt, IndexReader *ir);
|
115
115
|
extern void filt_destroy_i(Filter *filt);
|
116
116
|
extern void filt_deref(Filter *filt);
|
117
|
-
extern
|
117
|
+
extern unsigned long filt_hash(Filter *filt);
|
118
118
|
extern int filt_eq(Filter *filt, Filter *o);
|
119
119
|
|
120
120
|
/***************************************************************************
|
@@ -196,18 +196,18 @@ enum QUERY_TYPE
|
|
196
196
|
|
197
197
|
struct Query
|
198
198
|
{
|
199
|
-
int
|
200
|
-
float
|
201
|
-
Weight
|
202
|
-
Query
|
203
|
-
void
|
204
|
-
Similarity
|
205
|
-
char
|
206
|
-
|
207
|
-
int
|
208
|
-
void
|
209
|
-
Weight
|
210
|
-
MatchVector
|
199
|
+
int ref_cnt;
|
200
|
+
float boost;
|
201
|
+
Weight *weight;
|
202
|
+
Query *(*rewrite)(Query *self, IndexReader *ir);
|
203
|
+
void (*extract_terms)(Query *self, HashSet *terms);
|
204
|
+
Similarity *(*get_similarity)(Query *self, Searcher *searcher);
|
205
|
+
char *(*to_s)(Query *self, const char *field);
|
206
|
+
unsigned long (*hash)(Query *self);
|
207
|
+
int (*eq)(Query *self, Query *o);
|
208
|
+
void (*destroy_i)(Query *self);
|
209
|
+
Weight *(*create_weight_i)(Query *self, Searcher *searcher);
|
210
|
+
MatchVector *(*get_matchv_i)(Query *self, MatchVector *mv, TermVector *tv);
|
211
211
|
enum QUERY_TYPE type;
|
212
212
|
};
|
213
213
|
|
@@ -220,7 +220,7 @@ extern void q_deref(Query *self);
|
|
220
220
|
extern const char *q_get_query_name(enum QUERY_TYPE type);
|
221
221
|
extern Weight *q_weight(Query *self, Searcher *searcher);
|
222
222
|
extern Query *q_combine(Query **queries, int q_cnt);
|
223
|
-
extern
|
223
|
+
extern unsigned long q_hash(Query *self);
|
224
224
|
extern int q_eq(Query *self, Query *o);
|
225
225
|
extern Query *q_create(size_t size);
|
226
226
|
#define q_new(type) q_create(sizeof(type))
|
@@ -825,9 +825,11 @@ typedef struct QParser
|
|
825
825
|
HashSet *fields_buf;
|
826
826
|
HashSet *def_fields;
|
827
827
|
HashSet *all_fields;
|
828
|
+
HashSet *tokenized_fields;
|
828
829
|
Analyzer *analyzer;
|
829
830
|
HashTable *ts_cache;
|
830
831
|
Query *result;
|
832
|
+
TokenStream *non_tokenizer;
|
831
833
|
bool or_default : 1;
|
832
834
|
bool wild_lower : 1;
|
833
835
|
bool clean_str : 1;
|
@@ -837,7 +839,7 @@ typedef struct QParser
|
|
837
839
|
} QParser;
|
838
840
|
|
839
841
|
extern QParser *qp_new(HashSet *all_fields, HashSet *def_fields,
|
840
|
-
Analyzer *analyzer);
|
842
|
+
HashSet *tokenized_fields, Analyzer *analyzer);
|
841
843
|
extern void qp_destroy(QParser *self);
|
842
844
|
extern Query *qp_parse(QParser *self, char *qstr);
|
843
845
|
extern char *qp_clean_str(char *str);
|
data/ext/similarity.c
CHANGED
@@ -33,7 +33,7 @@ int term_eq(const void *t1, const void *t2)
|
|
33
33
|
(strcmp(((Term *)t1)->field, ((Term *)t2)->field) == 0);
|
34
34
|
}
|
35
35
|
|
36
|
-
|
36
|
+
unsigned long term_hash(const void *t)
|
37
37
|
{
|
38
38
|
return str_hash(((Term *)t)->text) * str_hash(((Term *)t)->field);
|
39
39
|
}
|
data/ext/sort.c
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
*
|
9
9
|
***************************************************************************/
|
10
10
|
|
11
|
-
|
11
|
+
unsigned long sort_field_hash(const void *p)
|
12
12
|
{
|
13
13
|
SortField *self = (SortField *)p;
|
14
14
|
return str_hash(self->field) ^ (self->type*37);
|
data/ext/store.c
CHANGED
@@ -22,19 +22,19 @@ void with_lock(Lock *lock, void (*func)(void *arg), void *arg)
|
|
22
22
|
void with_lock_name(Store *store, char *lock_name,
|
23
23
|
void (*func)(void *arg), void *arg)
|
24
24
|
{
|
25
|
-
Lock *lock = store->
|
25
|
+
Lock *lock = store->open_lock_i(store, lock_name);
|
26
26
|
if (!lock->obtain(lock)) {
|
27
27
|
RAISE(LOCK_ERROR, "couldn't obtain lock \"%s\"", lock->name);
|
28
28
|
}
|
29
29
|
func(arg);
|
30
30
|
lock->release(lock);
|
31
|
-
store->
|
31
|
+
store->close_lock_i(lock);
|
32
32
|
}
|
33
33
|
|
34
34
|
void store_deref(Store *store)
|
35
35
|
{
|
36
36
|
mutex_lock(&store->mutex_i);
|
37
|
-
if (--store->ref_cnt
|
37
|
+
if (--store->ref_cnt <= 0) {
|
38
38
|
store->close_i(store);
|
39
39
|
}
|
40
40
|
else {
|
@@ -42,6 +42,23 @@ void store_deref(Store *store)
|
|
42
42
|
}
|
43
43
|
}
|
44
44
|
|
45
|
+
Lock *open_lock(Store *store, char *lockname)
|
46
|
+
{
|
47
|
+
Lock *lock = store->open_lock_i(store, lockname);
|
48
|
+
hs_add(store->locks, lock);
|
49
|
+
return lock;
|
50
|
+
}
|
51
|
+
|
52
|
+
void close_lock(Lock *lock)
|
53
|
+
{
|
54
|
+
hs_del(lock->store->locks, lock);
|
55
|
+
}
|
56
|
+
|
57
|
+
void close_lock_i(Lock *lock)
|
58
|
+
{
|
59
|
+
lock->store->close_lock_i(lock);
|
60
|
+
}
|
61
|
+
|
45
62
|
/**
|
46
63
|
* Create a store struct initializing the mutex.
|
47
64
|
*/
|
@@ -51,6 +68,7 @@ Store *store_new()
|
|
51
68
|
store->ref_cnt = 1;
|
52
69
|
mutex_init(&store->mutex_i, NULL);
|
53
70
|
mutex_init(&store->mutex, NULL);
|
71
|
+
store->locks = hs_new(ptr_hash, ptr_eq, (free_ft)&close_lock_i);
|
54
72
|
return store;
|
55
73
|
}
|
56
74
|
|
@@ -63,6 +81,7 @@ void store_destroy(Store *store)
|
|
63
81
|
{
|
64
82
|
mutex_destroy(&store->mutex_i);
|
65
83
|
mutex_destroy(&store->mutex);
|
84
|
+
hs_destroy(store->locks);
|
66
85
|
free(store);
|
67
86
|
}
|
68
87
|
|