rroonga 6.1.3 → 7.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,269 @@
1
+ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License version 2.1 as published by the Free Software Foundation.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with this library; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ #define SELF(object) ((RbGrnInvertedIndexCursor *)DATA_PTR(object))
22
+
23
+ typedef struct _RbGrnInvertedIndexCursor RbGrnInvertedIndexCursor;
24
+ struct _RbGrnInvertedIndexCursor
25
+ {
26
+ VALUE self;
27
+ grn_ctx *context;
28
+ grn_ii_cursor *cursor;
29
+ grn_id term_id;
30
+ int flags;
31
+ };
32
+
33
+ static VALUE rb_cGrnInvertedIndexCursor;
34
+
35
+ static void
36
+ rb_grn_inverted_index_cursor_free(void *data)
37
+ {
38
+ RbGrnInvertedIndexCursor *rb_grn_cursor = data;
39
+
40
+ if (rb_grn_cursor->context && rb_grn_cursor->cursor) {
41
+ grn_ii_cursor_close(rb_grn_cursor->context,
42
+ rb_grn_cursor->cursor);
43
+ }
44
+ xfree(rb_grn_cursor);
45
+ }
46
+
47
+ static const rb_data_type_t rb_grn_inverted_index_cursor_type = {
48
+ "Groonga::InvertedIndexCursor",
49
+ {
50
+ NULL,
51
+ rb_grn_inverted_index_cursor_free,
52
+ NULL,
53
+ },
54
+ 0,
55
+ 0,
56
+ RUBY_TYPED_FREE_IMMEDIATELY,
57
+ };
58
+
59
+ VALUE
60
+ rb_grn_inverted_index_cursor_to_ruby_object (grn_ctx *context,
61
+ grn_ii_cursor *cursor,
62
+ grn_id term_id,
63
+ int flags,
64
+ VALUE rb_table,
65
+ VALUE rb_lexicon)
66
+ {
67
+ VALUE rb_cursor;
68
+ RbGrnInvertedIndexCursor *rb_grn_cursor;
69
+
70
+ rb_cursor = TypedData_Make_Struct(rb_cGrnInvertedIndexCursor,
71
+ RbGrnInvertedIndexCursor,
72
+ &rb_grn_inverted_index_cursor_type,
73
+ rb_grn_cursor);
74
+
75
+ rb_grn_cursor->self = rb_cursor;
76
+ rb_grn_cursor->context = context;
77
+ rb_grn_cursor->cursor = cursor;
78
+ rb_grn_cursor->term_id = term_id;
79
+ rb_grn_cursor->flags = flags;
80
+ rb_iv_set(rb_cursor, "@table", rb_table);
81
+ rb_iv_set(rb_cursor, "@lexicon", rb_lexicon);
82
+
83
+ if (rb_grn_cursor->cursor &&
84
+ (rb_grn_cursor->flags & GRN_OBJ_WITH_POSITION)) {
85
+ grn_ii_cursor_next(context, cursor);
86
+ }
87
+
88
+ return rb_cursor;
89
+ }
90
+
91
+ static VALUE
92
+ next_value (VALUE rb_posting,
93
+ RbGrnInvertedIndexCursor *rb_grn_cursor,
94
+ VALUE rb_table,
95
+ VALUE rb_lexicon)
96
+ {
97
+ grn_ctx *context = rb_grn_cursor->context;
98
+ grn_ii_cursor *cursor = rb_grn_cursor->cursor;
99
+ grn_posting *posting = NULL;
100
+
101
+ if (rb_grn_cursor->flags & GRN_OBJ_WITH_POSITION) {
102
+ posting = grn_ii_cursor_next_pos(context, cursor);
103
+ while (!posting && grn_ii_cursor_next(context, cursor)) {
104
+ posting = grn_ii_cursor_next_pos(context, cursor);
105
+ break;
106
+ }
107
+ } else {
108
+ posting = grn_ii_cursor_next(context, cursor);
109
+ }
110
+ if (!posting) {
111
+ return Qnil;
112
+ }
113
+
114
+ if (NIL_P(rb_posting)) {
115
+ return rb_grn_posting_new(posting,
116
+ rb_grn_cursor->term_id,
117
+ rb_table,
118
+ rb_lexicon);
119
+ } else {
120
+ rb_grn_posting_update(rb_posting,
121
+ posting,
122
+ rb_grn_cursor->term_id);
123
+ return rb_posting;
124
+ }
125
+ }
126
+
127
+ static VALUE
128
+ rb_grn_inverted_index_cursor_next (VALUE self)
129
+ {
130
+ RbGrnInvertedIndexCursor *rb_grn_cursor;
131
+ VALUE rb_table;
132
+ VALUE rb_lexicon;
133
+ VALUE rb_posting;
134
+
135
+ TypedData_Get_Struct(self,
136
+ RbGrnInvertedIndexCursor,
137
+ &rb_grn_inverted_index_cursor_type,
138
+ rb_grn_cursor);
139
+ if (!rb_grn_cursor->context) {
140
+ rb_raise(rb_eGrnClosed,
141
+ "can't access already closed Groonga object: %" PRIsVALUE,
142
+ self);
143
+ }
144
+
145
+ if (!rb_grn_cursor->cursor) {
146
+ return Qnil;
147
+ }
148
+
149
+ rb_table = rb_iv_get(self, "@table");
150
+ rb_lexicon = rb_iv_get(self, "@lexicon");
151
+ rb_posting = next_value(Qnil, rb_grn_cursor, rb_table, rb_lexicon);
152
+
153
+ return rb_posting;
154
+
155
+ }
156
+
157
+ static VALUE
158
+ rb_grn_inverted_index_cursor_each (int argc, VALUE *argv, VALUE self)
159
+ {
160
+ RbGrnInvertedIndexCursor *rb_grn_cursor;
161
+ grn_bool reuse_posting_object;
162
+ VALUE rb_options;
163
+ VALUE rb_reuse_posting_object;
164
+ VALUE rb_table;
165
+ VALUE rb_lexicon;
166
+ VALUE rb_posting = Qnil;
167
+
168
+ RETURN_ENUMERATOR(self, argc, argv);
169
+
170
+ rb_scan_args(argc, argv, "01", &rb_options);
171
+
172
+ rb_grn_scan_options(rb_options,
173
+ "reuse_posting_object", &rb_reuse_posting_object,
174
+ NULL);
175
+
176
+ TypedData_Get_Struct(self,
177
+ RbGrnInvertedIndexCursor,
178
+ &rb_grn_inverted_index_cursor_type,
179
+ rb_grn_cursor);
180
+ if (!rb_grn_cursor->context) {
181
+ rb_raise(rb_eGrnClosed,
182
+ "can't access already closed Groonga object: %" PRIsVALUE,
183
+ self);
184
+ }
185
+
186
+ if (!rb_grn_cursor->cursor) {
187
+ return Qnil;
188
+ }
189
+
190
+ rb_table = rb_iv_get(self, "@table");
191
+ rb_lexicon = rb_iv_get(self, "@lexicon");
192
+ reuse_posting_object = RVAL2CBOOL(rb_reuse_posting_object);
193
+
194
+ if (reuse_posting_object) {
195
+ rb_posting = rb_grn_posting_new(NULL, GRN_ID_NIL, rb_table, rb_lexicon);
196
+ }
197
+ while (GRN_TRUE) {
198
+ if (!reuse_posting_object) {
199
+ rb_posting = Qnil;
200
+ }
201
+ rb_posting = next_value(rb_posting, rb_grn_cursor, rb_table, rb_lexicon);
202
+ if (NIL_P(rb_posting)) {
203
+ break;
204
+ }
205
+ rb_yield(rb_posting);
206
+ }
207
+
208
+ return Qnil;
209
+ }
210
+
211
+ static VALUE
212
+ rb_grn_inverted_index_cursor_close (VALUE self)
213
+ {
214
+ RbGrnInvertedIndexCursor *rb_grn_cursor;
215
+
216
+ TypedData_Get_Struct(self,
217
+ RbGrnInvertedIndexCursor,
218
+ &rb_grn_inverted_index_cursor_type,
219
+ rb_grn_cursor);
220
+ if (!rb_grn_cursor->context) {
221
+ rb_raise(rb_eGrnClosed,
222
+ "can't access already closed Groonga object: %" PRIsVALUE,
223
+ self);
224
+ }
225
+
226
+ if (rb_grn_cursor->cursor) {
227
+ grn_ii_cursor_close(rb_grn_cursor->context,
228
+ rb_grn_cursor->cursor);
229
+ }
230
+ rb_grn_cursor->context = NULL;
231
+ rb_grn_cursor->cursor = NULL;
232
+
233
+ return Qnil;
234
+
235
+ }
236
+
237
+ static VALUE
238
+ rb_grn_inverted_index_cursor_is_closed (VALUE self)
239
+ {
240
+ RbGrnInvertedIndexCursor *rb_grn_cursor;
241
+
242
+ TypedData_Get_Struct(self,
243
+ RbGrnInvertedIndexCursor,
244
+ &rb_grn_inverted_index_cursor_type,
245
+ rb_grn_cursor);
246
+ if (rb_grn_cursor->context) {
247
+ return Qfalse;
248
+ } else {
249
+ return Qtrue;
250
+ }
251
+
252
+ }
253
+
254
+ void
255
+ rb_grn_init_inverted_index_cursor (VALUE mGrn)
256
+ {
257
+ rb_cGrnInvertedIndexCursor =
258
+ rb_define_class_under(mGrn, "InvertedIndexCursor", rb_cData);
259
+ rb_include_module(rb_cGrnInvertedIndexCursor, rb_mEnumerable);
260
+
261
+ rb_define_method(rb_cGrnInvertedIndexCursor, "next",
262
+ rb_grn_inverted_index_cursor_next, 0);
263
+ rb_define_method(rb_cGrnInvertedIndexCursor, "each",
264
+ rb_grn_inverted_index_cursor_each, -1);
265
+ rb_define_method(rb_cGrnInvertedIndexCursor, "close",
266
+ rb_grn_inverted_index_cursor_close, 0);
267
+ rb_define_method(rb_cGrnInvertedIndexCursor, "closed?",
268
+ rb_grn_inverted_index_cursor_is_closed, 0);
269
+ }
@@ -1973,7 +1973,7 @@ rb_grn_object_dirty_p (VALUE self)
1973
1973
  void
