groonga 0.0.1 → 0.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.
Files changed (52) hide show
  1. data/NEWS.ja.rdoc +11 -0
  2. data/NEWS.rdoc +11 -0
  3. data/README.ja.rdoc +4 -3
  4. data/README.rdoc +4 -3
  5. data/Rakefile +1 -1
  6. data/TUTORIAL.ja.rdoc +168 -44
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-small-many-items.rb +156 -0
  9. data/benchmark/write-small-many-items.rb +145 -0
  10. data/example/bookmark.rb +68 -20
  11. data/ext/rb-grn-array-cursor.c +8 -0
  12. data/ext/rb-grn-array.c +40 -11
  13. data/ext/rb-grn-column.c +38 -209
  14. data/ext/rb-grn-context.c +203 -56
  15. data/ext/rb-grn-database.c +119 -5
  16. data/ext/rb-grn-encoding-support.c +64 -0
  17. data/ext/rb-grn-encoding.c +58 -1
  18. data/ext/rb-grn-fix-size-column.c +220 -0
  19. data/ext/rb-grn-hash-cursor.c +8 -0
  20. data/ext/rb-grn-hash.c +244 -2
  21. data/ext/rb-grn-index-column.c +474 -0
  22. data/ext/rb-grn-object.c +143 -265
  23. data/ext/rb-grn-patricia-trie.c +148 -2
  24. data/ext/rb-grn-query.c +5 -3
  25. data/ext/rb-grn-record.c +3 -2
  26. data/ext/rb-grn-snippet.c +5 -3
  27. data/ext/rb-grn-table-cursor-key-support.c +3 -3
  28. data/ext/rb-grn-table-cursor.c +106 -112
  29. data/ext/rb-grn-table-key-support.c +220 -118
  30. data/ext/rb-grn-table.c +336 -80
  31. data/ext/rb-grn-type.c +5 -4
  32. data/ext/rb-grn-utils.c +62 -63
  33. data/ext/rb-grn.h +215 -14
  34. data/ext/rb-groonga.c +7 -16
  35. data/extconf.rb +3 -1
  36. data/html/favicon.ico +0 -0
  37. data/html/favicon.xcf +0 -0
  38. data/html/index.html +1 -7
  39. data/lib/groonga/record.rb +6 -1
  40. data/test/groonga-test-utils.rb +1 -0
  41. data/test/test-array.rb +81 -0
  42. data/test/test-column.rb +22 -12
  43. data/test/test-context.rb +1 -29
  44. data/test/test-database.rb +30 -0
  45. data/test/test-hash.rb +194 -0
  46. data/test/test-index-column.rb +57 -0
  47. data/test/test-patricia-trie.rb +82 -0
  48. data/test/test-record.rb +10 -10
  49. data/test/test-table.rb +37 -130
  50. data/test/test-type.rb +4 -3
  51. metadata +15 -4
  52. data/benchmark/small-many-items.rb +0 -175
@@ -22,7 +22,51 @@
22
22
  * Document-module: Groonga::Encoding
23
23
  *
24
24
  * groongaがサポートしてるエンコーディングが定義されてい
25
- * るモジュールです。
25
+ * るモジュール。
26
+ *
27
+ * エンコーディングの指定方法は以下の通り。
28
+ *
29
+ * [+nil+]
30
+ * コンテキストと関連付けられているオブジェクトの場合(多
31
+ * くの場合)はコンテキストのエンコーディングを使用。
32
+ *
33
+ * それ以外のオブジェクトの場合(コンテキスト自身など)は
34
+ * groongaのビルド時に指定したエンコーディング
35
+ * (Groonga::Encoding::DEFAULT)を使用
36
+ *
37
+ * [+:default+]
38
+ * groongaのビルド時に指定したエンコーディングを使用。
39
+ * Groonga::Encoding::DEFAULT
40
+ *
41
+ * [+:none+]
42
+ * エンコーディングを指定しない。Groonga::Encoding::NONE
43
+ *
44
+ * [+:euc_jp+]
45
+ * EUC-JPを使用。Groonga::Encoding::EUC_JP
46
+ *
47
+ * [<tt>"euc-jp"</tt>]
48
+ * +:euc_jp+と同じ。
49
+ *
50
+ * [+:utf8+]
51
+ * UTF-8を使用。Groonga::Encoding::UTF8
52
+ *
53
+ * [<tt>"utf-8"</tt>]
54
+ * +:utf8+と同じ。
55
+ *
56
+ * [+:sjis+]
57
+ * Shift_JISを使用。Groonga::Encoding::SJIS
58
+ *
59
+ * [+:shift_jis+]
60
+ * +:sjis+と同じ。
61
+ *
62
+ * [<tt>"shift-jis"</tt>]
63
+ * +:sjis+と同じ。
64
+ *
65
+ * [+:latin1+]
66
+ * Latin-1を使用。Groonga::Encoding::LATIN1
67
+ *
68
+ * [+:koi8r+]
69
+ * KOI8-Rを使用。Groonga::Encoding::KOI8R
26
70
  */
