groonga 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # This benchmark is based on Tokyo Cabinet's benchmark at
4
+ # http://alpha.mixi.co.jp/blog/?p=791
5
+ #
6
+ # On my environment at 2009/05/16:
7
+ # % for x in {0..9}; do ruby benchmark/write-small-many-items.rb $x; done
8
+ # user system total real memory
9
+ # Hash 1.090000 0.180000 1.270000 ( 1.565159) 47.090MB
10
+ # groonga: Hash: memory 0.930000 0.140000 1.070000 ( 1.364338) 23.473MB
11
+ # groonga: Trie: memory 1.170000 0.120000 1.290000 ( 1.601229) 15.480MB
12
+ # groonga: Hash: file 0.980000 0.170000 1.150000 ( 1.398126) 23.477MB
13
+ # groonga: Trie: file 1.220000 0.130000 1.350000 ( 1.744243) 15.484MB
14
+ # Localmemcache: file 1.100000 0.210000 1.310000 ( 1.734014) 39.301MB
15
+ # TC: Hash: memory 0.710000 0.130000 0.840000 ( 1.061472) 42.055MB
16
+ # TC: Tree: memory 0.640000 0.150000 0.790000 ( 1.040223) 30.566MB
17
+ # TC: Hash: file 1.310000 2.370000 3.680000 ( 5.028978) 2.133MB
18
+ # TC: Tree: file 1.030000 0.200000 1.230000 ( 1.666725) 6.086MB
19
+ #
20
+ # Ruby: Debian GNU/Linux sid at 2009/05/16:
21
+ # ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]
22
+ # groonga: HEAD at 2009/05/16: ed49074fbc217b97c0b0b8d675f2417f9490c87e
23
+ # Ruby/Groonga: trunk at 2009/05/16: r321
24
+ # Localmemcache: HEAD at 2009/05/16: 6f8cfbd3a103c2be8d54834a65deb096d7cda34f
25
+ # Tokyo Cabinet: 1.4.20
26
+ # Tokyo Cabinet Ruby: 1.23
27
+ #
28
+ # NOTE: All C source codes are built with "-g -O0"
29
+ # option. They will be more faster with "-O2" option.
30
+
31
+ require File.join(File.dirname(__FILE__), "common.rb")
32
+
33
+ n = 500000
34
+
35
+ values = []
36
+ n.times do |i|
37
+ values << "%08d" % i
38
+ end
39
+
40
+ item("Hash") do
41
+ @hash = {}
42
+ values.each do |value|
43
+ @hash[value] = value
44
+ end
45
+ end
46
+
47
+ begin
48
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
49
+ $LOAD_PATH.unshift(File.join(base_dir, "ext"))
50
+ $LOAD_PATH.unshift(File.join(base_dir, "lib"))
51
+
52
+ require 'groonga'
53
+ @database = Groonga::Database.create
54
+
55
+ item("groonga: Hash: memory") do
56
+ @hash = Groonga::Hash.create(:key_type => "<shorttext>",
57
+ :value_size => 8)
58
+ values.each do |value|
59
+ @hash[value] = value
60
+ end
61
+ end
62
+
63
+ item("groonga: Trie: memory") do
64
+ @hash = Groonga::PatriciaTrie.create(:key_type => "<shorttext>",
65
+ :value_size => 8)
66
+ values.each do |value|
67
+ @hash[value] = value
68
+ end
69
+ end
70
+
71
+ @hash_file = Tempfile.new("groonga-hash")
72
+ item("groonga: Hash: file") do
73
+ @hash = Groonga::Hash.create(:key_type => "<shorttext>",
74
+ :value_size => 8,
75
+ :path => @hash_file.path)
76
+ values.each do |value|
77
+ @hash[value] = value
78
+ end
79
+ end
80
+
81
+ trie_file = Tempfile.new("groonga-trie")
82
+ item("groonga: Trie: file") do
83
+ @hash = Groonga::PatriciaTrie.create(:key_type => "<shorttext>",
84
+ :value_size => 8,
85
+ :path => trie_file.path)
86
+ values.each do |value|
87
+ @hash[value] = value
88
+ end
89
+ end
90
+ rescue LoadError
91
+ end
92
+
93
+ begin
94
+ require 'localmemcache'
95
+
96
+ item("Localmemcache: file") do
97
+ LocalMemCache.drop(:namespace => "write-small-many-items", :force => true)
98
+ @db = LocalMemCache.new(:namespace => "write-small-many-items")
99
+ values.each do |value|
100
+ @db[value] = value
101
+ end
102
+ end
103
+ rescue LoadError
104
+ end
105
+
106
+ begin
107
+ require 'tokyocabinet'
108
+
109
+ item("TC: Hash: memory") do
110
+ @db = TokyoCabinet::ADB::new
111
+ @db.open("*#bnum=#{n}#mode=wct#xmsiz=0")
112
+ values.each do |value|
113
+ @db.put(value, value)
114
+ end
115
+ end
116
+
117
+ item("TC: Tree: memory") do
118
+ @db = TokyoCabinet::ADB::new
119
+ @db.open("+#bnum=#{n}#mode=wct#xmsiz=0")
120
+ values.each do |value|
121
+ @db.put(value, value)
122
+ end
123
+ end
124
+
125
+ hash_file = Tempfile.new(["tc-hash", ".tch"])
126
+ item("TC: Hash: file") do
127
+ @db = TokyoCabinet::ADB::new
128
+ @db.open("#{hash_file.path}#bnum=#{n}#mode=wct#xmsiz=0")
129
+ values.each do |value|
130
+ @db.put(value, value)
131
+ end
132
+ end
133
+
134
+ tree_file = Tempfile.new(["tc-tree", ".tcb"])
135
+ item("TC: Tree: file") do
136
+ @db = TokyoCabinet::ADB::new
137
+ @db.open("#{tree_file.path}#bnum=#{n}#mode=wct#xmsiz=0")
138
+ values.each do |value|
139
+ @db.put(value, value)
140
+ end
141
+ end
142
+ rescue LoadError
143
+ end
144
+
145
+ report(Integer(ARGV[0] || 0))
data/example/bookmark.rb CHANGED
@@ -10,29 +10,77 @@ Groonga::Context.default_options = {:encoding => :utf8}
10
10
  path = ARGV[0]
