1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2014-2015 Brazil
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 "../grn_ctx_impl.h"
20#include "../grn_ii.h"
21#include <string.h>
22
23#ifdef GRN_WITH_MRUBY
24#include <mruby.h>
25#include <mruby/array.h>
26#include <mruby/class.h>
27#include <mruby/data.h>
28
29#include "mrb_ctx.h"
30#include "mrb_converter.h"
31#include "mrb_index_column.h"
32#include "mrb_operator.h"
33#include "mrb_options.h"
34
35static struct mrb_data_type mrb_grn_index_column_type = {
36 "Groonga::IndexColumn",
37 NULL
38};
39
40static mrb_value
41mrb_grn_index_column_initialize(mrb_state *mrb, mrb_value self)
42{
43 mrb_value mrb_index_column_ptr;
44
45 mrb_get_args(mrb, "o", &mrb_index_column_ptr);
46 DATA_TYPE(self) = &mrb_grn_index_column_type;
47 DATA_PTR(self) = mrb_cptr(mrb_index_column_ptr);
48 return self;
49}
50
51static mrb_value
52mrb_grn_index_column_get_lexicon(mrb_state *mrb, mrb_value self)
53{
54 grn_obj *index_column;
55 grn_obj *lexicon;
56
57 index_column = DATA_PTR(self);
58 lexicon = ((grn_ii *)index_column)->lexicon;
59
60 return grn_mrb_value_from_grn_obj(mrb, lexicon);
61}
62
63static mrb_value
64mrb_grn_index_column_get_source_ids(mrb_state *mrb, mrb_value self)
65{
66 grn_ctx *ctx = (grn_ctx *)mrb->ud;
67 grn_obj *index_column;
68 grn_obj source_ids;
69 unsigned int i, n_ids;
70 mrb_value mrb_source_ids;
71
72 index_column = DATA_PTR(self);
73 GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_DB_VOID);
74 grn_obj_get_info(ctx, index_column, GRN_INFO_SOURCE, &source_ids);
75 n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id);
76
77 mrb_source_ids = mrb_ary_new_capa(mrb, n_ids);
78 for (i = 0; i < n_ids; i++) {
79 grn_id source_id = GRN_RECORD_VALUE_AT(&source_ids, i);
80 mrb_ary_push(mrb, mrb_source_ids, mrb_fixnum_value(source_id));
81 }
82
83 GRN_OBJ_FIN(ctx, &source_ids);
84
85 return mrb_source_ids;
86}
87
88static mrb_value
89mrb_grn_index_column_estimate_size_for_term_id(mrb_state *mrb, mrb_value self)
90{
91 grn_ctx *ctx = (grn_ctx *)mrb->ud;
92 grn_obj *index_column;
93 mrb_int term_id;
94 unsigned int size;
95
96 index_column = DATA_PTR(self);
97 mrb_get_args(mrb, "i", &term_id);
98
99 size = grn_ii_estimate_size(ctx, (grn_ii *)index_column, term_id);
100 return mrb_fixnum_value(size);
101}
102
103static mrb_value
104mrb_grn_index_column_estimate_size_for_query(mrb_state *mrb, mrb_value self)
105{
106 grn_ctx *ctx = (grn_ctx *)mrb->ud;
107 grn_obj *index_column;
108 grn_obj *lexicon;
109 mrb_value mrb_query;
110 void *query;
111 unsigned int query_size;
112 grn_mrb_value_to_raw_data_buffer buffer;
113 mrb_value mrb_options = mrb_nil_value();
114 grn_search_optarg optarg;
115 unsigned int size;
116
117 index_column = DATA_PTR(self);
118 mrb_get_args(mrb, "o|H", &mrb_query, &mrb_options);
119
120 lexicon = grn_ctx_at(ctx, index_column->header.domain);
121 grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
122 grn_mrb_value_to_raw_data(mrb, "query", mrb_query, lexicon->header.domain,
123 &buffer, &query, &query_size);
124
125 memset(&optarg, 0, sizeof(grn_search_optarg));
126 optarg.mode = GRN_OP_EXACT;
127
128 if (!mrb_nil_p(mrb_options)) {
129 mrb_value mrb_mode;
130
131 mrb_mode = grn_mrb_options_get_lit(mrb, mrb_options, "mode");
132 if (!mrb_nil_p(mrb_mode)) {
133 optarg.mode = grn_mrb_value_to_operator(mrb, mrb_mode);
134 }
135 }
136
137 size = grn_ii_estimate_size_for_query(ctx, (grn_ii *)index_column,
138 query, query_size, &optarg);
139 grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
140
141 grn_mrb_ctx_check(mrb);
142
143 return mrb_fixnum_value(size);
144}
145
146static mrb_value
147mrb_grn_index_column_estimate_size_for_lexicon_cursor(mrb_state *mrb,
148 mrb_value self)
149{
150 grn_ctx *ctx = (grn_ctx *)mrb->ud;
151 grn_obj *index_column;
152 mrb_value mrb_lexicon_cursor;
153 grn_table_cursor *lexicon_cursor;
154 unsigned int size;
155
156 index_column = DATA_PTR(self);
157 mrb_get_args(mrb, "o", &mrb_lexicon_cursor);
158
159 lexicon_cursor = DATA_PTR(mrb_lexicon_cursor);
160 size = grn_ii_estimate_size_for_lexicon_cursor(ctx,
161 (grn_ii *)index_column,
162 lexicon_cursor);
163 return mrb_fixnum_value(size);
164}
165
166void
167grn_mrb_index_column_init(grn_ctx *ctx)
168{
169 grn_mrb_data *data = &(ctx->impl->mrb);
170 mrb_state *mrb = data->state;
171 struct RClass *module = data->module;
172 struct RClass *column_class;
173 struct RClass *klass;
174
175 column_class = mrb_class_get_under(mrb, module, "Column");
176 klass = mrb_define_class_under(mrb, module, "IndexColumn", column_class);
177 MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
178 mrb_define_method(mrb, klass, "initialize",
179 mrb_grn_index_column_initialize, MRB_ARGS_REQ(1));
180
181 mrb_define_method(mrb, klass, "lexicon",
182 mrb_grn_index_column_get_lexicon,
183 MRB_ARGS_NONE());
184
185 mrb_define_method(mrb, klass, "source_ids",
186 mrb_grn_index_column_get_source_ids,
187 MRB_ARGS_NONE());
188
189 mrb_define_method(mrb, klass, "estimate_size_for_term_id",
190 mrb_grn_index_column_estimate_size_for_term_id,
191 MRB_ARGS_REQ(1));
192 mrb_define_method(mrb, klass, "estimate_size_for_query",
193 mrb_grn_index_column_estimate_size_for_query,
194 MRB_ARGS_ARG(1, 1));
195 mrb_define_method(mrb, klass, "estimate_size_for_lexicon_cursor",
196 mrb_grn_index_column_estimate_size_for_lexicon_cursor,
197 MRB_ARGS_REQ(1));
198}
199#endif
200