1974
1974
  rb_grn_init_object (VALUE mGrn)
1975
1975
  {
1976
- rb_cGrnObject = rb_define_class_under(mGrn, "Object", rb_cObject);
1976
+ rb_cGrnObject = rb_define_class_under(mGrn, "Object", rb_cData);
1977
1977
  rb_define_alloc_func(rb_cGrnObject, rb_grn_object_alloc);
1978
1978
 
1979
1979
  rb_define_attr(rb_cGrnObject, "context", GRN_TRUE, GRN_FALSE);
@@ -245,7 +245,7 @@ rb_grn_plugin_s_names (int argc, VALUE *argv, VALUE klass)
245
245
  void
246
246
  rb_grn_init_plugin (VALUE mGrn)
247
247
  {
248
- cGrnPlugin = rb_define_class_under(mGrn, "Plugin", rb_cObject);
248
+ cGrnPlugin = rb_define_class_under(mGrn, "Plugin", rb_cData);
249
249
  rb_define_alloc_func(cGrnPlugin, rb_grn_plugin_alloc);
250
250
 
251
251
  rb_define_singleton_method(cGrnPlugin, "register",
@@ -277,7 +277,7 @@ rb_grn_table_cursor_each (VALUE self)
277
277
  void
278
278
  rb_grn_init_table_cursor (VALUE mGrn)
279
279
  {
280
- rb_cGrnTableCursor = rb_define_class_under(mGrn, "TableCursor", rb_cObject);
280
+ rb_cGrnTableCursor = rb_define_class_under(mGrn, "TableCursor", rb_cData);
281
281
  rb_define_alloc_func(rb_cGrnTableCursor, rb_grn_object_alloc);
282
282
 
283
283
  rb_include_module(rb_cGrnTableCursor, rb_mEnumerable);
@@ -356,7 +356,11 @@ rb_grn_table_key_support_get_key (VALUE self, VALUE rb_id)
356
356
  /*
357
357
  * テーブルに主キーが _key_ のレコードがあるならtrueを返す。
358
358
  *
359
+ * @overload key?(key)
360
+ * @since 7.0.0
361
+ *
359
362
  * @overload has_key?(key)
363
+ * @deprecated Use {key?} instead.
360
364
  */
361
365
  static VALUE
362
366
  rb_grn_table_key_support_has_key (VALUE self, VALUE rb_key)
@@ -1123,6 +1127,8 @@ rb_grn_init_table_key_support (VALUE mGrn)
1123
1127
  rb_grn_table_key_support_get_id, -1);
1124
1128
  rb_define_method(rb_mGrnTableKeySupport, "key",
1125
1129
  rb_grn_table_key_support_get_key, 1);
1130
+ rb_define_method(rb_mGrnTableKeySupport, "key?",
1131
+ rb_grn_table_key_support_has_key, 1);
1126
1132
  rb_define_method(rb_mGrnTableKeySupport, "has_key?",
1127
1133
  rb_grn_table_key_support_has_key, 1);
1128
1134
 
@@ -1377,9 +1377,6 @@ rb_grn_table_geo_sort (int argc, VALUE *argv, VALUE self)
1377
1377
  offset = NUM2INT(rb_offset);
1378
1378
  if (!NIL_P(rb_limit))
1379
1379
  limit = NUM2INT(rb_limit);
1380
- /* TODO: Remove me when Groonga 5.1.0 is released. */
1381
- if (limit < 0)
1382
- limit = grn_table_size(context, table) + limit + 1;
1383
1380
 
1384
1381
  result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY,
1385
1382
  NULL, table);
@@ -1061,13 +1061,37 @@ rb_grn_value_to_ruby_object (grn_ctx *context,
1061
1061
 
1062
1062
  grn_id
1063
1063
  rb_grn_id_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *table,
1064
- VALUE related_object)
1064
+ VALUE rb_related_object)
1065
1065
  {
1066
1066
  VALUE rb_id;
1067
1067
 
1068
1068
  if (NIL_P(object))
1069
1069
  return Qnil;
1070
1070
 
1071
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord)) &&
1072
+ !RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cInteger))) {
1073
+ VALUE rb_record;
1074
+ if (table) {
1075
+ VALUE rb_table;
1076
+ rb_table = GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE);
1077
+ if (!NIL_P(rb_table) &&
1078
+ RVAL2CBOOL(rb_obj_is_kind_of(rb_table,
1079
+ rb_mGrnTableKeySupport))) {
1080
+ rb_record = rb_funcall(rb_table, rb_intern("[]"), 1, object);
1081
+ if (NIL_P(rb_record)) {
1082
+ rb_raise(rb_eArgError,
1083
+ "nonexistent key: %" PRIsVALUE
1084
+ ": %" PRIsVALUE
1085
+ ": %" PRIsVALUE,
1086
+ object,
1087
+ rb_table,
1088
+ rb_related_object);
1089
+ }
1090
+ object = rb_record;
1091
+ }
1092
+ }
1093
+ }
1094
+
1071
1095
  if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