11
11
  persistent = !path.nil?
12
12
 
13
- Groonga::Database.create(:path => path)
13
+ p Groonga::Database.create(:path => path)
14
14
 
15
- items = Groonga::Hash.create(:name => "<items>", :persistent => persistent)
15
+ p(items = Groonga::Hash.create(:name => "<items>", :persistent => persistent))
16
16
 
17
- items.add("http://ja.wikipedia.org/wiki/Ruby")
18
- items.add("http://www.ruby-lang.org/")
17
+ p items.add("http://ja.wikipedia.org/wiki/Ruby")
18
+ p items.add("http://www.ruby-lang.org/")
19
19
 
20
- title_column = items.define_column("title", "<text>",
21
- :persistent => persistent)
20
+ p items.define_column("title", "<text>", :persistent => persistent)
22
21
 
23
- terms = Groonga::Hash.create(:name => "<terms>",
24
- :key_type => "<shorttext>",
25
- :key_normalize => true,
26
- :persistent => persistent)
27
- title_index_column = terms.define_column("item_title", items,
28
- :type => "index",
29
- :with_position => true,
30
- :persistent => persistent)
31
- title_index_column.source = title_column
22
+ p(terms = Groonga::Hash.create(:name => "<terms>",
23
+ :key_type => "<shorttext>",
24
+ :persistent => persistent,
25
+ :default_tokenizer => "<token:bigram>"))
26
+ p terms.define_index_column("item_title", items,
27
+ :persistent => persistent,
28
+ :source => "<items>.title")
32
29
 