27
71
 
28
72
  static VALUE mGrnEncoding;
@@ -104,12 +148,25 @@ rb_grn_encoding_to_ruby_object (grn_encoding encoding)
104
148
  return rb_encoding;
105
149
  }
106
150
 
151
+ /*
152
+ * call-seq:
153
+ * Groonga::Encoding.default -> エンコーディング
154
+ *
155
+ * デフォルトのエンコーディングを返す。
156
+ */
107
157
  static VALUE
108
158
  rb_grn_encoding_s_get_default (VALUE self)
109
159
  {
110
160
  return GRNENCODING2RVAL(grn_get_default_encoding());
111
161
  }
112
162
 
163
+ /*
164
+ * call-seq:
165
+ * Groonga::Encoding.default(encoding)
166
+ *
167
+ * デフォルトのエンコーディングを設定する。エンコーディング
168
+ * の指定方法はGroonga::Encodingを参照。
169
+ */
113
170
  static VALUE
114
171
  rb_grn_encoding_s_set_default (VALUE self, VALUE rb_encoding)
115
172
  {
@@ -0,0 +1,220 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ #define SELF(object) ((RbGrnFixSizeColumn *)DATA_PTR(object))
22
+
23
+ VALUE rb_cGrnFixSizeColumn;
24
+
25
+ /*
26
+ * Document-class: Groonga::FixSizeColumn < Groonga::Column
27
+ *
28
+ * 固定長データ用のカラム。
29
+ */
30
+
31
+ void
32
+ rb_grn_fix_size_column_unbind (RbGrnFixSizeColumn *rb_grn_fix_size_column)
33
+ {
34
+ RbGrnObject *rb_grn_object;
35
+ grn_ctx *context;
36
+
37
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_fix_size_column);
38
+ context = rb_grn_object->context;
39
+
40
+ if (context)
41
+ grn_obj_close(context, rb_grn_fix_size_column->value);
42
+
43
+ rb_grn_object_unbind(rb_grn_object);
44
+ }
45
+
46
+ static void
47
+ rb_grn_fix_size_column_free (void *object)
48
+ {
49
+ RbGrnFixSizeColumn *rb_grn_fix_size_column = object;
50
+
51
+ rb_grn_fix_size_column_unbind(rb_grn_fix_size_column);
52
+ xfree(rb_grn_fix_size_column);
53
+ }
54
+
55
+ VALUE
56
+ rb_grn_fix_size_column_alloc (VALUE klass)
57
+ {
58
+ return Data_Wrap_Struct(klass, NULL, rb_grn_fix_size_column_free, NULL);
59
+ }
60
+
61
+ void
62
+ rb_grn_fix_size_column_bind (RbGrnFixSizeColumn *rb_grn_fix_size_column,
63
+ grn_ctx *context, grn_obj *column,
64
+ rb_grn_boolean owner)
65
+ {
66
+ RbGrnObject *rb_grn_object;
67
+
68
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_fix_size_column);
69
+ rb_grn_object_bind(rb_grn_object, context, column, owner);
70
+ rb_grn_object->unbind =
71
+ RB_GRN_UNBIND_FUNCTION(rb_grn_fix_size_column_unbind);
72
+
73
+ rb_grn_fix_size_column->value = grn_obj_open(context, GRN_BULK, 0,
74
+ rb_grn_object->range_id);
75
+ }
76
+
77
+ void
78
+ rb_grn_fix_size_column_assign (VALUE self, VALUE rb_context,
79
+ grn_ctx *context, grn_obj *column,
80
+ rb_grn_boolean owner)
81
+ {
82
+ RbGrnFixSizeColumn *rb_grn_fix_size_column;
83
+
84
+ rb_grn_fix_size_column = ALLOC(RbGrnFixSizeColumn);
85
+ DATA_PTR(self) = rb_grn_fix_size_column;
86
+ rb_grn_fix_size_column_bind(rb_grn_fix_size_column, context, column, owner);
87
+
88
+ rb_iv_set(self, "context", rb_context);
89
+ }
90
+
91
+ void
92
+ rb_grn_fix_size_column_deconstruct (RbGrnFixSizeColumn *rb_grn_fix_size_column,
93
+ grn_obj **column,
94
+ grn_ctx **context,
95
+ grn_id *domain_id,
96
+ grn_obj **domain,
97
+ grn_obj **value,
98
+ grn_id *range_id,
99
+ grn_obj **range)
100
+ {
101
+ RbGrnObject *rb_grn_object;
102
+
103
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_fix_size_column);
104
+ rb_grn_object_deconstruct(rb_grn_object, column, context,
105
+ domain_id, domain,
106
+ range_id, range);
107
+
108
+ if (value)
109
+ *value = rb_grn_fix_size_column->value;
110
+ }
111
+
112
+ /*
113
+ * call-seq:
114
+ * column[id] -> 値
115
+ *
116
+ * _column_の_id_に対応する値を返す。
117
+ */
118
+ VALUE
119
+ rb_grn_fix_size_column_array_reference (VALUE self, VALUE rb_id)
120
+ {
121
+ grn_id id;
122
+ grn_ctx *context;
123
+ grn_obj *fix_size_column;
124
+ grn_obj *range;
125
+ grn_obj *value;
126
+
127
+ rb_grn_fix_size_column_deconstruct(SELF(self), &fix_size_column, &context,
128
+ NULL, NULL,
129
+ &value, NULL, &range);
130
+
131
+ id = NUM2UINT(rb_id);
132
+ GRN_BULK_REWIND(value);
133
+ grn_obj_get_value(context, fix_size_column, id, value);
134
+ rb_grn_context_check(context, self);
135
+
136
+ return GRNVALUE2RVAL(context, value, range, self);
137
+ }
138
+
139
+ /*
140
+ * call-seq:
141
+ * column[id] = value
142
+ *
143
+ * _column_の_id_に対応する値を設定する。
144
+ */
145
+ static VALUE
146
+ rb_grn_fix_size_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
147
+ {
148
+ grn_ctx *context = NULL;
149
+ grn_obj *column;
150
+ grn_id domain_id, range_id;
151
+ grn_obj *domain, *range;
152
+ grn_obj *value;
153
+ grn_rc rc;
154
+ grn_id id;
155
+
156
+ rb_grn_fix_size_column_deconstruct(SELF(self), &column, &context,
157
+ &domain_id, &domain,
158
+ &value, &range_id, &range);
159
+
160
+ id = NUM2UINT(rb_id);
161
+
162
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cGrnRecord))) {
163
+ VALUE rb_id, rb_table;
164
+ grn_obj *table;
165
+
166
+ if (!range)
167
+ rb_raise(rb_eArgError,
168
+ "%s isn't associated with any table: %s",
169
+ rb_grn_inspect(self), rb_grn_inspect(rb_value));
170
+
171
+ rb_id = rb_funcall(rb_value, rb_intern("id"), 0);
172
+ rb_table = rb_funcall(rb_value, rb_intern("table"), 0);
173
+ table = RVAL2GRNTABLE(rb_table, &context);
174
+ if (grn_obj_id(context, table) != range_id)
175
+ rb_raise(rb_eArgError,
176
+ "%s isn't associated with passed record's table: %s",
177
+ rb_grn_inspect(self),
178
+ rb_grn_inspect(rb_value));
179
+
180
+ rb_value = rb_id;
181
+ } else if (range) {
182
+ switch (range->header.type) {
183
+ case GRN_TABLE_HASH_KEY:
184
+ case GRN_TABLE_PAT_KEY:
185
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cFixnum))) {
186
+ VALUE rb_range;
187
+ grn_id id;
188
+
189
+ rb_range = GRNOBJECT2RVAL(Qnil, context, range, RB_GRN_FALSE);
190
+ id = rb_grn_table_key_support_get(rb_range, rb_value);
191
+ rb_value = UINT2NUM(id);
192
+ }
193
+ break;
194
+ default:
195
+ break;
196
+ }
197
+ }
198
+
199
+ GRN_BULK_REWIND(value);
200
+ RVAL2GRNBULK(rb_value, context, value);
201
+
202
+ rc = grn_obj_set_value(context, column, id, value, GRN_OBJ_SET);
203
+ rb_grn_context_check(context, self);
204
+ rb_grn_rc_check(rc, self);
205
+
206
+ return Qnil;
207
+ }
208
+
209
+ void
210
+ rb_grn_init_fix_size_column (VALUE mGrn)
211
+ {
212
+ rb_cGrnFixSizeColumn =
213
+ rb_define_class_under(mGrn, "FixSizeColumn", rb_cGrnColumn);
214
+ rb_define_alloc_func(rb_cGrnFixSizeColumn, rb_grn_fix_size_column_alloc);
215
+
216
+ rb_define_method(rb_cGrnFixSizeColumn, "[]",
217
+ rb_grn_fix_size_column_array_reference, 1);
218
+ rb_define_method(rb_cGrnFixSizeColumn, "[]=",
219
+ rb_grn_fix_size_column_array_set, 2);
220
+ }
@@ -20,6 +20,14 @@
20
20
 
