ferret 0.10.6 → 0.10.7
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.
- 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
|
|