33
- items["http://ja.wikipedia.org/wiki/Ruby"]["title"] = "Ruby"
34
- items["http://www.ruby-lang.org/"]["title"] = "オブジェクトスクリプト言語Ruby"
30
+ p items.find("http://ja.wikipedia.org/wiki/Ruby")["title"] = "Ruby"
31
+ p items.find("http://www.ruby-lang.org/")["title"] = "オブジェクトスクリプト言語Ruby"
35
32
 
36
- p terms.collect(&:key)
37
- p title_index_column.search("Ruby").size
38
- p title_index_column.search("ruby").size
33
+ p(users = Groonga::Hash.create(:name => "<users>",
34
+ :key_type => "<shorttext>",
35
+ :persistent => persistent))
36
+ p users.define_column("name", "<text>",
37
+ :persistent => persistent)
38
+
39
+ p(comments = Groonga::Array.create(:name => "<comments>",
40
+ :persistent => persistent))
41
+ p comments.define_column("item", items)
42
+ p comments.define_column("author", users)
43
+ p comments.define_column("content", "<text>")
44
+ p comments.define_column("issued", "<time>")
45
+
46
+ p terms.define_index_column("comment_content", comments,
47
+ :persistent => persistent,
48
+ :source => "<comments>.content")
49
+
50
+ p users.add("moritan", :name => "モリタン")
51
+ p users.add("taporobo", :name => "タポロボ")
52
+
53
+
54
+ p items.find("http://d.hatena.ne.jp/brazil/20050829/1125321936")
55
+
56
+ p items.add("http://d.hatena.ne.jp/brazil/20050829/1125321936",
57
+ :title => "[翻訳]JavaScript: 世界で最も誤解されたプログラミング言語")
58
+
59
+ p comments.add(:item => "http://d.hatena.ne.jp/brazil/20050829/1125321936",
60
+ :author => "moritan",
61
+ :content => "JavaScript LISP",
62
+ :issued => 1187430026)
63
+
64
+ @items = items
65
+ @comments = comments
66
+ def add_bookmark(url, title, author, content, issued)
67
+ item = @items.find(url) || @items.add(url, :title => title)
68
+ @comments.add(:item => item,
69
+ :author => author,
70
+ :content => content,
71
+ :issued => issued)
72
+ end
73
+
74
+ p add_bookmark("http://practical-scheme.net/docs/cont-j.html",
75
+ "なんでも継続", "moritan", "継続 LISP Scheme", 1187568692)
76
+ p add_bookmark("http://d.hatena.ne.jp/higepon/20070815/1187192864",
77
+ "末尾再帰", "taporobo", "末尾再帰 Scheme LISP", 1187568793)
78
+ p add_bookmark("http://practical-scheme.net/docs/cont-j.html",
79
+ "なんでも継続", "taporobo", "トランポリン LISP continuation",
80
+ 1187568692)
81
+
82
+ terms.column("comment_content").search("LISP").each do |record|
83
+ record = record.key
84
+ p [record[".issued"], record[".item.title"], record[".author.name"],
85
+ record[".content"]]
86
+ end
@@ -20,6 +20,14 @@
20
20
 
21
21
  VALUE rb_cGrnArrayCursor;
22
22
 
23
+ /*
24
+ * Document-class: Groonga::ArrayCursor < Groonga::TableCursor
25
+ *
26
+ * Groonga::Arrayに登録されているレコードを順番に取り出すため
27
+ * のオブジェクト。利用できるメソッドはGroonga::TableCursorを
28
+ * 参照。
29
+ */
30
+
23
31
  void
24
32
  rb_grn_init_array_cursor (VALUE mGrn)