21
21
  VALUE rb_cGrnHashCursor;
22
22
 
23
+ /*
24
+ * Document-class: Groonga::HashCursor < Groonga::TableCursor
25
+ *
26
+ * Groonga::Hashに登録されているレコードを順番に取り出すため
27
+ * のオブジェクト。利用できるメソッドはGroonga::TableCursor
28
+ * とGroonga::TableCursorKeySupportを参照。
29
+ */
30
+
23
31
  void
24
32
  rb_grn_init_hash_cursor (VALUE mGrn)
25
33
  {
data/ext/rb-grn-hash.c CHANGED
@@ -18,23 +18,265 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object) (RVAL2GRNTABLE(object))
21
+ #define SELF(object) ((RbGrnTableKeySupport *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_cGrnHash;
24
24
 
25
+ /*
26
+ * Document-class: Groonga::Hash < Groonga::Table
27
+ *
28
+ * 各レコードをキーで管理するテーブル。キーと完全一致するレ
29
+ * コードを非常に高速に検索できる。
30
+ */
31
+
32
+ /*
33
+ * call-seq:
34
+ * Groonga::Hash.create(options={}) -> Groonga::Hash
35
+ * Groonga::Hash.create(options={}) {|table| ... }
36
+ *
37
+ * 各レコードをキーで管理するテーブルを生成する。ブロックを指
38
+ * 定すると、そのブロックに生成したテーブルが渡され、ブロック
39
+ * を抜けると自動的にテーブルが破棄される。
40
+ *
41
+ * _options_に指定可能な値は以下の通り。
42
+ *
43
+ * [+:context+]
44
+ * テーブルが利用するGroonga::Context。省略すると
45
+ * Groonga::Context.defaultを用いる。
46
+ *
47
+ * [+:name+]
48
+ * テーブルの名前。名前をつけると、Groonga::Context#[]に名
49
+ * 前を指定してテーブルを取得することができる。省略すると
50
+ * 無名テーブルになり、テーブルIDでのみ取得できる。
51
+ *
52
+ * [+:path+]
53
+ * テーブルを保存するパス。パスを指定すると永続テーブルとな
54
+ * り、プロセス終了後もレコードは保持される。次回起動時に
55
+ * Groonga::Hash.openで保存されたレコードを利用することが
56
+ * できる。省略すると一時テーブルになり、プロセスが終了する
57
+ * とレコードは破棄される。
58
+ *
59
+ * [+:persistent+]
60
+ * +true+を指定すると永続テーブルとなる。+path+を省略した
61
+ * 場合は自動的にパスが付加される。+:context+で指定した
62
+ * Groonga::Contextに結びついているデータベースが一時デー
63
+ * タベースの場合は例外が発生する。
64
+ *
65
+ * [+:key_type+]
66
+ * キーの種類を示すオブジェクトを指定する。キーの種類には
67
+ * Groonga::Typeまたはテーブル(Groonga::Array、
68
+ * Groonga::Hash、Groonga::PatriciaTrieのどれか)を指定する。
69
+ *
70
+ * Groonga::Typeを指定した場合は、その型が示す範囲の値をキー
71
+ * として使用する。ただし、キーの最大サイズは4096バイトで
72
+ * あるため、Groonga::Type::TEXTやGroonga::Type::LONG_TEXT
73
+ * は使用できない。
74
+ *
75
+ * テーブルを指定した場合はレコードIDをキーとして使用する。
76
+ * 指定したテーブルのGroonga::Recordをキーとして使用するこ
77
+ * ともでき、その場合は自動的にGroonga::Recordからレコード
78
+ * IDを取得する。
79
+ *
80
+ * 省略した場合は文字列をキーとして使用する。この場合、
81
+ * 4096バイトまで使用可能である。
82
+ *
83
+ * [+:value_size+]
84
+ * 値の大きさを指定する。省略すると0になる。
85
+ *
86
+ * [+:default_tokenizer+]
87
+ * Groonga::IndexColumnで使用するトークナイザを指定する。
88
+ * デフォルトでは何も設定されていないので、テーブルに
89
+ * Groonga::IndexColumnを定義する場合は
90
+ * <tt>"<token:bigram>"</tt>などを指定する必要がある。
91
+ *
92
+ * 使用例:
93
+ *
94
+ * 無名一時テーブルを生成する。
95
+ * Groonga::Hash.create
96
+ *
97
+ * 無名永続テーブルを生成する。
98
+ * Groonga::Hash.create(:path => "/tmp/hash.grn")
99
+ *
100
+ * 名前付き永続テーブルを生成する。ただし、ファイル名は気に
101
+ * しない。
102
+ * Groonga::Hash.create(:name => "<bookmarks>",
103
+ * :persistent => true)
104
+ *
105
+ * それぞれのレコードに512バイトの値を格納できる無名一時テー
106
+ * ブルを生成する。
107
+ * Groonga::Hash.create(:value => 512)
108
+ *
109
+ * キーとして文字列を使用する無名一時テーブルを生成する。
110
+ * Groonga::Hash.create(:key_type => Groonga::Type::TEXT)
111
+ *
112
+ * キーとして文字列を使用する無名一時テーブルを生成する。
113
+ * (キーの種類を表すオブジェクトは文字列で指定。)
114
+ * Groonga::Hash.create(:key_type => "<shorttext>")
115
+ *
116
+ * キーとして<tt><bookmarks></tt>テーブルのレコードを使用す
117
+ * る無名一時テーブルを生成する。
118
+ * bookmarks = Groonga::Hash.create(:name => "<bookmarks>")
119
+ * Groonga::Hash.create(:key_type => bookmarks)
120
+ *
121
+ * キーとして<tt><bookmarks></tt>テーブルのレコードを使用す
122
+ * る無名一時テーブルを生成する。
123
+ * (テーブルは文字列で指定。)
124
+ * Groonga::Hash.create(:name => "<bookmarks>")
125
+ * Groonga::Hash.create(:key_type => "<bookmarks>")
126
+ *
127
+ * 全文検索用のトークンをバイグラムで切り出す無名一時テーブ
128
+ * ルを生成する。
129
+ * bookmarks = Groonga::Hash.create(:name => "<bookmarks>")
130
+ * bookmarks.define_column("comment", "<text>")
131
+ * terms = Groonga::Hash.create(:name => "<terms>",
132
+ * :default_tokenizer => "<token:bigram>")
133
+ * terms.define_index_column("content", bookmarks,
134
+ * :source => "<bookmarks>.comment")
135
+ */
25
136
  static VALUE
