1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* Copyright(C) 2009-2015 Brazil |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License version 2.1 as published by the Free Software Foundation. |
7 | |
8 | This library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Lesser General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Lesser General Public |
14 | License along with this library; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
16 | */ |
17 | #include "grn_db.h" |
18 | |
19 | uint32_t |
20 | grn_rset_recinfo_calc_values_size(grn_ctx *ctx, grn_table_group_flags flags) |
21 | { |
22 | uint32_t size = 0; |
23 | |
24 | if (flags & GRN_TABLE_GROUP_CALC_MAX) { |
25 | size += GRN_RSET_MAX_SIZE; |
26 | } |
27 | if (flags & GRN_TABLE_GROUP_CALC_MIN) { |
28 | size += GRN_RSET_MIN_SIZE; |
29 | } |
30 | if (flags & GRN_TABLE_GROUP_CALC_SUM) { |
31 | size += GRN_RSET_SUM_SIZE; |
32 | } |
33 | if (flags & GRN_TABLE_GROUP_CALC_AVG) { |
34 | size += GRN_RSET_AVG_SIZE; |
35 | } |
36 | |
37 | return size; |
38 | } |
39 | |
40 | void |
41 | grn_rset_recinfo_update_calc_values(grn_ctx *ctx, |
42 | grn_rset_recinfo *ri, |
43 | grn_obj *table, |
44 | grn_obj *value) |
45 | { |
46 | grn_table_group_flags flags; |
47 | byte *values; |
48 | grn_obj value_int64; |
49 | grn_obj value_float; |
50 | |
51 | flags = DB_OBJ(table)->flags.group; |
52 | |
53 | values = (((byte *)ri->subrecs) + |
54 | GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, |
55 | DB_OBJ(table)->max_n_subrecs)); |
56 | |
57 | GRN_INT64_INIT(&value_int64, 0); |
58 | GRN_FLOAT_INIT(&value_float, 0); |
59 | |
60 | if (flags & (GRN_TABLE_GROUP_CALC_MAX | |
61 | GRN_TABLE_GROUP_CALC_MIN | |
62 | GRN_TABLE_GROUP_CALC_SUM)) { |
63 | grn_obj_cast(ctx, value, &value_int64, GRN_FALSE); |
64 | } |
65 | if (flags & GRN_TABLE_GROUP_CALC_AVG) { |
66 | grn_obj_cast(ctx, value, &value_float, GRN_FALSE); |
67 | } |
68 | |
69 | if (flags & GRN_TABLE_GROUP_CALC_MAX) { |
70 | int64_t current_max = *((int64_t *)values); |
71 | int64_t value_raw = GRN_INT64_VALUE(&value_int64); |
72 | if (ri->n_subrecs == 1 || value_raw > current_max) { |
73 | *((int64_t *)values) = value_raw; |
74 | } |
75 | values += GRN_RSET_MAX_SIZE; |
76 | } |
77 | if (flags & GRN_TABLE_GROUP_CALC_MIN) { |
78 | int64_t current_min = *((int64_t *)values); |
79 | int64_t value_raw = GRN_INT64_VALUE(&value_int64); |
80 | if (ri->n_subrecs == 1 || value_raw < current_min) { |
81 | *((int64_t *)values) = value_raw; |
82 | } |
83 | values += GRN_RSET_MIN_SIZE; |
84 | } |
85 | if (flags & GRN_TABLE_GROUP_CALC_SUM) { |
86 | int64_t value_raw = GRN_INT64_VALUE(&value_int64); |
87 | *((int64_t *)values) += value_raw; |
88 | values += GRN_RSET_SUM_SIZE; |
89 | } |
90 | if (flags & GRN_TABLE_GROUP_CALC_AVG) { |
91 | double current_average = *((double *)values); |
92 | double value_raw = GRN_FLOAT_VALUE(&value_float); |
93 | *((double *)values) += (value_raw - current_average) / ri->n_subrecs; |
94 | values += GRN_RSET_AVG_SIZE; |
95 | } |
96 | |
97 | GRN_OBJ_FIN(ctx, &value_float); |
98 | GRN_OBJ_FIN(ctx, &value_int64); |
99 | } |
100 | |
101 | int64_t * |
102 | grn_rset_recinfo_get_max_(grn_ctx *ctx, |
103 | grn_rset_recinfo *ri, |
104 | grn_obj *table) |
105 | { |
106 | grn_table_group_flags flags; |
107 | byte *values; |
108 | |
109 | flags = DB_OBJ(table)->flags.group; |
110 | if (!(flags & GRN_TABLE_GROUP_CALC_MAX)) { |
111 | return NULL; |
112 | } |
113 | |
114 | values = (((byte *)ri->subrecs) + |
115 | GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, |
116 | DB_OBJ(table)->max_n_subrecs)); |
117 | |
118 | return (int64_t *)values; |
119 | } |
120 | |
121 | int64_t |
122 | grn_rset_recinfo_get_max(grn_ctx *ctx, |
123 | grn_rset_recinfo *ri, |
124 | grn_obj *table) |
125 | { |
126 | int64_t *max_address; |
127 | |
128 | max_address = grn_rset_recinfo_get_max_(ctx, ri, table); |
129 | if (max_address) { |
130 | return *max_address; |
131 | } else { |
132 | return 0; |
133 | } |
134 | } |
135 | |
136 | void |
137 | grn_rset_recinfo_set_max(grn_ctx *ctx, |
138 | grn_rset_recinfo *ri, |
139 | grn_obj *table, |
140 | int64_t max) |
141 | { |
142 | int64_t *max_address; |
143 | |
144 | max_address = grn_rset_recinfo_get_max_(ctx, ri, table); |
145 | if (!max_address) { |
146 | return; |
147 | } |
148 | |
149 | *max_address = max; |
150 | } |
151 | |
152 | int64_t * |
153 | grn_rset_recinfo_get_min_(grn_ctx *ctx, |
154 | grn_rset_recinfo *ri, |
155 | grn_obj *table) |
156 | { |
157 | grn_table_group_flags flags; |
158 | byte *values; |
159 | |
160 | flags = DB_OBJ(table)->flags.group; |
161 | if (!(flags & GRN_TABLE_GROUP_CALC_MIN)) { |
162 | return NULL; |
163 | } |
164 | |
165 | values = (((byte *)ri->subrecs) + |
166 | GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, |
167 | DB_OBJ(table)->max_n_subrecs)); |
168 | |
169 | if (flags & GRN_TABLE_GROUP_CALC_MAX) { |
170 | values += GRN_RSET_MAX_SIZE; |
171 | } |
172 | |
173 | return (int64_t *)values; |
174 | } |
175 | |
176 | int64_t |
177 | grn_rset_recinfo_get_min(grn_ctx *ctx, |
178 | grn_rset_recinfo *ri, |
179 | grn_obj *table) |
180 | { |
181 | int64_t *min_address; |
182 | |
183 | min_address = grn_rset_recinfo_get_min_(ctx, ri, table); |
184 | if (min_address) { |
185 | return *min_address; |
186 | } else { |
187 | return 0; |
188 | } |
189 | } |
190 | |
191 | void |
192 | grn_rset_recinfo_set_min(grn_ctx *ctx, |
193 | grn_rset_recinfo *ri, |
194 | grn_obj *table, |
195 | int64_t min) |
196 | { |
197 | int64_t *min_address; |
198 | |
199 | min_address = grn_rset_recinfo_get_min_(ctx, ri, table); |
200 | if (!min_address) { |
201 | return; |
202 | } |
203 | |
204 | *min_address = min; |
205 | } |
206 | |
207 | int64_t * |
208 | grn_rset_recinfo_get_sum_(grn_ctx *ctx, |
209 | grn_rset_recinfo *ri, |
210 | grn_obj *table) |
211 | { |
212 | grn_table_group_flags flags; |
213 | byte *values; |
214 | |
215 | flags = DB_OBJ(table)->flags.group; |
216 | if (!(flags & GRN_TABLE_GROUP_CALC_SUM)) { |
217 | return NULL; |
218 | } |
219 | |
220 | values = (((byte *)ri->subrecs) + |
221 | GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, |
222 | DB_OBJ(table)->max_n_subrecs)); |
223 | |
224 | if (flags & GRN_TABLE_GROUP_CALC_MAX) { |
225 | values += GRN_RSET_MAX_SIZE; |
226 | } |
227 | if (flags & GRN_TABLE_GROUP_CALC_MIN) { |
228 | values += GRN_RSET_MIN_SIZE; |
229 | } |
230 | |
231 | return (int64_t *)values; |
232 | } |
233 | |
234 | int64_t |
235 | grn_rset_recinfo_get_sum(grn_ctx *ctx, |
236 | grn_rset_recinfo *ri, |
237 | grn_obj *table) |
238 | { |
239 | int64_t *sum_address; |
240 | |
241 | sum_address = grn_rset_recinfo_get_sum_(ctx, ri, table); |
242 | if (sum_address) { |
243 | return *sum_address; |
244 | } else { |
245 | return 0; |
246 | } |
247 | } |
248 | |
249 | void |
250 | grn_rset_recinfo_set_sum(grn_ctx *ctx, |
251 | grn_rset_recinfo *ri, |
252 | grn_obj *table, |
253 | int64_t sum) |
254 | { |
255 | int64_t *sum_address; |
256 | |
257 | sum_address = grn_rset_recinfo_get_sum_(ctx, ri, table); |
258 | if (!sum_address) { |
259 | return; |
260 | } |
261 | |
262 | *sum_address = sum; |
263 | } |
264 | |
265 | double * |
266 | grn_rset_recinfo_get_avg_(grn_ctx *ctx, |
267 | grn_rset_recinfo *ri, |
268 | grn_obj *table) |
269 | { |
270 | grn_table_group_flags flags; |
271 | byte *values; |
272 | |
273 | flags = DB_OBJ(table)->flags.group; |
274 | if (!(flags & GRN_TABLE_GROUP_CALC_AVG)) { |
275 | return NULL; |
276 | } |
277 | |
278 | values = (((byte *)ri->subrecs) + |
279 | GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, |
280 | DB_OBJ(table)->max_n_subrecs)); |
281 | |
282 | if (flags & GRN_TABLE_GROUP_CALC_MAX) { |
283 | values += GRN_RSET_MAX_SIZE; |
284 | } |
285 | if (flags & GRN_TABLE_GROUP_CALC_MIN) { |
286 | values += GRN_RSET_MIN_SIZE; |
287 | } |
288 | if (flags & GRN_TABLE_GROUP_CALC_SUM) { |
289 | values += GRN_RSET_SUM_SIZE; |
290 | } |
291 | |
292 | return (double *)values; |
293 | } |
294 | |
295 | double |
296 | grn_rset_recinfo_get_avg(grn_ctx *ctx, |
297 | grn_rset_recinfo *ri, |
298 | grn_obj *table) |
299 | { |
300 | double *avg_address; |
301 | |
302 | avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table); |
303 | if (avg_address) { |
304 | return *avg_address; |
305 | } else { |
306 | return 0; |
307 | } |
308 | } |
309 | |
310 | void |
311 | grn_rset_recinfo_set_avg(grn_ctx *ctx, |
312 | grn_rset_recinfo *ri, |
313 | grn_obj *table, |
314 | double avg) |
315 | { |
316 | double *avg_address; |
317 | |
318 | avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table); |
319 | if (!avg_address) { |
320 | return; |
321 | } |
322 | |
323 | *avg_address = avg; |
324 | } |
325 | |