25
33
  {
data/ext/rb-grn-array.c CHANGED
@@ -25,8 +25,8 @@ VALUE rb_cGrnArray;
25
25
  /*
26
26
  * Document-class: Groonga::Array < Groonga::Table
27
27
  *
28
- * 各レコードにキーが存在しないテーブル。レコードはIDで識別
29
- * する。
28
+ * 各レコードがキーに関連付けられていないテーブル。レコードは
29
+ * IDで識別する。
30
30
  */
31
31
 
32
32
  /*
@@ -51,7 +51,7 @@ VALUE rb_cGrnArray;
51
51
  *
52
52
  * [+:path+]
53
53
  * テーブルを保存するパス。パスを指定すると永続テーブルとな
54
- * り、プロセス終了後もレコードは保持され、次回起動時に
54
+ * り、プロセス終了後もレコードは保持される。次回起動時に
55
55
  * Groonga::Array.openで保存されたレコードを利用することが
56
56
  * できる。省略すると一時テーブルになり、プロセスが終了する
57
57
  * とレコードは破棄される。
@@ -65,6 +65,8 @@ VALUE rb_cGrnArray;
65
65
  * [+:value_size+]
66
66
  * 値の大きさを指定する。省略すると0になる。
67
67
  *
68
+ * 使用例:
69
+ *
68
70
  * 無名一時テーブルを生成する。
69
71
  * Groonga::Array.create
70
72
  *
@@ -102,7 +104,7 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
102
104
  "value_size", &rb_value_size,
103
105
  NULL);
104
106
 
105
- context = rb_grn_context_ensure(rb_context);
107
+ context = rb_grn_context_ensure(&rb_context);
106
108
 
107
109
  if (!NIL_P(rb_name)) {
108
110
  name = StringValuePtr(rb_name);
@@ -122,8 +124,11 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
122
124
 
123
125
  table = grn_table_create(context, name, name_size, path,
124
126
  flags, NULL, value_size);
127
+ if (!table)
128
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
125
129
  rb_table = GRNOBJECT2RVAL(klass, context, table, RB_GRN_TRUE);
126
130
  rb_grn_context_check(context, rb_table);
131
+ rb_iv_set(rb_table, "context", rb_context);
127
132
 
128
133
  if (rb_block_given_p())
129
134
  return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
@@ -133,27 +138,51 @@ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
133
138
 
134
139
  /*
135
140
  * call-seq:
136
- * array.add -> Groonga::Recordまたはnil
141
+ * array.add(values=nil) -> Groonga::Recordまたはnil
142
+ *
143
+ * レコード追加し、追加したレコードを返す。レコードの追加に失
144
+ * 敗した場合は+nil+を返す。
145
+ *
146
+ * _values_にはレコードのカラムに設定する値を指定する。省略
147
+ * した場合または+nil+を指定した場合はカラムは設定しない。カ
148
+ * ラムの値は<tt>{:カラム名1 => 値1, :カラム名2 => 値2,
149
+ * ...}</tt>と指定する。
150
+ *
151
+ * 使用例では、以下のようなユーザを格納するGroonga::Arrayが
152
+ * 定義されているものとする。
153
+ * users = Groonga::Array.create(:name => "<users>")
154
+ * users.define_column("name", "<shorttext>")
155
+ * users.define_column("uri", "<shorttext>")
137
156
  *
138
- * レコード追加し、追加したレコードを返します。レコードの追
139
- * 加に失敗した場合は+nil+を返します。
157
+ * ユーザを追加する。
158
+ * user = users.add
159
+ *
160
+ * daijiroユーザを追加する。
161
+ * daijiro = users.add(:name => "daijiro")
162
+ *
163
+ * gunyara-kunユーザを追加する。
164
+ * gunyara_kun = users.add(:name => "gunyara-kun",
165
+ * :uri => "http://d.hatena.ne.jp/tasukuchan/")
140
166
  */
141
167
  static VALUE
142
- rb_grn_array_add (VALUE self)
168
+ rb_grn_array_add (int argc, VALUE *argv, VALUE self)
143
169
  {
144
170
  grn_ctx *context = NULL;
145
171
  grn_obj *table;
146
172
  grn_id id;
173
+ VALUE values;
174
+
175
+ rb_scan_args(argc, argv, "01", &values);
147
176
 
148
177
  table = SELF(self, &context);
149
178
 
150
- id = grn_table_add(context, table);
179
+ id = grn_table_add(context, table, NULL, 0, NULL);
151
180
  rb_grn_context_check(context, self);
152
181
 
153
182
  if (GRN_ID_NIL == id)
154
183
  return Qnil;
155
184
  else
156
- return rb_grn_record_new(self, id);
185
+ return rb_grn_record_new(self, id, values);
157
186
  }
158
187
 
159
188
  void
@@ -164,5 +193,5 @@ rb_grn_init_array (VALUE mGrn)
164
193
  rb_define_singleton_method(rb_cGrnArray, "create",
165
194
  rb_grn_array_s_create, -1);
166
195
 
167
- rb_define_method(rb_cGrnArray, "add", rb_grn_array_add, 0);
196
+ rb_define_method(rb_cGrnArray, "add", rb_grn_array_add, -1);
168
197
  }
