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-1335 USA
16 */
17 #include "grn_db.h"
18
19 uint32_t
grn_rset_recinfo_calc_values_size(grn_ctx * ctx,grn_table_group_flags flags)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
grn_rset_recinfo_update_calc_values(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table,grn_obj * value)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 *
grn_rset_recinfo_get_max_(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_get_max(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_set_max(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table,int64_t max)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 *
grn_rset_recinfo_get_min_(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_get_min(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_set_min(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table,int64_t min)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 *
grn_rset_recinfo_get_sum_(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_get_sum(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_set_sum(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table,int64_t sum)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 *
grn_rset_recinfo_get_avg_(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_get_avg(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table)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
grn_rset_recinfo_set_avg(grn_ctx * ctx,grn_rset_recinfo * ri,grn_obj * table,double avg)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