isomorfeus-ferret 0.13.10 → 0.14.0
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.
- checksums.yaml +4 -4
- data/README.md +40 -19
- data/ext/isomorfeus_ferret_ext/bzlib.h +83 -82
- data/ext/isomorfeus_ferret_ext/frb_index.c +55 -194
- data/ext/isomorfeus_ferret_ext/frb_lazy_doc.c +705 -0
- data/ext/isomorfeus_ferret_ext/frb_store.c +1 -1
- data/ext/isomorfeus_ferret_ext/frt_config.h +1 -1
- data/ext/isomorfeus_ferret_ext/frt_hash.h +6 -8
- data/ext/isomorfeus_ferret_ext/frt_hashset.c +5 -5
- data/ext/isomorfeus_ferret_ext/frt_index.c +8 -3
- data/ext/isomorfeus_ferret_ext/frt_index.h +3 -1
- data/ext/isomorfeus_ferret_ext/frt_q_parser.c +1 -0
- data/ext/isomorfeus_ferret_ext/frt_store.h +1 -1
- data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +8 -6
- data/lib/isomorfeus/ferret/index/index.rb +11 -8
- data/lib/isomorfeus/ferret/version.rb +1 -1
- metadata +3 -2
@@ -0,0 +1,705 @@
|
|
1
|
+
#include "frt_index.h"
|
2
|
+
#include "isomorfeus_ferret.h"
|
3
|
+
|
4
|
+
extern VALUE rb_hash_update(int argc, VALUE *argv, VALUE self);
|
5
|
+
|
6
|
+
extern VALUE sym_each;
|
7
|
+
extern ID id_eql;
|
8
|
+
|
9
|
+
static VALUE sym_each_key;
|
10
|
+
static VALUE sym_each_value;
|
11
|
+
static ID id_compact;
|
12
|
+
static ID id_equal;
|
13
|
+
static ID id_except;
|
14
|
+
static ID id_fields;
|
15
|
+
static ID id_flatten;
|
16
|
+
static ID id_ge;
|
17
|
+
static ID id_get;
|
18
|
+
static ID id_gt;
|
19
|
+
static ID id_inspect;
|
20
|
+
static ID id_invert;
|
21
|
+
static ID id_le;
|
22
|
+
static ID id_merge_bang;
|
23
|
+
static ID id_reject;
|
24
|
+
static ID id_select;
|
25
|
+
static ID id_size;
|
26
|
+
static ID id_slice;
|
27
|
+
static ID id_to_h;
|
28
|
+
static ID id_to_proc;
|
29
|
+
static ID id_transform_keys;
|
30
|
+
static ID id_transform_values;
|
31
|
+
|
32
|
+
FrtLazyDoc empty_lazy_doc = {0};
|
33
|
+
VALUE cLazyDoc;
|
34
|
+
|
35
|
+
typedef struct rLazyDoc {
|
36
|
+
FrtHash *hash;
|
37
|
+
FrtLazyDoc *doc;
|
38
|
+
} rLazyDoc;
|
39
|
+
|
40
|
+
/****************************************************************************
|
41
|
+
*
|
42
|
+
* LazyDoc Methods
|
43
|
+
*
|
44
|
+
****************************************************************************/
|
45
|
+
|
46
|
+
static void frb_ld_free(void *p) {
|
47
|
+
rLazyDoc *rld = (rLazyDoc *)p;
|
48
|
+
if (rld->doc != &empty_lazy_doc) {
|
49
|
+
frt_lazy_doc_close(rld->doc);
|
50
|
+
}
|
51
|
+
frt_h_destroy(rld->hash);
|
52
|
+
free(rld);
|
53
|
+
}
|
54
|
+
|
55
|
+
static size_t frb_ld_size(const void *p) {
|
56
|
+
return sizeof(rLazyDoc);
|
57
|
+
(void)p;
|
58
|
+
}
|
59
|
+
|
60
|
+
void rld_mark(void *key, void *value, void *arg) {
|
61
|
+
rb_gc_mark((VALUE)value);
|
62
|
+
}
|
63
|
+
|
64
|
+
static void frb_ld_mark(void *p) {
|
65
|
+
frt_h_each(((rLazyDoc *)p)->hash, rld_mark, NULL);
|
66
|
+
}
|
67
|
+
|
68
|
+
const rb_data_type_t frb_ld_t = {
|
69
|
+
.wrap_struct_name = "FrbLazyDoc",
|
70
|
+
.function = {
|
71
|
+
.dmark = frb_ld_mark,
|
72
|
+
.dfree = frb_ld_free,
|
73
|
+
.dsize = frb_ld_size,
|
74
|
+
.dcompact = NULL,
|
75
|
+
.reserved = {0},
|
76
|
+
},
|
77
|
+
.parent = NULL,
|
78
|
+
.data = NULL,
|
79
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
80
|
+
};
|
81
|
+
|
82
|
+
VALUE frb_get_lazy_doc(FrtLazyDoc *lazy_doc) {
|
83
|
+
rLazyDoc *rld = FRT_ALLOC(rLazyDoc);
|
84
|
+
rld->hash = frt_h_new_ptr(NULL);
|
85
|
+
rld->doc = lazy_doc;
|
86
|
+
return TypedData_Wrap_Struct(cLazyDoc, &frb_ld_t, rld);
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE frb_ld_alloc(VALUE rclass) {
|
90
|
+
rLazyDoc *rld = FRT_ALLOC(rLazyDoc);
|
91
|
+
rld->hash = frt_h_new_ptr(NULL);
|
92
|
+
rld->doc = &empty_lazy_doc;
|
93
|
+
return TypedData_Wrap_Struct(rclass, &frb_ld_t, rld);
|
94
|
+
}
|
95
|
+
|
96
|
+
static VALUE frb_ld_df_load(VALUE self, VALUE rkey, FrtLazyDocField *lazy_df) {
|
97
|
+
rLazyDoc *rld = DATA_PTR(self);
|
98
|
+
VALUE rdata;
|
99
|
+
if (lazy_df->size == 1) {
|
100
|
+
char *data = frt_lazy_df_get_data(lazy_df, 0);
|
101
|
+
rdata = rb_str_new(data, lazy_df->data[0].length);
|
102
|
+
rb_enc_associate(rdata, lazy_df->data[0].encoding);
|
103
|
+
} else {
|
104
|
+
int i;
|
105
|
+
VALUE rstr;
|
106
|
+
rdata = rb_ary_new2(lazy_df->size);
|
107
|
+
for (i = 0; i < lazy_df->size; i++) {
|
108
|
+
char *data = frt_lazy_df_get_data(lazy_df, i);
|
109
|
+
rstr = rb_str_new(data, lazy_df->data[i].length);
|
110
|
+
rb_enc_associate(rstr, lazy_df->data[i].encoding);
|
111
|
+
rb_ary_store(rdata, i, rstr);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
frt_h_set(rld->hash, (void *)rkey, (void *)rdata);
|
115
|
+
return rdata;
|
116
|
+
}
|
117
|
+
|
118
|
+
/*
|
119
|
+
* call-seq:
|
120
|
+
* lazy_doc.load -> lazy_doc
|
121
|
+
*
|
122
|
+
* Load all unloaded fields in the document from the index.
|
123
|
+
*/
|
124
|
+
static VALUE frb_ld_load(VALUE self) {
|
125
|
+
rLazyDoc *rld = DATA_PTR(self);
|
126
|
+
FrtLazyDoc *ld = rld->doc;
|
127
|
+
if (ld->loaded) return self;
|
128
|
+
int i;
|
129
|
+
FrtLazyDocField *lazy_df;
|
130
|
+
for (i = 0; i < ld->size; i++) {
|
131
|
+
lazy_df = ld->fields[i];
|
132
|
+
if (!(lazy_df->loaded)) frb_ld_df_load(self, ID2SYM(lazy_df->name), lazy_df);
|
133
|
+
}
|
134
|
+
ld->loaded = true;
|
135
|
+
return self;
|
136
|
+
}
|
137
|
+
|
138
|
+
/*
|
139
|
+
* call-seq:
|
140
|
+
* lazy_doc.fields -> array of available fields
|
141
|
+
*
|
142
|
+
* Returns the list of fields stored for this particular document. If you try
|
143
|
+
* to access any of these fields in the document the field will be loaded.
|
144
|
+
* Try to access any other field an nil will be returned.
|
145
|
+
*/
|
146
|
+
static VALUE frb_ld_fields(VALUE self) {
|
147
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
148
|
+
VALUE rfields = rb_ivar_get(self, id_fields);
|
149
|
+
if (rfields == Qnil) {
|
150
|
+
int i;
|
151
|
+
rfields = rb_ary_new2(ld->size);
|
152
|
+
for (i = 0; i < ld->size; i++) {
|
153
|
+
rb_ary_store(rfields, i, ID2SYM(ld->fields[i]->name));
|
154
|
+
}
|
155
|
+
rb_ivar_set(self, id_fields, rfields);
|
156
|
+
}
|
157
|
+
return rfields;
|
158
|
+
}
|
159
|
+
|
160
|
+
void rld_to_hash(void *key, void *value, void *arg) {
|
161
|
+
rb_hash_aset((VALUE)arg, (VALUE)key, (VALUE)value);
|
162
|
+
}
|
163
|
+
|
164
|
+
static VALUE frb_ld_to_h(VALUE self) {
|
165
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
166
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
167
|
+
VALUE hash = rb_hash_new();
|
168
|
+
frt_h_each(rld->hash, rld_to_hash, (void *)hash);
|
169
|
+
return hash;
|
170
|
+
}
|
171
|
+
|
172
|
+
static VALUE frb_ld_lt(VALUE self, VALUE other) {
|
173
|
+
VALUE other_h;
|
174
|
+
if (TYPE(other) == T_HASH) {
|
175
|
+
other_h = other;
|
176
|
+
} else {
|
177
|
+
rLazyDoc *other_rld;
|
178
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
179
|
+
other_h = frb_ld_to_h(other);
|
180
|
+
}
|
181
|
+
VALUE self_h = frb_ld_to_h(self);
|
182
|
+
return rb_funcall(self_h, id_lt, 1, other_h);
|
183
|
+
}
|
184
|
+
|
185
|
+
static VALUE frb_ld_le(VALUE self, VALUE other) {
|
186
|
+
VALUE other_h;
|
187
|
+
if (TYPE(other) == T_HASH) {
|
188
|
+
other_h = other;
|
189
|
+
} else {
|
190
|
+
rLazyDoc *other_rld;
|
191
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
192
|
+
other_h = frb_ld_to_h(other);
|
193
|
+
}
|
194
|
+
VALUE self_h = frb_ld_to_h(self);
|
195
|
+
return rb_funcall(self_h, id_le, 1, other_h);
|
196
|
+
}
|
197
|
+
|
198
|
+
static VALUE frb_ld_equal(VALUE self, VALUE other) {
|
199
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
200
|
+
int other_size;
|
201
|
+
VALUE other_h;
|
202
|
+
if (TYPE(other) == T_HASH) {
|
203
|
+
other_h = other;
|
204
|
+
other_size = FIX2INT(rb_funcall(other_h, id_size, 0));
|
205
|
+
} else {
|
206
|
+
rLazyDoc *other_rld;
|
207
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
208
|
+
other_h = frb_ld_to_h(other);
|
209
|
+
other_size = other_rld->doc->size;
|
210
|
+
}
|
211
|
+
if (ld->size == other_size) {
|
212
|
+
VALUE self_h = frb_ld_to_h(self);
|
213
|
+
return rb_funcall(self_h, id_equal, 1, other_h);
|
214
|
+
}
|
215
|
+
return Qfalse;
|
216
|
+
}
|
217
|
+
|
218
|
+
static VALUE frb_ld_gt(VALUE self, VALUE other) {
|
219
|
+
VALUE other_h;
|
220
|
+
if (TYPE(other) == T_HASH) {
|
221
|
+
other_h = other;
|
222
|
+
} else {
|
223
|
+
rLazyDoc *other_rld;
|
224
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
225
|
+
other_h = frb_ld_to_h(other);
|
226
|
+
}
|
227
|
+
VALUE self_h = frb_ld_to_h(self);
|
228
|
+
return rb_funcall(self_h, id_gt, 1, other_h);
|
229
|
+
}
|
230
|
+
|
231
|
+
static VALUE frb_ld_ge(VALUE self, VALUE other) {
|
232
|
+
VALUE other_h;
|
233
|
+
if (TYPE(other) == T_HASH) {
|
234
|
+
other_h = other;
|
235
|
+
} else {
|
236
|
+
rLazyDoc *other_rld;
|
237
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
238
|
+
other_h = frb_ld_to_h(other);
|
239
|
+
}
|
240
|
+
VALUE self_h = frb_ld_to_h(self);
|
241
|
+
return rb_funcall(self_h, id_ge, 1, other_h);
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE frb_ld_get(VALUE self, VALUE key) {
|
245
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
246
|
+
VALUE rval = (VALUE)frt_h_get(rld->hash, (void *)key);
|
247
|
+
if (rval) return rval;
|
248
|
+
if (TYPE(key) != T_SYMBOL) rb_raise(rb_eArgError, "key, must be a symbol");
|
249
|
+
FrtLazyDocField *df = frt_h_get(rld->doc->field_dictionary, (void *)SYM2ID(key));
|
250
|
+
if (df) return frb_ld_df_load(self, key, df);
|
251
|
+
return Qnil;
|
252
|
+
}
|
253
|
+
|
254
|
+
void rld_any(void *key, void *value, void *arg) {
|
255
|
+
VALUE *v = arg;
|
256
|
+
*v = rb_yield_values(2, (VALUE)key, (VALUE)value);
|
257
|
+
}
|
258
|
+
|
259
|
+
static VALUE frb_ld_assoc(VALUE self, VALUE key) {
|
260
|
+
rLazyDoc *rld = DATA_PTR(self);
|
261
|
+
VALUE value = (VALUE)frt_h_get(rld->hash, (void *)key);
|
262
|
+
if (!value) {
|
263
|
+
FrtLazyDoc *ld = rld->doc;
|
264
|
+
FrtLazyDocField *df = frt_h_get(ld->field_dictionary, (void *)SYM2ID(key));
|
265
|
+
if (!df) return Qnil;
|
266
|
+
if (df && !df->loaded) value = frb_ld_df_load(self, key, df);
|
267
|
+
}
|
268
|
+
VALUE a[2] = {key, value};
|
269
|
+
return rb_ary_new_from_values(2, a);
|
270
|
+
}
|
271
|
+
|
272
|
+
static VALUE frb_ld_any(int argc, VALUE *argv, VALUE self) {
|
273
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
274
|
+
FrtLazyDoc *ld = rld->doc;
|
275
|
+
if (argc == 0) {
|
276
|
+
if (!rb_block_given_p()) {
|
277
|
+
return (ld->size > 0) ? Qtrue : Qfalse;
|
278
|
+
} else {
|
279
|
+
if (!ld->loaded) frb_ld_load(self);
|
280
|
+
VALUE res = Qnil;
|
281
|
+
frt_h_each(rld->hash, rld_any, &res);
|
282
|
+
if (RTEST(res)) return Qtrue;
|
283
|
+
else return Qfalse;
|
284
|
+
}
|
285
|
+
} else if (argc == 1) {
|
286
|
+
VALUE obj = argv[0];
|
287
|
+
VALUE key = rb_funcall(obj, id_get, 1, 0);
|
288
|
+
VALUE a = frb_ld_assoc(self, key);
|
289
|
+
return rb_funcall(a, id_equal, 1, obj);
|
290
|
+
}
|
291
|
+
rb_raise(rb_eArgError, "at most one arg may be given");
|
292
|
+
return Qfalse;
|
293
|
+
}
|
294
|
+
|
295
|
+
static VALUE frb_ld_compact(VALUE self) {
|
296
|
+
VALUE hash = frb_ld_to_h(self);
|
297
|
+
return rb_funcall(hash, id_compact, 0);
|
298
|
+
}
|
299
|
+
|
300
|
+
static VALUE frb_ld_dig(int argc, VALUE *argv, VALUE self) {
|
301
|
+
if (argc == 0) rb_raise(rb_eArgError, "at least a key must be given");
|
302
|
+
VALUE key = argv[0];
|
303
|
+
if (TYPE(key) != T_SYMBOL) rb_raise(rb_eArgError, "first arg, key, must be a symbol");
|
304
|
+
VALUE value = frb_ld_get(self, key);
|
305
|
+
if (argc == 1) return value;
|
306
|
+
if (TYPE(value) == T_ARRAY && argc == 2) {
|
307
|
+
return rb_ary_entry(value, NUM2LONG(argv[1]));
|
308
|
+
}
|
309
|
+
return Qnil;
|
310
|
+
}
|
311
|
+
|
312
|
+
static VALUE frb_ld_to_enum(VALUE self) {
|
313
|
+
return rb_enumeratorize(self, sym_each, 0, NULL);
|
314
|
+
}
|
315
|
+
|
316
|
+
static VALUE frb_ld_to_key_enum(VALUE self) {
|
317
|
+
return rb_enumeratorize(self, sym_each_key, 0, NULL);
|
318
|
+
}
|
319
|
+
|
320
|
+
static VALUE frb_ld_to_value_enum(VALUE self) {
|
321
|
+
return rb_enumeratorize(self, sym_each_value, 0, NULL);
|
322
|
+
}
|
323
|
+
|
324
|
+
void rld_each(void *key, void *value, void *arg) {
|
325
|
+
rb_yield_values(2, (VALUE)key, (VALUE)value);
|
326
|
+
}
|
327
|
+
|
328
|
+
static VALUE frb_ld_each(VALUE self) {
|
329
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
330
|
+
FrtLazyDoc *ld = rld->doc;
|
331
|
+
if (!ld->loaded) frb_ld_load(self);
|
332
|
+
if (rb_block_given_p()) {
|
333
|
+
frt_h_each(rld->hash, rld_each, NULL);
|
334
|
+
return self;
|
335
|
+
} else {
|
336
|
+
return frb_ld_to_enum(self);
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
void rld_each_key(void *key, void *value, void *arg) {
|
341
|
+
rb_yield((VALUE)key);
|
342
|
+
}
|
343
|
+
|
344
|
+
static VALUE frb_ld_each_key(VALUE self) {
|
345
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
346
|
+
FrtLazyDoc *ld = rld->doc;
|
347
|
+
if (!ld->loaded) frb_ld_load(self);
|
348
|
+
if (rb_block_given_p()) {
|
349
|
+
frt_h_each(rld->hash, rld_each_key, NULL);
|
350
|
+
return self;
|
351
|
+
} else {
|
352
|
+
return frb_ld_to_key_enum(self);
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
void rld_each_value(void *key, void *value, void *arg) {
|
357
|
+
rb_yield((VALUE)value);
|
358
|
+
}
|
359
|
+
|
360
|
+
static VALUE frb_ld_each_value(VALUE self) {
|
361
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
362
|
+
FrtLazyDoc *ld = rld->doc;
|
363
|
+
if (!ld->loaded) frb_ld_load(self);
|
364
|
+
if (rb_block_given_p()) {
|
365
|
+
frt_h_each(rld->hash, rld_each_value, NULL);
|
366
|
+
return self;
|
367
|
+
} else {
|
368
|
+
return frb_ld_to_value_enum(self);
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
static VALUE frb_ld_empty(VALUE self) {
|
373
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
374
|
+
return (ld->size == 0) ? Qtrue : Qfalse;
|
375
|
+
}
|
376
|
+
|
377
|
+
static VALUE frb_ld_eql(VALUE self, VALUE other) {
|
378
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
379
|
+
rLazyDoc *other_rld;
|
380
|
+
int other_size;
|
381
|
+
VALUE other_h;
|
382
|
+
if (TYPE(other) == T_HASH) {
|
383
|
+
other_h = other;
|
384
|
+
other_size = FIX2INT(rb_funcall(other_h, id_size, 0));
|
385
|
+
} else {
|
386
|
+
TypedData_Get_Struct(other, rLazyDoc, &frb_ld_t, other_rld);
|
387
|
+
other_h = frb_ld_to_h(other);
|
388
|
+
other_size = other_rld->doc->size;
|
389
|
+
}
|
390
|
+
if (ld->size == other_size) {
|
391
|
+
VALUE self_h = frb_ld_to_h(self);
|
392
|
+
return rb_funcall(self_h, id_eql, 1, other_h);
|
393
|
+
}
|
394
|
+
return Qfalse;
|
395
|
+
}
|
396
|
+
|
397
|
+
static VALUE frb_ld_except(int argc, VALUE *argv, VALUE self) {
|
398
|
+
VALUE hash = frb_ld_to_h(self);
|
399
|
+
return rb_funcallv(hash, id_except, argc, argv);
|
400
|
+
}
|
401
|
+
|
402
|
+
static VALUE frb_ld_fetch(int argc, VALUE *argv, VALUE self) {
|
403
|
+
VALUE key = argv[0];
|
404
|
+
if (TYPE(key) != T_SYMBOL) rb_raise(rb_eArgError, "first arg must be a symbol");
|
405
|
+
VALUE res = frb_ld_get(self, key);
|
406
|
+
if (argc == 1) {
|
407
|
+
if (res == Qnil && rb_block_given_p()) return rb_yield(key);
|
408
|
+
return res;
|
409
|
+
}
|
410
|
+
if (argc == 2) {
|
411
|
+
if (res == Qnil) return argv[1];
|
412
|
+
return res;
|
413
|
+
}
|
414
|
+
rb_raise(rb_eArgError, "too many args, only two allowed: key, default_value");
|
415
|
+
}
|
416
|
+
|
417
|
+
static VALUE frb_ld_fetch_values(int argc, VALUE *argv, VALUE self) {
|
418
|
+
rLazyDoc *rld = DATA_PTR(self);
|
419
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
420
|
+
VALUE ary = rb_ary_new();
|
421
|
+
int i;
|
422
|
+
VALUE value;
|
423
|
+
for (i=0; i<argc; i++) {
|
424
|
+
value = (VALUE)frt_h_get(rld->hash, (void *)argv[i]);
|
425
|
+
if (value) rb_ary_push(ary, value);
|
426
|
+
else if (rb_block_given_p()) {
|
427
|
+
value = rb_yield(argv[i]);
|
428
|
+
rb_ary_push(ary, value);
|
429
|
+
}
|
430
|
+
}
|
431
|
+
if (FIX2INT(rb_funcall(ary, id_size, 0)) == 0) rb_raise(rb_eException, "nothing found for given keys");
|
432
|
+
return ary;
|
433
|
+
}
|
434
|
+
|
435
|
+
static VALUE frb_ld_filter(VALUE self) {
|
436
|
+
VALUE hash = frb_ld_to_h(self);
|
437
|
+
return rb_funcall_passing_block(hash, id_select, 0, NULL);
|
438
|
+
}
|
439
|
+
|
440
|
+
void rld_flatten(void *key, void *value, void *arg) {
|
441
|
+
rb_ary_push((VALUE)arg, (VALUE)key);
|
442
|
+
rb_ary_push((VALUE)arg, (VALUE)value);
|
443
|
+
}
|
444
|
+
|
445
|
+
static VALUE frb_ld_flatten(int argc, VALUE *argv, VALUE self) {
|
446
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
447
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
448
|
+
VALUE ary = rb_ary_new();
|
449
|
+
frt_h_each(rld->hash, rld_flatten, (void *)ary);
|
450
|
+
if (argc == 1) {
|
451
|
+
int level = FIX2INT(argv[0]) - 1;
|
452
|
+
VALUE rlevel = INT2FIX(level);
|
453
|
+
rb_funcall(ary, id_flatten, 1, rlevel);
|
454
|
+
}
|
455
|
+
return ary;
|
456
|
+
}
|
457
|
+
|
458
|
+
static VALUE frb_ld_has_key(VALUE self, VALUE key) {
|
459
|
+
if (TYPE(key) != T_SYMBOL) rb_raise(rb_eArgError, "arg must be a symbol");
|
460
|
+
VALUE hk = Qfalse;
|
461
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
462
|
+
ID dfkey = SYM2ID(key);
|
463
|
+
FrtLazyDocField *df = frt_h_get(ld->field_dictionary, (void *)dfkey);
|
464
|
+
if (df) hk = Qtrue;
|
465
|
+
return hk;
|
466
|
+
}
|
467
|
+
|
468
|
+
static VALUE frb_ld_has_value(VALUE self, VALUE value) {
|
469
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
470
|
+
FrtLazyDoc *ld = rld->doc;
|
471
|
+
if (!ld->loaded) frb_ld_load(self);
|
472
|
+
int i;
|
473
|
+
VALUE hvalue;
|
474
|
+
for (i=0; i<ld->size; i++) {
|
475
|
+
hvalue = (VALUE)frt_h_get(rld->hash, (void *)ID2SYM(ld->fields[i]->name));
|
476
|
+
hvalue = rb_funcall(hvalue, id_equal, 1, value);
|
477
|
+
if (hvalue == Qtrue) return Qtrue;
|
478
|
+
}
|
479
|
+
return Qfalse;
|
480
|
+
}
|
481
|
+
|
482
|
+
static VALUE frb_ld_inspect(VALUE self) {
|
483
|
+
VALUE hash = frb_ld_to_h(self);
|
484
|
+
return rb_funcall(hash, id_inspect, 0);
|
485
|
+
}
|
486
|
+
|
487
|
+
static VALUE frb_ld_invert(VALUE self) {
|
488
|
+
VALUE hash = frb_ld_to_h(self);
|
489
|
+
return rb_funcall(hash, id_invert, 0);
|
490
|
+
}
|
491
|
+
|
492
|
+
static VALUE frb_ld_key(VALUE self, VALUE value) {
|
493
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
494
|
+
FrtLazyDoc *ld = rld->doc;
|
495
|
+
if (!ld->loaded) frb_ld_load(self);
|
496
|
+
int i;
|
497
|
+
VALUE hvalue;
|
498
|
+
for (i=0; i<ld->size; i++) {
|
499
|
+
hvalue = (VALUE)frt_h_get(rld->hash, (void *)ID2SYM(ld->fields[i]->name));
|
500
|
+
hvalue = rb_funcall(hvalue, id_equal, 1, value);
|
501
|
+
if (hvalue == Qtrue) return ID2SYM(ld->fields[i]->name);
|
502
|
+
}
|
503
|
+
return Qnil;
|
504
|
+
}
|
505
|
+
|
506
|
+
static VALUE frb_ld_length(VALUE self) {
|
507
|
+
FrtLazyDoc *ld = ((rLazyDoc *)DATA_PTR(self))->doc;
|
508
|
+
return INT2FIX(ld->size);
|
509
|
+
}
|
510
|
+
|
511
|
+
static VALUE frb_ld_merge(int argc, VALUE *argv, VALUE self) {
|
512
|
+
rLazyDoc *rld = (rLazyDoc *)DATA_PTR(self);
|
513
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
514
|
+
VALUE hash = frb_ld_to_h(self);
|
515
|
+
return rb_funcall_passing_block(hash, id_merge_bang, argc, argv);
|
516
|
+
}
|
517
|
+
|
518
|
+
static VALUE frb_ld_rassoc(VALUE self, VALUE value) {
|
519
|
+
VALUE key = frb_ld_key(self, value);
|
520
|
+
if (key == Qnil) return Qnil;
|
521
|
+
VALUE a[2] = {key, value};
|
522
|
+
return rb_ary_new_from_values(2, a);
|
523
|
+
}
|
524
|
+
|
525
|
+
static VALUE frb_ld_reject(VALUE self) {
|
526
|
+
VALUE hash = frb_ld_to_h(self);
|
527
|
+
return rb_funcall_passing_block(hash, id_reject, 0, NULL);
|
528
|
+
}
|
529
|
+
|
530
|
+
static VALUE frb_ld_slice(int argc, VALUE *argv, VALUE self) {
|
531
|
+
VALUE hash = frb_ld_to_h(self);
|
532
|
+
return rb_funcallv(hash, id_slice, argc, argv);
|
533
|
+
}
|
534
|
+
|
535
|
+
void rld_to_a(void *key, void *value, void *arg) {
|
536
|
+
VALUE ary = rb_ary_new();
|
537
|
+
rb_ary_push(ary, (VALUE)key);
|
538
|
+
rb_ary_push(ary, (VALUE)value);
|
539
|
+
rb_ary_push((VALUE)arg, ary);
|
540
|
+
}
|
541
|
+
|
542
|
+
static VALUE frb_ld_to_a(VALUE self) {
|
543
|
+
rLazyDoc *rld = DATA_PTR(self);
|
544
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
545
|
+
VALUE ary = rb_ary_new();
|
546
|
+
frt_h_each(rld->hash, rld_to_a, (void *)ary);
|
547
|
+
return ary;
|
548
|
+
}
|
549
|
+
|
550
|
+
static VALUE frb_ld_to_ha(VALUE self) {
|
551
|
+
VALUE hash = frb_ld_to_h(self);
|
552
|
+
if (!rb_block_given_p()) return hash;
|
553
|
+
return rb_funcall_passing_block(hash, id_to_h, 0, NULL);
|
554
|
+
}
|
555
|
+
|
556
|
+
static VALUE frb_ld_to_proc(VALUE self) {
|
557
|
+
VALUE hash = frb_ld_to_h(self);
|
558
|
+
return rb_funcall(hash, id_to_proc, 0);
|
559
|
+
}
|
560
|
+
|
561
|
+
static VALUE frb_ld_transform_keys(int argc, VALUE *argv, VALUE self) {
|
562
|
+
VALUE hash = frb_ld_to_h(self);
|
563
|
+
return rb_funcall_passing_block(hash, id_transform_keys, argc, argv);
|
564
|
+
}
|
565
|
+
|
566
|
+
static VALUE frb_ld_transform_values(VALUE self) {
|
567
|
+
VALUE hash = frb_ld_to_h(self);
|
568
|
+
return rb_funcall_passing_block(hash, id_transform_values, 0, NULL);
|
569
|
+
}
|
570
|
+
|
571
|
+
void rld_values(void *key, void *value, void *arg) {
|
572
|
+
rb_ary_push((VALUE)arg, (VALUE)value);
|
573
|
+
}
|
574
|
+
|
575
|
+
static VALUE frb_ld_values(VALUE self) {
|
576
|
+
rLazyDoc *rld = DATA_PTR(self);
|
577
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
578
|
+
VALUE ary = rb_ary_new();
|
579
|
+
frt_h_each(rld->hash, rld_values, (void *)ary);
|
580
|
+
return ary;
|
581
|
+
}
|
582
|
+
|
583
|
+
static VALUE frb_ld_values_at(int argc, VALUE *argv, VALUE self) {
|
584
|
+
rLazyDoc *rld = DATA_PTR(self);
|
585
|
+
if (!rld->doc->loaded) frb_ld_load(self);
|
586
|
+
VALUE ary = rb_ary_new();
|
587
|
+
int i;
|
588
|
+
VALUE value;
|
589
|
+
for (i=0; i<argc; i++) {
|
590
|
+
value = (VALUE)frt_h_get(rld->hash, (void *)argv[i]);
|
591
|
+
if (value) rb_ary_push(ary, value);
|
592
|
+
else rb_ary_push(ary, Qnil);
|
593
|
+
}
|
594
|
+
return ary;
|
595
|
+
}
|
596
|
+
|
597
|
+
/*
|
598
|
+
* Document-class: Ferret::Index::LazyDoc
|
599
|
+
*
|
600
|
+
* == Summary
|
601
|
+
*
|
602
|
+
* When a document is retrieved from the index a LazyDoc is returned.
|
603
|
+
* It inherits from rubys Hash class, however it is read only.
|
604
|
+
* LazyDoc lazily adds fields to itself when they are accessed or
|
605
|
+
* automatically loads all fields if needed.
|
606
|
+
* To load all fields use the LazyDoc#load method.
|
607
|
+
* Methods from the Hash class, that would modify the LazyDoc itself,
|
608
|
+
* are not supported, .
|
609
|
+
*
|
610
|
+
* == Example
|
611
|
+
*
|
612
|
+
* doc = index_reader[0]
|
613
|
+
*
|
614
|
+
* doc.keys #=> []
|
615
|
+
* doc.values #=> []
|
616
|
+
* doc.fields #=> [:title, :content]
|
617
|
+
*
|
618
|
+
* title = doc[:title] #=> "the title"
|
619
|
+
* doc.keys #=> [:title]
|
620
|
+
* doc.values #=> ["the title"]
|
621
|
+
* doc.fields #=> [:title, :content]
|
622
|
+
*
|
623
|
+
* doc.load
|
624
|
+
* doc.keys #=> [:title, :content]
|
625
|
+
* doc.values #=> ["the title", "the content"]
|
626
|
+
* doc.fields #=> [:title, :content]
|
627
|
+
*/
|
628
|
+
void Init_LazyDoc(void) {
|
629
|
+
sym_each_key = ID2SYM(rb_intern("each_key"));
|
630
|
+
sym_each_value = ID2SYM(rb_intern("each_value"));
|
631
|
+
id_compact = rb_intern("compact");
|
632
|
+
id_equal = rb_intern("==");
|
633
|
+
id_except = rb_intern("except");
|
634
|
+
id_fields = rb_intern("@fields");
|
635
|
+
id_flatten = rb_intern("flatten");
|
636
|
+
id_ge = rb_intern(">=");
|
637
|
+
id_get = rb_intern("[]");
|
638
|
+
id_gt = rb_intern(">");
|
639
|
+
id_inspect = rb_intern("inspect");
|
640
|
+
id_invert = rb_intern("invert");
|
641
|
+
id_le = rb_intern("<=");
|
642
|
+
id_merge_bang = rb_intern("merge!");
|
643
|
+
id_reject = rb_intern("reject");
|
644
|
+
id_select = rb_intern("select");
|
645
|
+
id_size = rb_intern("size");
|
646
|
+
id_slice = rb_intern("slice");
|
647
|
+
id_to_h = rb_intern("to_h");
|
648
|
+
id_to_proc = rb_intern("to_proc");
|
649
|
+
id_transform_keys = rb_intern("transform_keys");
|
650
|
+
id_transform_values = rb_intern("transform_values");
|
651
|
+
|
652
|
+
cLazyDoc = rb_define_class_under(mIndex, "LazyDoc", rb_cObject);
|
653
|
+
rb_include_module(cLazyDoc, rb_mEnumerable);
|
654
|
+
rb_define_alloc_func(cLazyDoc, frb_ld_alloc);
|
655
|
+
rb_define_method(cLazyDoc, "load", frb_ld_load, 0);
|
656
|
+
rb_define_method(cLazyDoc, "fields", frb_ld_fields, 0);
|
657
|
+
rb_define_method(cLazyDoc, "keys", frb_ld_fields, 0);
|
658
|
+
rb_define_method(cLazyDoc, "<", frb_ld_lt, 1);
|
659
|
+
rb_define_method(cLazyDoc, "<=", frb_ld_le, 1);
|
660
|
+
rb_define_method(cLazyDoc, "==", frb_ld_equal, 1);
|
661
|
+
rb_define_method(cLazyDoc, ">", frb_ld_gt, 1);
|
662
|
+
rb_define_method(cLazyDoc, ">=", frb_ld_ge, 1);
|
663
|
+
rb_define_method(cLazyDoc, "[]", frb_ld_get, 1);
|
664
|
+
rb_define_method(cLazyDoc, "any?", frb_ld_any, -1);
|
665
|
+
rb_define_method(cLazyDoc, "assoc", frb_ld_assoc, 1);
|
666
|
+
rb_define_method(cLazyDoc, "compact", frb_ld_compact, 0);
|
667
|
+
rb_define_method(cLazyDoc, "dig", frb_ld_dig, -1);
|
668
|
+
rb_define_method(cLazyDoc, "each", frb_ld_each, 0);
|
669
|
+
rb_define_method(cLazyDoc, "each_key", frb_ld_each_key, 0);
|
670
|
+
rb_define_method(cLazyDoc, "each_pair", frb_ld_each, 0);
|
671
|
+
rb_define_method(cLazyDoc, "each_value", frb_ld_each_value, 0);
|
672
|
+
rb_define_method(cLazyDoc, "empty?", frb_ld_empty, 0);
|
673
|
+
rb_define_method(cLazyDoc, "eql?", frb_ld_eql, 1);
|
674
|
+
rb_define_method(cLazyDoc, "except", frb_ld_except, -1);
|
675
|
+
rb_define_method(cLazyDoc, "fetch", frb_ld_fetch, -1);
|
676
|
+
rb_define_method(cLazyDoc, "fetch_values", frb_ld_fetch_values, -1);
|
677
|
+
rb_define_method(cLazyDoc, "filter", frb_ld_filter, 0);
|
678
|
+
rb_define_method(cLazyDoc, "flatten", frb_ld_flatten, -1);
|
679
|
+
rb_define_method(cLazyDoc, "has_key?", frb_ld_has_key, 1);
|
680
|
+
rb_define_method(cLazyDoc, "has_value?", frb_ld_has_value, 1);
|
681
|
+
rb_define_method(cLazyDoc, "include?", frb_ld_has_key, 1);
|
682
|
+
rb_define_method(cLazyDoc, "inspect", frb_ld_inspect, 0);
|
683
|
+
rb_define_method(cLazyDoc, "invert", frb_ld_invert, 0);
|
684
|
+
rb_define_method(cLazyDoc, "key", frb_ld_key, 1);
|
685
|
+
rb_define_method(cLazyDoc, "key?", frb_ld_has_key, 1);
|
686
|
+
rb_define_method(cLazyDoc, "length", frb_ld_length, 0);
|
687
|
+
rb_define_method(cLazyDoc, "member?", frb_ld_has_key, 1);
|
688
|
+
rb_define_method(cLazyDoc, "merge", frb_ld_merge, -1);
|
689
|
+
rb_define_method(cLazyDoc, "rassoc", frb_ld_rassoc, 1);
|
690
|
+
rb_define_method(cLazyDoc, "reject", frb_ld_reject, 0);
|
691
|
+
rb_define_method(cLazyDoc, "select", frb_ld_filter, 0);
|
692
|
+
rb_define_method(cLazyDoc, "size", frb_ld_length, 0);
|
693
|
+
rb_define_method(cLazyDoc, "slice", frb_ld_slice, -1);
|
694
|
+
rb_define_method(cLazyDoc, "to_a", frb_ld_to_a, 0);
|
695
|
+
rb_define_method(cLazyDoc, "to_enum", frb_ld_to_enum, 0);
|
696
|
+
rb_define_method(cLazyDoc, "to_h", frb_ld_to_ha, 0);
|
697
|
+
rb_define_method(cLazyDoc, "to_hash", frb_ld_to_h, 0);
|
698
|
+
rb_define_method(cLazyDoc, "to_proc", frb_ld_to_proc, 0);
|
699
|
+
rb_define_method(cLazyDoc, "to_s", frb_ld_inspect, 0);
|
700
|
+
rb_define_method(cLazyDoc, "transform_keys", frb_ld_transform_keys, -1);
|
701
|
+
rb_define_method(cLazyDoc, "transform_values", frb_ld_transform_values, 0);
|
702
|
+
rb_define_method(cLazyDoc, "value?", frb_ld_has_value, 1);
|
703
|
+
rb_define_method(cLazyDoc, "values", frb_ld_values, 0);
|
704
|
+
rb_define_method(cLazyDoc, "values_at", frb_ld_values_at, -1);
|
705
|
+
}
|
@@ -402,7 +402,7 @@ static VALUE frb_fsdir_new(int argc, VALUE *argv, VALUE klass) {
|
|
402
402
|
frb_create_dir(rpath);
|
403
403
|
}
|
404
404
|
if (!rb_funcall(rb_cFile, id_is_directory, 1, rpath)) {
|
405
|
-
rb_raise(
|
405
|
+
rb_raise(cFileNotFoundError, "No directory <%s> found. Use :create => true to create one.", rs2s(rpath));
|
406
406
|
}
|
407
407
|
store = frt_open_fs_store(rs2s(rpath));
|
408
408
|
if (create) store->clear_all(store);
|