groonga 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.ja.rdoc +11 -0
- data/NEWS.rdoc +11 -0
- data/README.ja.rdoc +4 -3
- data/README.rdoc +4 -3
- data/Rakefile +1 -1
- data/TUTORIAL.ja.rdoc +168 -44
- data/benchmark/common.rb +49 -0
- data/benchmark/read-write-small-many-items.rb +156 -0
- data/benchmark/write-small-many-items.rb +145 -0
- data/example/bookmark.rb +68 -20
- data/ext/rb-grn-array-cursor.c +8 -0
- data/ext/rb-grn-array.c +40 -11
- data/ext/rb-grn-column.c +38 -209
- data/ext/rb-grn-context.c +203 -56
- data/ext/rb-grn-database.c +119 -5
- data/ext/rb-grn-encoding-support.c +64 -0
- data/ext/rb-grn-encoding.c +58 -1
- data/ext/rb-grn-fix-size-column.c +220 -0
- data/ext/rb-grn-hash-cursor.c +8 -0
- data/ext/rb-grn-hash.c +244 -2
- data/ext/rb-grn-index-column.c +474 -0
- data/ext/rb-grn-object.c +143 -265
- data/ext/rb-grn-patricia-trie.c +148 -2
- data/ext/rb-grn-query.c +5 -3
- data/ext/rb-grn-record.c +3 -2
- data/ext/rb-grn-snippet.c +5 -3
- data/ext/rb-grn-table-cursor-key-support.c +3 -3
- data/ext/rb-grn-table-cursor.c +106 -112
- data/ext/rb-grn-table-key-support.c +220 -118
- data/ext/rb-grn-table.c +336 -80
- data/ext/rb-grn-type.c +5 -4
- data/ext/rb-grn-utils.c +62 -63
- data/ext/rb-grn.h +215 -14
- data/ext/rb-groonga.c +7 -16
- data/extconf.rb +3 -1
- data/html/favicon.ico +0 -0
- data/html/favicon.xcf +0 -0
- data/html/index.html +1 -7
- data/lib/groonga/record.rb +6 -1
- data/test/groonga-test-utils.rb +1 -0
- data/test/test-array.rb +81 -0
- data/test/test-column.rb +22 -12
- data/test/test-context.rb +1 -29
- data/test/test-database.rb +30 -0
- data/test/test-hash.rb +194 -0
- data/test/test-index-column.rb +57 -0
- data/test/test-patricia-trie.rb +82 -0
- data/test/test-record.rb +10 -10
- data/test/test-table.rb +37 -130
- data/test/test-type.rb +4 -3
- metadata +15 -4
- 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
|
-
|
21
|
-
:persistent => persistent)
|
20
|
+
p items.define_column("title", "<text>", :persistent => persistent)
|
22
21
|
|
23
|
-
terms = Groonga::Hash.create(:name => "<terms>",
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
34
|
-
items
|
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
|
37
|
-
|
38
|
-
|
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
|
data/ext/rb-grn-array-cursor.c
CHANGED
@@ -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
|
-
*
|
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
|
-
*
|
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
|
-
*
|
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,
|
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
|
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
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
268
|
-
|
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
|
}
|