ferret 0.3.2 → 0.9.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.
- data/CHANGELOG +9 -0
- data/Rakefile +51 -25
- data/ext/analysis.c +553 -0
- data/ext/analysis.h +76 -0
- data/ext/array.c +83 -0
- data/ext/array.h +19 -0
- data/ext/bitvector.c +164 -0
- data/ext/bitvector.h +29 -0
- data/ext/compound_io.c +335 -0
- data/ext/document.c +336 -0
- data/ext/document.h +87 -0
- data/ext/ferret.c +88 -47
- data/ext/ferret.h +43 -109
- data/ext/field.c +395 -0
- data/ext/filter.c +103 -0
- data/ext/fs_store.c +352 -0
- data/ext/global.c +219 -0
- data/ext/global.h +73 -0
- data/ext/hash.c +446 -0
- data/ext/hash.h +80 -0
- data/ext/hashset.c +141 -0
- data/ext/hashset.h +37 -0
- data/ext/helper.c +11 -0
- data/ext/helper.h +5 -0
- data/ext/inc/lang.h +41 -0
- data/ext/ind.c +389 -0
- data/ext/index.h +884 -0
- data/ext/index_io.c +269 -415
- data/ext/index_rw.c +2543 -0
- data/ext/lang.c +31 -0
- data/ext/lang.h +41 -0
- data/ext/priorityqueue.c +228 -0
- data/ext/priorityqueue.h +44 -0
- data/ext/q_boolean.c +1331 -0
- data/ext/q_const_score.c +154 -0
- data/ext/q_fuzzy.c +287 -0
- data/ext/q_match_all.c +142 -0
- data/ext/q_multi_phrase.c +343 -0
- data/ext/q_parser.c +2180 -0
- data/ext/q_phrase.c +657 -0
- data/ext/q_prefix.c +75 -0
- data/ext/q_range.c +247 -0
- data/ext/q_span.c +1566 -0
- data/ext/q_term.c +308 -0
- data/ext/q_wildcard.c +146 -0
- data/ext/r_analysis.c +255 -0
- data/ext/r_doc.c +578 -0
- data/ext/r_index_io.c +996 -0
- data/ext/r_qparser.c +158 -0
- data/ext/r_search.c +2321 -0
- data/ext/r_store.c +263 -0
- data/ext/r_term.c +219 -0
- data/ext/ram_store.c +447 -0
- data/ext/search.c +524 -0
- data/ext/search.h +1065 -0
- data/ext/similarity.c +143 -39
- data/ext/sort.c +661 -0
- data/ext/store.c +35 -0
- data/ext/store.h +152 -0
- data/ext/term.c +704 -143
- data/ext/termdocs.c +599 -0
- data/ext/vector.c +594 -0
- data/lib/ferret.rb +9 -10
- data/lib/ferret/analysis/analyzers.rb +2 -2
- data/lib/ferret/analysis/standard_tokenizer.rb +1 -1
- data/lib/ferret/analysis/token.rb +14 -14
- data/lib/ferret/analysis/token_filters.rb +3 -3
- data/lib/ferret/document/field.rb +16 -17
- data/lib/ferret/index/document_writer.rb +4 -4
- data/lib/ferret/index/index.rb +39 -23
- data/lib/ferret/index/index_writer.rb +2 -2
- data/lib/ferret/index/multiple_term_doc_pos_enum.rb +1 -8
- data/lib/ferret/index/segment_term_vector.rb +4 -4
- data/lib/ferret/index/term.rb +5 -1
- data/lib/ferret/index/term_vector_offset_info.rb +6 -6
- data/lib/ferret/index/term_vectors_io.rb +5 -5
- data/lib/ferret/query_parser/query_parser.tab.rb +81 -77
- data/lib/ferret/search.rb +1 -1
- data/lib/ferret/search/boolean_query.rb +2 -1
- data/lib/ferret/search/field_sorted_hit_queue.rb +3 -3
- data/lib/ferret/search/fuzzy_query.rb +2 -1
- data/lib/ferret/search/index_searcher.rb +3 -0
- data/lib/ferret/search/{match_all_docs_query.rb → match_all_query.rb} +7 -7
- data/lib/ferret/search/multi_phrase_query.rb +6 -5
- data/lib/ferret/search/phrase_query.rb +3 -6
- data/lib/ferret/search/prefix_query.rb +4 -4
- data/lib/ferret/search/sort.rb +3 -1
- data/lib/ferret/search/sort_field.rb +9 -9
- data/lib/ferret/search/spans/near_spans_enum.rb +1 -1
- data/lib/ferret/search/spans/span_near_query.rb +1 -1
- data/lib/ferret/search/spans/span_weight.rb +1 -1
- data/lib/ferret/search/spans/spans_enum.rb +7 -7
- data/lib/ferret/store/fs_store.rb +10 -6
- data/lib/ferret/store/ram_store.rb +3 -3
- data/lib/rferret.rb +36 -0
- data/test/functional/thread_safety_index_test.rb +2 -2
- data/test/test_helper.rb +16 -2
- data/test/unit/analysis/c_token.rb +25 -0
- data/test/unit/analysis/tc_per_field_analyzer_wrapper.rb +1 -1
- data/test/unit/analysis/tc_standard_analyzer.rb +1 -1
- data/test/unit/document/{tc_document.rb → c_document.rb} +0 -0
- data/test/unit/document/c_field.rb +98 -0
- data/test/unit/document/tc_field.rb +0 -66
- data/test/unit/index/{tc_index.rb → c_index.rb} +62 -6
- data/test/unit/index/{tc_index_reader.rb → c_index_reader.rb} +51 -10
- data/test/unit/index/{tc_index_writer.rb → c_index_writer.rb} +0 -4
- data/test/unit/index/{tc_term.rb → c_term.rb} +1 -3
- data/test/unit/index/{tc_term_vector_offset_info.rb → c_term_voi.rb} +5 -5
- data/test/unit/index/tc_segment_term_vector.rb +2 -2
- data/test/unit/index/tc_term_vectors_io.rb +4 -4
- data/test/unit/query_parser/c_query_parser.rb +138 -0
- data/test/unit/search/{tc_filter.rb → c_filter.rb} +24 -24
- data/test/unit/search/{tc_fuzzy_query.rb → c_fuzzy_query.rb} +0 -0
- data/test/unit/search/{tc_index_searcher.rb → c_index_searcher.rb} +9 -26
- data/test/unit/search/{tc_search_and_sort.rb → c_search_and_sort.rb} +15 -15
- data/test/unit/search/{tc_sort.rb → c_sort.rb} +2 -1
- data/test/unit/search/c_sort_field.rb +27 -0
- data/test/unit/search/{tc_spans.rb → c_spans.rb} +0 -0
- data/test/unit/search/tc_sort_field.rb +7 -20
- data/test/unit/store/c_fs_store.rb +76 -0
- data/test/unit/store/c_ram_store.rb +35 -0
- data/test/unit/store/m_store.rb +34 -0
- data/test/unit/store/m_store_lock.rb +68 -0
- data/test/unit/store/tc_fs_store.rb +0 -53
- data/test/unit/store/tc_ram_store.rb +0 -20
- data/test/unit/store/tm_store.rb +0 -30
- data/test/unit/store/tm_store_lock.rb +0 -66
- metadata +84 -31
- data/ext/Makefile +0 -140
- data/ext/ferret_ext.so +0 -0
- data/ext/priority_queue.c +0 -232
- data/ext/ram_directory.c +0 -321
- data/ext/segment_merge_queue.c +0 -37
- data/ext/segment_term_enum.c +0 -326
- data/ext/string_helper.c +0 -42
- data/ext/tags +0 -344
- data/ext/term_buffer.c +0 -230
- data/ext/term_infos_reader.c +0 -54
- data/ext/terminfo.c +0 -160
- data/ext/token.c +0 -93
- data/ext/util.c +0 -12
data/ext/r_store.c
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
#include "ferret.h"
|
2
|
+
#include "store.h"
|
3
|
+
|
4
|
+
VALUE cLock;
|
5
|
+
VALUE cDirectory;
|
6
|
+
VALUE cRAMDirectory;
|
7
|
+
VALUE cFSDirectory;
|
8
|
+
|
9
|
+
/****************************************************************************
|
10
|
+
*
|
11
|
+
* Lock Methods
|
12
|
+
*
|
13
|
+
****************************************************************************/
|
14
|
+
|
15
|
+
void
|
16
|
+
frt_lock_free(void *p)
|
17
|
+
{
|
18
|
+
Lock *lock = (Lock *)p;
|
19
|
+
if (RTEST(object_get(lock->store))) {
|
20
|
+
lock->store->close_lock(lock);
|
21
|
+
} else {
|
22
|
+
free(lock->name);
|
23
|
+
free(lock);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
void
|
28
|
+
frt_lock_mark(void *p)
|
29
|
+
{
|
30
|
+
Lock *lock = (Lock *)p;
|
31
|
+
rb_gc_mark(object_get(lock->store));
|
32
|
+
}
|
33
|
+
|
34
|
+
#define GET_LOCK Lock *lock; Data_Get_Struct(self, Lock, lock);
|
35
|
+
static VALUE
|
36
|
+
frt_lock_obtain(int argc, VALUE *argv, VALUE self)
|
37
|
+
{
|
38
|
+
VALUE rtimeout;
|
39
|
+
int timeout = 1;
|
40
|
+
GET_LOCK;
|
41
|
+
if (rb_scan_args(argc, argv, "01", &rtimeout) > 0) {
|
42
|
+
timeout = FIX2INT(rtimeout);
|
43
|
+
}
|
44
|
+
/* TODO: use the lock timeout */
|
45
|
+
if (!lock->obtain(lock)) {
|
46
|
+
rb_raise(rb_eStandardError, "could not obtain lock: #%s", lock->name);
|
47
|
+
}
|
48
|
+
return Qtrue;
|
49
|
+
}
|
50
|
+
|
51
|
+
static VALUE
|
52
|
+
frt_lock_while_locked(int argc, VALUE *argv, VALUE self)
|
53
|
+
{
|
54
|
+
VALUE rtimeout;
|
55
|
+
int timeout = 1;
|
56
|
+
GET_LOCK;
|
57
|
+
if (rb_scan_args(argc, argv, "01", &rtimeout) > 0) {
|
58
|
+
timeout = FIX2INT(rtimeout);
|
59
|
+
}
|
60
|
+
if (!lock->obtain(lock)) {
|
61
|
+
rb_raise(rb_eStandardError, "could not obtain lock: #%s", lock->name);
|
62
|
+
}
|
63
|
+
rb_yield(Qnil);
|
64
|
+
lock->release(lock);
|
65
|
+
return Qtrue;
|
66
|
+
}
|
67
|
+
|
68
|
+
static VALUE
|
69
|
+
frt_lock_is_locked(VALUE self)
|
70
|
+
{
|
71
|
+
GET_LOCK;
|
72
|
+
return lock->is_locked(lock) ? Qtrue : Qfalse;
|
73
|
+
}
|
74
|
+
|
75
|
+
static VALUE
|
76
|
+
frt_lock_release(VALUE self)
|
77
|
+
{
|
78
|
+
GET_LOCK;
|
79
|
+
lock->release(lock);
|
80
|
+
return Qnil;
|
81
|
+
}
|
82
|
+
|
83
|
+
/****************************************************************************
|
84
|
+
*
|
85
|
+
* Directory Methods
|
86
|
+
*
|
87
|
+
****************************************************************************/
|
88
|
+
|
89
|
+
void
|
90
|
+
frt_dir_free(void *p)
|
91
|
+
{
|
92
|
+
Store *store = (Store *)p;
|
93
|
+
object_del(p);
|
94
|
+
store->close(store);
|
95
|
+
}
|
96
|
+
|
97
|
+
#define GET_STORE Store *store; Data_Get_Struct(self, Store, store)
|
98
|
+
static VALUE
|
99
|
+
frt_dir_close(VALUE self)
|
100
|
+
{
|
101
|
+
/*
|
102
|
+
GET_STORE;
|
103
|
+
Frt_Unwrap_Struct(self);
|
104
|
+
object_del(store);
|
105
|
+
store->close(store);
|
106
|
+
*/
|
107
|
+
return Qnil;
|
108
|
+
}
|
109
|
+
|
110
|
+
static VALUE
|
111
|
+
frt_dir_exists(VALUE self, VALUE rfname)
|
112
|
+
{
|
113
|
+
GET_STORE;
|
114
|
+
rfname = rb_obj_as_string(rfname);
|
115
|
+
return store->exists(store, RSTRING(rfname)->ptr) ? Qtrue : Qfalse;
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE
|
119
|
+
frt_dir_touch(VALUE self, VALUE rfname)
|
120
|
+
{
|
121
|
+
GET_STORE;
|
122
|
+
rfname = rb_obj_as_string(rfname);
|
123
|
+
store->touch(store, RSTRING(rfname)->ptr);
|
124
|
+
return Qnil;
|
125
|
+
}
|
126
|
+
|
127
|
+
typedef struct RTerm {
|
128
|
+
VALUE field;
|
129
|
+
VALUE text;
|
130
|
+
} RTerm;
|
131
|
+
|
132
|
+
static VALUE
|
133
|
+
frt_dir_delete(VALUE self, VALUE rfname)
|
134
|
+
{
|
135
|
+
GET_STORE;
|
136
|
+
rfname = rb_obj_as_string(rfname);
|
137
|
+
return INT2FIX(store->remove(store, RSTRING(rfname)->ptr));
|
138
|
+
}
|
139
|
+
|
140
|
+
static VALUE
|
141
|
+
frt_dir_file_count(VALUE self)
|
142
|
+
{
|
143
|
+
GET_STORE;
|
144
|
+
return INT2FIX(store->count(store));
|
145
|
+
}
|
146
|
+
|
147
|
+
static VALUE
|
148
|
+
frt_dir_refresh(VALUE self)
|
149
|
+
{
|
150
|
+
GET_STORE;
|
151
|
+
store->clear_all(store);
|
152
|
+
return Qnil;
|
153
|
+
}
|
154
|
+
|
155
|
+
static VALUE
|
156
|
+
frt_dir_rename(VALUE self, VALUE rfrom, VALUE rto)
|
157
|
+
{
|
158
|
+
GET_STORE;
|
159
|
+
rfrom = rb_obj_as_string(rfrom);
|
160
|
+
rto = rb_obj_as_string(rto);
|
161
|
+
store->rename(store, RSTRING(rfrom)->ptr, RSTRING(rto)->ptr);
|
162
|
+
return Qnil;
|
163
|
+
}
|
164
|
+
|
165
|
+
static VALUE
|
166
|
+
frt_dir_make_lock(VALUE self, VALUE rlock_name)
|
167
|
+
{
|
168
|
+
GET_STORE;
|
169
|
+
rlock_name = rb_obj_as_string(rlock_name);
|
170
|
+
return Data_Wrap_Struct(cLock, &frt_lock_mark, &frt_lock_free,
|
171
|
+
store->open_lock(store, RSTRING(rlock_name)->ptr));
|
172
|
+
}
|
173
|
+
|
174
|
+
/****************************************************************************
|
175
|
+
*
|
176
|
+
* RAMDirectory Methods
|
177
|
+
*
|
178
|
+
****************************************************************************/
|
179
|
+
|
180
|
+
static VALUE
|
181
|
+
frt_ramdir_init(int argc, VALUE *argv, VALUE self)
|
182
|
+
{
|
183
|
+
VALUE rdir, rclose_dir;
|
184
|
+
Store *store;
|
185
|
+
bool close_dir = false;
|
186
|
+
switch (rb_scan_args(argc, argv, "02", &rdir, &rclose_dir)) {
|
187
|
+
case 2: close_dir = RTEST(rclose_dir);
|
188
|
+
case 1: {
|
189
|
+
Store *ostore;
|
190
|
+
Data_Get_Struct(rdir, Store, ostore);
|
191
|
+
if (close_dir) Frt_Unwrap_Struct(rdir);
|
192
|
+
store = open_ram_store_and_copy(ostore, close_dir);
|
193
|
+
break;
|
194
|
+
}
|
195
|
+
default: store = open_ram_store();
|
196
|
+
}
|
197
|
+
Frt_Wrap_Struct(self, NULL, frt_dir_free, store);
|
198
|
+
object_add(store, self);
|
199
|
+
return self;
|
200
|
+
}
|
201
|
+
|
202
|
+
/****************************************************************************
|
203
|
+
*
|
204
|
+
* FSDirectory Methods
|
205
|
+
*
|
206
|
+
****************************************************************************/
|
207
|
+
|
208
|
+
static VALUE
|
209
|
+
frt_fsdir_new(VALUE klass, VALUE rpath, VALUE rcreate)
|
210
|
+
{
|
211
|
+
VALUE self;
|
212
|
+
Store *store;
|
213
|
+
bool create = RTEST(rcreate);
|
214
|
+
rpath = rb_obj_as_string(rpath);
|
215
|
+
store = open_fs_store(RSTRING(rpath)->ptr);
|
216
|
+
if (create) store->clear_all(store);
|
217
|
+
if ((self = object_get(store)) == Qnil) {
|
218
|
+
self = Data_Wrap_Struct(klass, NULL, &frt_dir_free, store);
|
219
|
+
object_add(store, self);
|
220
|
+
}
|
221
|
+
return self;
|
222
|
+
}
|
223
|
+
|
224
|
+
/****************************************************************************
|
225
|
+
*
|
226
|
+
* Init Function
|
227
|
+
*
|
228
|
+
****************************************************************************/
|
229
|
+
|
230
|
+
#define DIR_METHODS(dir)\
|
231
|
+
rb_define_method(dir, "close", frt_dir_close, 0);\
|
232
|
+
rb_define_method(dir, "exists?", frt_dir_exists, 1);\
|
233
|
+
rb_define_method(dir, "touch", frt_dir_touch, 1);\
|
234
|
+
rb_define_method(dir, "delete", frt_dir_delete, 1);\
|
235
|
+
rb_define_method(dir, "file_count", frt_dir_file_count, 0);\
|
236
|
+
rb_define_method(dir, "refresh", frt_dir_refresh, 0);\
|
237
|
+
rb_define_method(dir, "rename", frt_dir_rename, 2);\
|
238
|
+
rb_define_method(dir, "make_lock", frt_dir_make_lock, 1);
|
239
|
+
|
240
|
+
void
|
241
|
+
Init_dir(void)
|
242
|
+
{
|
243
|
+
cLock = rb_define_class_under(mStore, "Lock", rb_cObject);
|
244
|
+
rb_define_method(cLock, "obtain", frt_lock_obtain, -1);
|
245
|
+
rb_define_method(cLock, "while_locked", frt_lock_while_locked, -1);
|
246
|
+
rb_define_method(cLock, "release", frt_lock_release, 0);
|
247
|
+
rb_define_method(cLock, "locked?", frt_lock_is_locked, 0);
|
248
|
+
|
249
|
+
cDirectory = rb_define_class_under(mStore, "Directory", rb_cObject);
|
250
|
+
rb_define_const(cDirectory, "LOCK_PREFIX", rb_str_new2(LOCK_PREFIX));
|
251
|
+
|
252
|
+
/* RAMDirectory */
|
253
|
+
cRAMDirectory = rb_define_class_under(mStore, "RAMDirectory", cDirectory);
|
254
|
+
rb_define_alloc_func(cRAMDirectory, frt_data_alloc);
|
255
|
+
rb_define_method(cRAMDirectory, "initialize", frt_ramdir_init, -1);
|
256
|
+
DIR_METHODS(cRAMDirectory);
|
257
|
+
|
258
|
+
/* FSDirectory */
|
259
|
+
cFSDirectory = rb_define_class_under(mStore, "FSDirectory", cDirectory);
|
260
|
+
rb_define_alloc_func(cFSDirectory, frt_data_alloc);
|
261
|
+
rb_define_singleton_method(cFSDirectory, "new", frt_fsdir_new, 2);
|
262
|
+
DIR_METHODS(cFSDirectory);
|
263
|
+
}
|
data/ext/r_term.c
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
#include "ferret.h"
|
2
|
+
#include "index.h"
|
3
|
+
|
4
|
+
VALUE cTerm;
|
5
|
+
/****************************************************************************
|
6
|
+
*
|
7
|
+
* Term Methods
|
8
|
+
*
|
9
|
+
****************************************************************************/
|
10
|
+
|
11
|
+
typedef struct RTerm {
|
12
|
+
VALUE field;
|
13
|
+
VALUE text;
|
14
|
+
} RTerm;
|
15
|
+
|
16
|
+
void
|
17
|
+
frt_term_mark(void *p)
|
18
|
+
{
|
19
|
+
RTerm *term = (RTerm *)p;
|
20
|
+
rb_gc_mark(term->field);
|
21
|
+
rb_gc_mark(term->text);
|
22
|
+
}
|
23
|
+
|
24
|
+
static VALUE
|
25
|
+
frt_term_alloc(VALUE klass)
|
26
|
+
{
|
27
|
+
RTerm *term = ALLOC(RTerm);
|
28
|
+
term->field = Qnil;
|
29
|
+
term->text = Qnil;
|
30
|
+
return Data_Wrap_Struct(klass, &frt_term_mark, &free, term);
|
31
|
+
}
|
32
|
+
|
33
|
+
#define GET_TERM RTerm *term; Data_Get_Struct(self, RTerm, term)
|
34
|
+
static VALUE
|
35
|
+
frt_term_init(VALUE self, VALUE rfield, VALUE rtext)
|
36
|
+
{
|
37
|
+
GET_TERM;
|
38
|
+
term->field = rb_obj_as_string(rfield);
|
39
|
+
term->text = rb_obj_as_string(rtext);
|
40
|
+
return self;
|
41
|
+
}
|
42
|
+
|
43
|
+
VALUE
|
44
|
+
frt_get_rterm(char *field, char *text)
|
45
|
+
{
|
46
|
+
RTerm *rterm = ALLOC(RTerm);
|
47
|
+
rterm->field = rb_str_new2(field);
|
48
|
+
rterm->text = rb_str_new2(text);
|
49
|
+
return Data_Wrap_Struct(cTerm, &frt_term_mark, &free, rterm);
|
50
|
+
}
|
51
|
+
|
52
|
+
Term *
|
53
|
+
frt_set_term(VALUE self, Term *t)
|
54
|
+
{
|
55
|
+
GET_TERM;
|
56
|
+
t->field = RSTRING(term->field)->ptr;
|
57
|
+
t->text = RSTRING(term->text)->ptr;
|
58
|
+
return t;
|
59
|
+
}
|
60
|
+
|
61
|
+
Term *
|
62
|
+
frt_get_term(VALUE self)
|
63
|
+
{
|
64
|
+
Term *t = NULL;
|
65
|
+
if (self != Qnil) {
|
66
|
+
GET_TERM;
|
67
|
+
t = ALLOC(Term);
|
68
|
+
/* store text and field in text so that field will be freed with text */
|
69
|
+
t->text = ALLOC_N(char, RSTRING(term->text)->len +
|
70
|
+
RSTRING(term->field)->len + 2);
|
71
|
+
sprintf(t->text, "%s %s", RSTRING(term->text)->ptr,
|
72
|
+
RSTRING(term->field)->ptr);
|
73
|
+
t->text[RSTRING(term->text)->len] = '\0';
|
74
|
+
t->field = t->text + RSTRING(term->text)->len + 1;
|
75
|
+
}
|
76
|
+
return t;
|
77
|
+
}
|
78
|
+
|
79
|
+
static VALUE
|
80
|
+
frt_term_get_text(VALUE self)
|
81
|
+
{
|
82
|
+
GET_TERM;
|
83
|
+
return term->text;
|
84
|
+
}
|
85
|
+
|
86
|
+
static VALUE
|
87
|
+
frt_term_set_text(VALUE self, VALUE rtext)
|
88
|
+
{
|
89
|
+
GET_TERM;
|
90
|
+
term->text = rb_obj_as_string(rtext);
|
91
|
+
return Qnil;
|
92
|
+
}
|
93
|
+
|
94
|
+
static VALUE
|
95
|
+
frt_term_get_field(VALUE self)
|
96
|
+
{
|
97
|
+
GET_TERM;
|
98
|
+
return term->field;
|
99
|
+
}
|
100
|
+
|
101
|
+
static VALUE
|
102
|
+
frt_term_set_field(VALUE self, VALUE rfield)
|
103
|
+
{
|
104
|
+
GET_TERM;
|
105
|
+
term->field = rb_obj_as_string(rfield);
|
106
|
+
return Qnil;
|
107
|
+
}
|
108
|
+
|
109
|
+
VALUE
|
110
|
+
frt_term_to_s(VALUE self)
|
111
|
+
{
|
112
|
+
int tlen, flen;
|
113
|
+
char *res;
|
114
|
+
GET_TERM;
|
115
|
+
tlen = RSTRING(term->text)->len;
|
116
|
+
flen = RSTRING(term->field)->len;
|
117
|
+
res = alloca(flen + tlen + 1);
|
118
|
+
|
119
|
+
MEMCPY(res, StringValuePtr(term->field), char, flen);
|
120
|
+
res[flen] = ':';
|
121
|
+
MEMCPY(res + flen + 1, StringValuePtr(term->text), char, tlen);
|
122
|
+
return rb_str_new(res, tlen + flen + 1 );
|
123
|
+
}
|
124
|
+
|
125
|
+
inline int
|
126
|
+
frt_term_cmp(RTerm *t1, RTerm *t2)
|
127
|
+
{
|
128
|
+
int comp = rb_str_cmp(t1->field, t2->field);
|
129
|
+
if (comp == 0) {
|
130
|
+
comp = rb_str_cmp(t1->text, t2->text);
|
131
|
+
}
|
132
|
+
return comp;
|
133
|
+
}
|
134
|
+
|
135
|
+
int
|
136
|
+
frt_term_compare_to_int(VALUE self, VALUE rother)
|
137
|
+
{
|
138
|
+
RTerm *other;
|
139
|
+
GET_TERM;
|
140
|
+
Data_Get_Struct(rother, RTerm, other);
|
141
|
+
return frt_term_cmp(term, other);
|
142
|
+
}
|
143
|
+
|
144
|
+
VALUE
|
145
|
+
frt_term_lt(VALUE self, VALUE rother)
|
146
|
+
{
|
147
|
+
return frt_term_compare_to_int(self, rother) < 0 ? Qtrue : Qfalse;
|
148
|
+
}
|
149
|
+
|
150
|
+
VALUE
|
151
|
+
frt_term_gt(VALUE self, VALUE rother)
|
152
|
+
{
|
153
|
+
return frt_term_compare_to_int(self, rother) > 0 ? Qtrue : Qfalse;
|
154
|
+
}
|
155
|
+
|
156
|
+
VALUE
|
157
|
+
frt_term_le(VALUE self, VALUE rother)
|
158
|
+
{
|
159
|
+
return frt_term_compare_to_int(self, rother) <= 0 ? Qtrue : Qfalse;
|
160
|
+
}
|
161
|
+
|
162
|
+
VALUE
|
163
|
+
frt_term_ge(VALUE self, VALUE rother)
|
164
|
+
{
|
165
|
+
return frt_term_compare_to_int(self, rother) >= 0 ? Qtrue : Qfalse;
|
166
|
+
}
|
167
|
+
|
168
|
+
VALUE
|
169
|
+
frt_term_eq(VALUE self, VALUE rother)
|
170
|
+
{
|
171
|
+
if (rother == Qnil)
|
172
|
+
return Qfalse;
|
173
|
+
return frt_term_compare_to_int(self, rother) == 0 ? Qtrue : Qfalse;
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
static VALUE
|
178
|
+
frt_term_compare_to(VALUE self, VALUE other)
|
179
|
+
{
|
180
|
+
return INT2FIX(frt_term_compare_to_int(self, other));
|
181
|
+
}
|
182
|
+
|
183
|
+
static VALUE
|
184
|
+
frt_term_hash(VALUE self)
|
185
|
+
{
|
186
|
+
GET_TERM;
|
187
|
+
return INT2FIX(rb_str_hash(term->field) + rb_str_hash(term->text));
|
188
|
+
}
|
189
|
+
|
190
|
+
/****************************************************************************
|
191
|
+
*
|
192
|
+
* Init Function
|
193
|
+
*
|
194
|
+
****************************************************************************/
|
195
|
+
|
196
|
+
void
|
197
|
+
Init_term(void)
|
198
|
+
{
|
199
|
+
/* Term */
|
200
|
+
cTerm = rb_define_class_under(mIndex, "Term", rb_cObject);
|
201
|
+
rb_define_alloc_func(cTerm, frt_term_alloc);
|
202
|
+
rb_include_module(cTerm, rb_mComparable);
|
203
|
+
|
204
|
+
rb_define_method(cTerm, "initialize", frt_term_init, 2);
|
205
|
+
rb_define_method(cTerm, "set!", frt_term_init, 2);
|
206
|
+
rb_define_method(cTerm, "to_s", frt_term_to_s, 0);
|
207
|
+
rb_define_method(cTerm, "<=>", frt_term_compare_to, 1);
|
208
|
+
rb_define_method(cTerm, "<", frt_term_lt, 1);
|
209
|
+
rb_define_method(cTerm, ">", frt_term_gt, 1);
|
210
|
+
rb_define_method(cTerm, "<=", frt_term_le, 1);
|
211
|
+
rb_define_method(cTerm, ">=", frt_term_ge, 1);
|
212
|
+
rb_define_method(cTerm, "eql?", frt_term_eq, 1);
|
213
|
+
rb_define_method(cTerm, "==", frt_term_eq, 1);
|
214
|
+
rb_define_method(cTerm, "text", frt_term_get_text, 0);
|
215
|
+
rb_define_method(cTerm, "text=", frt_term_set_text, 1);
|
216
|
+
rb_define_method(cTerm, "field", frt_term_get_field, 0);
|
217
|
+
rb_define_method(cTerm, "field=", frt_term_set_field, 1);
|
218
|
+
rb_define_method(cTerm, "hash", frt_term_hash, 0);
|
219
|
+
}
|