26
137
  rb_grn_hash_s_create (int argc, VALUE *argv, VALUE self)
27
138
  {
28
- return rb_grn_table_s_create(argc, argv, self, GRN_TABLE_HASH_KEY);
139
+ grn_ctx *context;
140
+ grn_obj *key_type = NULL, *table;
141
+ const char *name = NULL, *path = NULL;
142
+ unsigned name_size = 0, value_size = 0;
143
+ grn_obj_flags flags = GRN_TABLE_HASH_KEY;
144
+ VALUE rb_table;
145
+ VALUE options, rb_context, rb_name, rb_path, rb_persistent;
146
+ VALUE rb_key_type, rb_value_size, rb_default_tokenizer;
147
+
148
+ rb_scan_args(argc, argv, "01", &options);
149
+
150
+ rb_grn_scan_options(options,
151
+ "context", &rb_context,
152
+ "name", &rb_name,
153
+ "path", &rb_path,
154
+ "persistent", &rb_persistent,
155
+ "key_type", &rb_key_type,
156
+ "value_size", &rb_value_size,
157
+ "default_tokenizer", &rb_default_tokenizer,
158
+ NULL);
159
+
160
+ context = rb_grn_context_ensure(&rb_context);
161
+
162
+ if (!NIL_P(rb_name)) {
163
+ name = StringValuePtr(rb_name);
164
+ name_size = RSTRING_LEN(rb_name);
165
+ }
166
+
167
+ if (!NIL_P(rb_path)) {
168
+ path = StringValueCStr(rb_path);
169
+ flags |= GRN_OBJ_PERSISTENT;
170
+ }
171
+
172
+ if (RVAL2CBOOL(rb_persistent))
173
+ flags |= GRN_OBJ_PERSISTENT;
174
+
175
+ if (NIL_P(rb_key_type)) {
176
+ flags |= GRN_OBJ_KEY_VAR_SIZE;
177
+ } else {
178
+ key_type = RVAL2GRNOBJECT(rb_key_type, &context);
179
+ }
180
+
181
+ if (!NIL_P(rb_value_size))
182
+ value_size = NUM2UINT(rb_value_size);
183
+
184
+ table = grn_table_create(context, name, name_size, path,
185
+ flags, key_type, value_size);
186
+ if (!table)
187
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
188
+ rb_table = rb_grn_table_key_support_alloc(self);
189
+ rb_grn_table_key_support_assign(rb_table, rb_context, context, table,
190
+ RB_GRN_TRUE);
191
+ rb_grn_context_check(context, rb_table);
192
+
193
+ if (!NIL_P(rb_default_tokenizer))
194
+ rb_funcall(rb_table, rb_intern("default_tokenizer="), 1,
195
+ rb_default_tokenizer);
196
+
197
+ if (rb_block_given_p())
198
+ return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
199
+ else
200
+ return rb_table;
201
+ }
202
+
203
+ /*
204
+ * call-seq:
205
+ * hash.search(key, options=nil) -> Groonga::Hash
206
+ *
207
+ * _key_にマッチするレコードのIDがキーに入っている
208
+ * Groonga::Hashを返す。マッチするレコードがない場合は空の
209
+ * Groonga::Hashが返。
210
+ *
211
+ * _options_で+:result+を指定することにより、そのテーブルにマッ
212
+ * チしたレコードIDがキーのレコードを追加することができる。
213
+ * +:result+にテーブルを指定した場合は、そのテーブルが返る。
214
+ *
215
+ * _options_に指定可能な値は以下の通り。
216
+ *
217
+ * [+:result+]
218
+ * 結果を格納するテーブル。
219
+ *
220
+ * 複数のキーで検索し、結果を1つのテーブルに集める。
221
+ * result = nil
222
+ * keys = ["morita", "gunyara-kun", "yu"]
223
+ * keys.each do |key|
224
+ * result = users.search(key, :result => result)
225
+ * end
226
+ * result.each do |record|
227
+ * user = record.key
228
+ * p user.key # -> "morita"または"gunyara-kun"または"yu"
229
+ * end
230
+ */
231
+ static VALUE
232
+ rb_grn_hash_search (int argc, VALUE *argv, VALUE self)
233
+ {
234
+ grn_rc rc;
235
+ grn_ctx *context;
236
+ grn_obj *table;
237
+ grn_id domain_id;
238
+ grn_obj *key, *domain, *result;
239
+ VALUE rb_key, options, rb_result;
240
+
241
+ rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
242
+ &key, &domain_id, &domain,
243
+ NULL, NULL, NULL);
244
+
245
+ rb_scan_args(argc, argv, "11", &rb_key, &options);
246
+
247
+ RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);
248
+
249
+ rb_grn_scan_options(options,
250
+ "result", &rb_result,
251
+ NULL);
252
+
253
+ if (NIL_P(rb_result)) {
254
+ result = grn_table_create(context, NULL, 0, NULL,
255
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
256
+ table, 0);
257
+ rb_grn_context_check(context, self);
258
+ rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
259
+ } else {
260
+ result = RVAL2GRNOBJECT(rb_result, &context);
261
+ }
262
+
263
+ rc = grn_obj_search(context, table, key,
264
+ result, GRN_SEL_OR, NULL);
265
+ rb_grn_rc_check(rc, self);
266
+
267
+ return rb_result;
29
268
  }
30
269
 
31
270
  void
32
271
  rb_grn_init_hash (VALUE mGrn)
33
272
  {
34
273
  rb_cGrnHash = rb_define_class_under(mGrn, "Hash", rb_cGrnTable);
274
+ rb_define_alloc_func(rb_cGrnHash, rb_grn_table_key_support_alloc);
35
275
 
36
276
  rb_include_module(rb_cGrnHash, rb_mGrnTableKeySupport);
37
277
 
38
278
  rb_define_singleton_method(rb_cGrnHash, "create",
39
279
  rb_grn_hash_s_create, -1);
280
+
281
+ rb_define_method(rb_cGrnHash, "search", rb_grn_hash_search, -1);
40
282
  }