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
19uint32_t
20grn_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
40void
41grn_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
101int64_t *
102grn_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
121int64_t
122grn_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
136void
137grn_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
152int64_t *
153grn_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
176int64_t
177grn_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
191void
192grn_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
207int64_t *
208grn_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
234int64_t
235grn_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
249void
250grn_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
265double *
266grn_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
295double
296grn_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
310void
311grn_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