rroonga 6.1.3 → 7.0.2

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.
@@ -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
  }