data/ext/rb-grn-column.c CHANGED
@@ -18,12 +18,35 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object, context) (RVAL2GRNCOLUMN(object, context))
21
+ #define SELF(object) ((RbGrnColumn *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_cGrnColumn;
24
- VALUE rb_cGrnFixSizeColumn;
25
24
  VALUE rb_cGrnVarSizeColumn;
26
- VALUE rb_cGrnIndexColumn;
25
+
26
+ /*
27
+ * Document-class: Groonga::Column < Groonga::Object
28
+ *
29
+ * テーブルに情報を付加するためのオブジェクト。テーブルに複
30
+ * 数のカラムを定義することによりレコード毎に複数の情報を付
31
+ * 加することができる。
32
+ *
33
+ * カラムには大きく分けて3種類ある。
34
+ * [Groonga::FixSizeColumn]
35
+ * 固定長のデータを格納するカラム。
36
+ * [Groonga::VarSizeColumn]
37
+ * 可変長のデータを格納するカラム。
38
+ * [Groonga::IndexColumn]
39
+ * 転置インデックスを格納するカラム。全文検索や参照元レコー
40
+ * ドの検索を行う場合はこのカラムを使用する。
41
+ *
42
+ * 固定長データ用カラム・可変長データ用カラムは1つのデータだ
43
+ * けを格納するか複数のデータを格納するかを選ぶことができる。
44
+ * 1つのデータの場合はスカラ値、複数のデータの場合はスカラー
45
+ * 値を格納するという。
46
+ *
47
+ * カラムは名前を持ち、1つのテーブルでは同じカラム名を持つカ
48
+ * ラムを複数定義することはできない。
49
+ */
27
50
 
28
51
  grn_obj *
29
52
  rb_grn_column_from_ruby_object (VALUE object, grn_ctx **context)
@@ -42,112 +65,12 @@ rb_grn_column_to_ruby_object (VALUE klass, grn_ctx *context, grn_obj *column,
42
65
  return GRNOBJECT2RVAL(klass, context, column, owner);
43
66
  }
44
67
 
