ferret 0.10.6 → 0.10.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/ext/analysis.c +136 -107
  2. data/ext/analysis.h +4 -0
  3. data/ext/bitvector.c +2 -2
  4. data/ext/bitvector.h +1 -1
  5. data/ext/compound_io.c +4 -4
  6. data/ext/defines.h +0 -2
  7. data/ext/filter.c +3 -3
  8. data/ext/fs_store.c +4 -4
  9. data/ext/hash.c +29 -18
  10. data/ext/hash.h +34 -16
  11. data/ext/hashset.c +6 -3
  12. data/ext/hashset.h +1 -1
  13. data/ext/index.c +22 -20
  14. data/ext/q_boolean.c +3 -3
  15. data/ext/q_const_score.c +1 -1
  16. data/ext/q_fuzzy.c +1 -1
  17. data/ext/q_match_all.c +1 -1
  18. data/ext/q_multi_term.c +2 -2
  19. data/ext/q_parser.c +21 -6
  20. data/ext/q_phrase.c +2 -2
  21. data/ext/q_prefix.c +1 -1
  22. data/ext/q_range.c +3 -3
  23. data/ext/q_span.c +8 -8
  24. data/ext/q_term.c +1 -1
  25. data/ext/q_wildcard.c +1 -1
  26. data/ext/r_analysis.c +10 -4
  27. data/ext/r_index.c +89 -12
  28. data/ext/r_qparser.c +67 -4
  29. data/ext/r_search.c +11 -1
  30. data/ext/r_store.c +51 -35
  31. data/ext/ram_store.c +18 -18
  32. data/ext/search.c +1 -1
  33. data/ext/search.h +25 -23
  34. data/ext/similarity.c +1 -1
  35. data/ext/sort.c +1 -1
  36. data/ext/store.c +22 -3
  37. data/ext/store.h +8 -2
  38. data/lib/ferret/index.rb +14 -4
  39. data/lib/ferret_version.rb +1 -1
  40. data/test/test_helper.rb +3 -0
  41. data/test/unit/analysis/tc_analyzer.rb +5 -5
  42. data/test/unit/analysis/tc_token_stream.rb +3 -3
  43. data/test/unit/index/tc_index_writer.rb +1 -1
  44. data/test/unit/query_parser/tc_query_parser.rb +7 -5
  45. data/test/unit/search/tc_filter.rb +1 -1
  46. data/test/unit/search/tc_fuzzy_query.rb +1 -1
  47. data/test/unit/search/tc_index_searcher.rb +1 -1
  48. data/test/unit/search/tc_multi_searcher.rb +1 -1
  49. data/test/unit/search/tc_search_and_sort.rb +1 -1
  50. data/test/unit/search/tc_spans.rb +1 -1
  51. 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 ulong
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
- if (object_get(lock->store) != Qnil) {
21
- lock->store->close_lock(lock);
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
- * No need to do anything here. Leave it to the garbage collector
162
- GET_STORE;
163
- Frt_Unwrap_Struct(self);
164
- object_del(store);
165
- store_deref(store);
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
- Store *store;
276
- GET_STORE(store, self);
282
+ VALUE rlock;
283
+ Lock *lock;
284
+ Store *store = DATA_PTR(self);
277
285
  StringValue(rlock_name);
278
- return Data_Wrap_Struct(cLock, &frt_lock_mark, &frt_lock_free,
279
- store->open_lock(store, RSTRING(rlock_name)->ptr));
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, "There is no directory: %s. Use create = true to "
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
- } else {
362
- store_deref(store);
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 *ram_open_lock(Store *store, char *lockname)
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 ram_close_lock(Lock *lock)
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 = 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;
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
@@ -413,7 +413,7 @@ Query *q_combine(Query **queries, int q_cnt)
413
413
  return ret_q;
414
414
  }
415
415
 
416
- ulong q_hash(Query *self)
416
+ unsigned long q_hash(Query *self)
417
417
  {
418
418
  return (self->hash(self) << 5) | self->type;
419
419
  }
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 *name;
103
- HashTable *cache;
104
- BitVector *(*get_bv_i)(struct Filter *self, IndexReader *ir);
105
- char *(*to_s)(struct Filter *self);
106
- ulong (*hash)(struct Filter *self);
107
- int (*eq)(struct Filter *self, struct Filter *o);
108
- void (*destroy_i)(struct Filter *self);
109
- int ref_cnt;
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 ulong filt_hash(Filter *filt);
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 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
- ulong (*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);
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 ulong q_hash(Query *self);
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
- ulong term_hash(const void *t)
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
- ulong sort_field_hash(const void *p)
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->open_lock(store, lock_name);
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->close_lock(lock);
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 == 0) {
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