1072
1096
  VALUE rb_table;
1073
1097
  rb_table = rb_funcall(object, rb_intern("table"), 0);
@@ -1077,9 +1101,12 @@ rb_grn_id_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *table,
1077
1101
  rb_expected_table =
1078
1102
  GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE);
1079
1103
  rb_raise(rb_eGrnError,
1080
- "wrong table: expected <%s>: actual <%s>",
1081
- rb_grn_inspect(rb_expected_table),
1082
- rb_grn_inspect(rb_table));
1104
+ "wrong table: expected %" PRIsVALUE
1105
+ ": actual %" PRIsVALUE
1106
+ ": %" PRIsVALUE,
1107
+ rb_expected_table,
1108
+ rb_table,
1109
+ rb_related_object);
1083
1110
  }
1084
1111
  rb_id = rb_funcall(object, rb_intern("id"), 0);
1085
1112
  } else {
@@ -1088,9 +1115,10 @@ rb_grn_id_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *table,
1088
1115
 
1089
1116
  if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_id, rb_cInteger)))
1090
1117
  rb_raise(rb_eGrnError,
1091
- "should be unsigned integer or Groogna::Record: <%s>: <%s>",
1092
- rb_grn_inspect(object),
1093
- rb_grn_inspect(related_object));
1118
+ "should be unsigned integer or Groogna::Record: %" PRIsVALUE
1119
+ ": %" PRIsVALUE,
1120
+ object,
1121
+ rb_related_object);
1094
1122
 