45
- static VALUE
46
- rb_grn_fix_size_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
47
- {
48
- grn_ctx *context = NULL;
49
- grn_obj *column;
50
- grn_id range;
51
- grn_obj *range_object = NULL;
52
- grn_rc rc;
53
- grn_id id;
54
- grn_obj value;
55
-
56
- column = SELF(self, &context);
57
- id = NUM2UINT(rb_id);
58
-
59
- range = grn_obj_get_range(context, column);
60
- if (range != GRN_ID_NIL)
61
- range_object = grn_ctx_get(context, range);
62
-
63
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cGrnRecord))) {
64
- VALUE rb_id, rb_table;
65
- grn_obj *table;
66
-
67
- if (!range_object)
68
- rb_raise(rb_eArgError,
69
- "%s isn't associated with any table: %s",
70
- rb_grn_inspect(self), rb_grn_inspect(rb_value));
71
-
72
- rb_id = rb_funcall(rb_value, rb_intern("id"), 0);
73
- rb_table = rb_funcall(rb_value, rb_intern("table"), 0);
74
- table = RVAL2GRNTABLE(rb_table, &context);
75
- if (grn_obj_id(context, table) != range)
76
- rb_raise(rb_eArgError,
77
- "%s isn't associated with passed record's table: %s",
78
- rb_grn_inspect(self),
79
- rb_grn_inspect(rb_value));
80
-
81
- RVAL2GRNUVECTOR(rb_ary_new3(1, rb_id), context, &value);
82
- } else if (range_object &&
83
- RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cInteger))) {
84
- switch (range_object->header.type) {
85
- case GRN_TABLE_PAT_KEY:
86
- case GRN_TABLE_HASH_KEY:
87
- case GRN_TABLE_NO_KEY:
88
- RVAL2GRNUVECTOR(rb_ary_new3(1, rb_value), context, &value);
89
- break;
90
- default:
91
- RVAL2GRNBULK(rb_value, context, &value);
92
- break;
93
- }
94
- } else {
95
- RVAL2GRNBULK(rb_value, context, &value);
96
- }
97
-
98
- rc = grn_obj_set_value(context, column, id, &value, GRN_OBJ_SET);
99
- grn_obj_close(context, &value);
100
- rb_grn_rc_check(rc, self);
101
-
102
- return Qnil;
103
- }
104
-
105
- static VALUE
106
- rb_grn_index_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
107
- {
108
- grn_ctx *context = NULL;
109
- grn_obj *column;
110
- grn_rc rc;
111
- grn_id id;
112
- unsigned int section;
113
- grn_obj old_value, new_value;
114
- VALUE rb_section, rb_old_value, rb_new_value;
115
-
116
- column = SELF(self, &context);
117
-
118
- id = NUM2UINT(rb_id);
119
-
120
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
121
- VALUE hash_value;
122
- hash_value = rb_hash_new();
123
- rb_hash_aset(hash_value, RB_GRN_INTERN("value"), rb_value);
124
- rb_value = hash_value;
125
- }
126
-
127
- rb_grn_scan_options(rb_value,
128
- "section", &rb_section,
129
- "old_value", &rb_old_value,
130
- "value", &rb_new_value,
131
- NULL);
132
-
133
- if (NIL_P(rb_section))
134
- section = 1;
135
- else
136
- section = NUM2UINT(rb_section);
137
-
138
- RVAL2GRNBULK(rb_old_value, context, &old_value);
139
- RVAL2GRNBULK(rb_new_value, context, &new_value);
140
-
141
- rc = grn_column_index_update(context, column,
142
- id, section, &old_value, &new_value);
143
- grn_obj_close(context, &old_value);
144
- grn_obj_close(context, &new_value);
145
-
146
- rb_grn_rc_check(rc, self);
147
-
148
- return Qnil;
149
- }
150
-
68
+ /*
69
+ * call-seq:
70
+ * column.table -> Groonga::Table
71
+ *
72
+ * カラムが所属するテーブルを返す。
73
+ */
151
74
  static VALUE
152
75
  rb_grn_column_get_table (VALUE self)
153
76
  {
@@ -155,119 +78,25 @@ rb_grn_column_get_table (VALUE self)
155
78
  grn_obj *column;
156
79
  grn_obj *table;
157
80
 
158
- column = SELF(self, &context);
81
+ rb_grn_object_deconstruct((RbGrnObject *)(SELF(self)), &column, &context,
82
+ NULL, NULL,
83
+ NULL, NULL);
159
84
  table = grn_column_table(context, column);
160
85
  rb_grn_context_check(context, self);
161
86
 
162
87
  return GRNOBJECT2RVAL(Qnil, context, table, RB_GRN_FALSE);
163
88
  }
164
89
 
165
- static VALUE
166
- rb_grn_index_column_get_sources (VALUE self)
167
- {
168
- grn_ctx *context = NULL;
169
- grn_obj *column;
170
- grn_obj sources;
171
- grn_id *source_ids;
172
- VALUE rb_sources;
173
- int i, n;
174
-
175
- column = SELF(self, &context);
176
-
177
- grn_obj_get_info(context, column, GRN_INFO_SOURCE, &sources);
178
- rb_grn_context_check(context, self);
179
-
180
- n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
181
- source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
182
- rb_sources = rb_ary_new2(n);
183
- for (i = 0; i < n; i++) {
184
- grn_obj *source;
185
- VALUE rb_source;
186
-
187
- source = grn_ctx_get(context, *source_ids);
188
- rb_source = GRNOBJECT2RVAL(Qnil, context, source, RB_GRN_FALSE);
189
- rb_ary_push(rb_sources, rb_source);
190
- source_ids++;
191
- }
192
-
193
- return rb_sources;
194
- }
195
-
196
- static VALUE
197
- rb_grn_index_column_set_sources (VALUE self, VALUE rb_sources)
198
- {
199
- grn_ctx *context = NULL;
200
- grn_obj *column;
201
- int i, n;
202
- VALUE *rb_source_values;
203
- grn_id *sources;
204
- grn_rc rc;
205
-
206
- column = SELF(self, &context);
207
-
208
- n = RARRAY_LEN(rb_sources);
209
- rb_source_values = RARRAY_PTR(rb_sources);
210
- sources = ALLOCA_N(grn_id, n);
211
- for (i = 0; i < n; i++) {
212
- VALUE rb_source_id;
213
- grn_obj *source;
214
- grn_id source_id;
215
-
216
- rb_source_id = rb_source_values[i];
217
- if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source_id, rb_cInteger))) {
218
- source_id = NUM2UINT(rb_source_id);
219
- } else {
220
- source = RVAL2GRNOBJECT(rb_source_id, &context);
221
- rb_grn_context_check(context, rb_source_id);
222
- source_id = grn_obj_id(context, source);
223
- }
224
- sources[i] = source_id;
225
- }
226
-
227
- {
228
- grn_obj source;
229
- GRN_OBJ_INIT(&source, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY);
230
- GRN_BULK_SET(context, &source, sources, n * sizeof(grn_id));
231
- rc = grn_obj_set_info(context, column, GRN_INFO_SOURCE, &source);
232
- }
233
-
234
- rb_grn_context_check(context, self);
235
- rb_grn_rc_check(rc, self);
236
-
237
- return Qnil;
238
- }
239
-
240
- static VALUE
241
- rb_grn_index_column_set_source (VALUE self, VALUE rb_source)
242
- {
243
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cArray)))
244
- rb_source = rb_ary_new3(1, rb_source);
245
-
246
- return rb_grn_index_column_set_sources(self, rb_source);
247
- }
248
-
249
90
  void
250
91
  rb_grn_init_column (VALUE mGrn)
251
92
  {
252
93
  rb_cGrnColumn = rb_define_class_under(mGrn, "Column", rb_cGrnObject);
253
- rb_cGrnFixSizeColumn =
254
- rb_define_class_under(mGrn, "FixSizeColumn", rb_cGrnColumn);
94
+
255
95
  rb_cGrnVarSizeColumn =
256
96
  rb_define_class_under(mGrn, "VarSizeColumn", rb_cGrnColumn);
257
- rb_cGrnIndexColumn =
258
- rb_define_class_under(mGrn, "IndexColumn", rb_cGrnColumn);
259
-
260
- rb_define_method(rb_cGrnFixSizeColumn, "[]=",
261
- rb_grn_fix_size_column_array_set, 2);
262
- rb_define_method(rb_cGrnIndexColumn, "[]=",
263
- rb_grn_index_column_array_set, 2);
264
97
 
265
98
  rb_define_method(rb_cGrnColumn, "table", rb_grn_column_get_table, 0);
266
99
 
267
- rb_define_method(rb_cGrnIndexColumn, "sources",
268
- rb_grn_index_column_get_sources, 0);
269
- rb_define_method(rb_cGrnIndexColumn, "sources=",
270
- rb_grn_index_column_set_sources, 1);
271
- rb_define_method(rb_cGrnIndexColumn, "source=",
272
- rb_grn_index_column_set_source, 1);
100
+ rb_grn_init_fix_size_column(mGrn);
101
+ rb_grn_init_index_column(mGrn);
273
102
  }