1095
1123
  return NUM2UINT(rb_id);
1096
1124
  }
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
2
  /*
3
- Copyright (C) 2009-2016 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2017 Kouhei Sutou <kou@clear-code.com>
4
4
  Copyright (C) 2015-2017 Masafumi Yokoyama <yokoyama@clear-code.com>
5
5
 
6
6
  This library is free software; you can redistribute it and/or
@@ -97,9 +97,9 @@ RB_GRN_BEGIN_DECLS
97
97
  # define debug(...)
98
98
  #endif
99
99
 
100
- #define RB_GRN_MAJOR_VERSION 6
101
- #define RB_GRN_MINOR_VERSION 1
102
- #define RB_GRN_MICRO_VERSION 3
100
+ #define RB_GRN_MAJOR_VERSION 7
101
+ #define RB_GRN_MINOR_VERSION 0
102
+ #define RB_GRN_MICRO_VERSION 2
103
103
 
104
104
  #define RB_GRN_OBJECT(object) ((RbGrnObject *)(object))
105
105
  #define RB_GRN_NAMED_OBJECT(object) ((RbGrnNamedObject *)(object))
@@ -336,6 +336,7 @@ void rb_grn_init_fix_size_column (VALUE mGrn);
336
336
  void rb_grn_init_variable_size_column (VALUE mGrn);
337
337
  void rb_grn_init_index_column (VALUE mGrn);
338
338
  void rb_grn_init_index_cursor (VALUE mGrn);
339
+ void rb_grn_init_inverted_index_cursor (VALUE mGrn);
339
340
  void rb_grn_init_posting (VALUE mGrn);
340
341
  void rb_grn_init_accessor (VALUE mGrn);
341
342
  void rb_grn_init_geo_point (VALUE mGrn);
@@ -367,6 +368,7 @@ void rb_grn_init_request_timer (VALUE mGrn);
367
368
  void rb_grn_init_request_timer_id (VALUE mGrn);
368
369
  void rb_grn_init_id (VALUE mGrn);
369
370
  void rb_grn_init_name (VALUE mGrn);
371
+ void rb_grn_init_default_cache (VALUE mGrn);
370
372
 
371
373
  VALUE rb_grn_rc_to_exception (grn_rc rc);
372
374
  void rb_grn_rc_check (grn_rc rc,
@@ -825,6 +827,13 @@ VALUE rb_grn_index_cursor_to_ruby_object (grn_ctx *context,
825
827
  VALUE rb_table,
826
828
  VALUE rb_lexicon,
827
829
  grn_bool owner);
830
+ VALUE rb_grn_inverted_index_cursor_to_ruby_object
831
+ (grn_ctx *context,
832
+ grn_ii_cursor *cursor,
833
+ grn_id term_id,
834
+ int flags,
835
+ VALUE rb_table,
836
+ VALUE rb_lexicon);
828
837
 
829
838
  grn_operator rb_grn_operator_from_ruby_object (VALUE object);
830
839
  grn_operator rb_grn_set_operator_from_ruby_object (VALUE object);
@@ -229,6 +229,7 @@ Init_groonga (void)
229
229
  rb_grn_init_table(mGrn);
230
230
  rb_grn_init_table_cursor(mGrn);
231
231
  rb_grn_init_index_cursor(mGrn);
232
+ rb_grn_init_inverted_index_cursor(mGrn);
232
233
  rb_grn_init_posting(mGrn);
233
234
  rb_grn_init_type(mGrn);
234
235
  rb_grn_init_procedure(mGrn);
@@ -255,4 +256,5 @@ Init_groonga (void)
255
256
  rb_grn_init_request_timer_id(mGrn);
256
257
  rb_grn_init_id(mGrn);
257
258
  rb_grn_init_name(mGrn);
259
+ rb_grn_init_default_cache(mGrn);
258
260
  }