Kouhei Sutou
null+****@clear*****
Mon Jan 19 18:56:43 JST 2015
Kouhei Sutou 2015-01-19 18:56:43 +0900 (Mon, 19 Jan 2015) New Revision: 3b911cf44cb196732bb871818750ad01b431afab https://github.com/groonga/groonga/commit/3b911cf44cb196732bb871818750ad01b431afab Message: Support avg in drilldown Added files: test/command/suite/select/drilldown/labeled/calc_types/avg.expected test/command/suite/select/drilldown/labeled/calc_types/avg.test Modified files: include/groonga/groonga.h lib/db.c lib/grn_db.h lib/grn_rset.h lib/output.c lib/rset.c Modified: include/groonga/groonga.h (+2 -0) =================================================================== --- include/groonga/groonga.h 2015-01-19 18:43:47 +0900 (b02785a) +++ include/groonga/groonga.h 2015-01-19 18:56:43 +0900 (3e89629) @@ -759,6 +759,8 @@ GRN_API unsigned int grn_table_size(grn_ctx *ctx, grn_obj *table); #define GRN_COLUMN_NAME_MIN_LEN (sizeof(GRN_COLUMN_NAME_MIN) - 1) #define GRN_COLUMN_NAME_SUM "_sum" #define GRN_COLUMN_NAME_SUM_LEN (sizeof(GRN_COLUMN_NAME_SUM) - 1) +#define GRN_COLUMN_NAME_AVG "_avg" +#define GRN_COLUMN_NAME_AVG_LEN (sizeof(GRN_COLUMN_NAME_AVG) - 1) GRN_API grn_obj *grn_column_create(grn_ctx *ctx, grn_obj *table, const char *name, unsigned int name_size, Modified: lib/db.c (+64 -0) =================================================================== --- lib/db.c 2015-01-19 18:43:47 +0900 (be82416) +++ lib/db.c 2015-01-19 18:56:43 +0900 (a62c381) @@ -4707,6 +4707,7 @@ grn_obj_get_accessor_rset_value(grn_ctx *ctx, grn_obj *obj, case GRN_ACCESSOR_GET_MAX : case GRN_ACCESSOR_GET_MIN : case GRN_ACCESSOR_GET_SUM : + case GRN_ACCESSOR_GET_AVG : case GRN_ACCESSOR_GET_NSUBRECS : if (GRN_TABLE_IS_GROUPED(obj)) { (*rp)->action = action; @@ -4768,6 +4769,7 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int case GRN_ACCESSOR_GET_MAX : case GRN_ACCESSOR_GET_MIN : case GRN_ACCESSOR_GET_SUM : + case GRN_ACCESSOR_GET_AVG : obj = grn_ctx_at(ctx, DB_OBJ(res->obj)->range); break; case GRN_ACCESSOR_GET_COLUMN_VALUE : @@ -4988,6 +4990,19 @@ grn_obj_get_accessor(grn_ctx *ctx, grn_obj *obj, const char *name, unsigned int goto exit; } break; + case 'a' : /* avg */ + if (len == GRN_COLUMN_NAME_AVG_LEN && + memcmp(name, + GRN_COLUMN_NAME_AVG, + GRN_COLUMN_NAME_AVG_LEN) == 0) { + if (!grn_obj_get_accessor_rset_value(ctx, obj, &res, + GRN_ACCESSOR_GET_AVG)) { + goto exit; + } + } else { + goto exit; + } + break; default : res = NULL; goto exit; @@ -5131,6 +5146,9 @@ grn_obj_get_range_info(grn_ctx *ctx, grn_obj *obj, case GRN_ACCESSOR_GET_SUM : *range_id = GRN_DB_INT64; break; + case GRN_ACCESSOR_GET_AVG : + *range_id = GRN_DB_FLOAT; + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : grn_obj_get_range_info(ctx, a->obj, range_id, range_flags); break; @@ -5171,6 +5189,7 @@ grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj) case GRN_ACCESSOR_GET_MAX : case GRN_ACCESSOR_GET_MIN : case GRN_ACCESSOR_GET_SUM : + case GRN_ACCESSOR_GET_AVG : res = 0; break; case GRN_ACCESSOR_GET_ID : @@ -5684,6 +5703,15 @@ grn_accessor_get_value_(grn_ctx *ctx, grn_accessor *a, grn_id id, uint32_t *size *size = GRN_RSET_SUM_SIZE; } break; + case GRN_ACCESSOR_GET_AVG : + if ((value = grn_obj_get_value_(ctx, a->obj, id, size))) { + value = + (const char *)grn_rset_recinfo_get_avg_(ctx, + (grn_rset_recinfo *)value, + a->obj); + *size = GRN_RSET_AVG_SIZE; + } + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : /* todo : support vector */ value = grn_obj_get_value_(ctx, a->obj, id, size); @@ -5810,6 +5838,17 @@ grn_accessor_get_value(grn_ctx *ctx, grn_accessor *a, grn_id id, grn_obj *value) } value->header.domain = GRN_DB_INT64; break; + case GRN_ACCESSOR_GET_AVG : + if (id) { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + double avg; + avg = grn_rset_recinfo_get_avg(ctx, ri, a->obj); + GRN_FLOAT_PUT(ctx, value, avg); + } else { + GRN_FLOAT_PUT(ctx, value, 0.0); + } + value->header.domain = GRN_DB_FLOAT; + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : /* todo : support vector */ grn_obj_get_value(ctx, a->obj, id, value); @@ -5949,6 +5988,23 @@ grn_accessor_set_value(grn_ctx *ctx, grn_accessor *a, grn_id id, } } break; + case GRN_ACCESSOR_GET_AVG : + grn_obj_get_value(ctx, a->obj, id, &buf); + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)GRN_BULK_HEAD(&buf); + if (value->header.type == GRN_DB_FLOAT) { + grn_rset_recinfo_set_avg(ctx, ri, a->obj, GRN_FLOAT_VALUE(value)); + } else { + grn_obj value_float; + GRN_FLOAT_INIT(&value_float, 0); + if (!grn_obj_cast(ctx, value, &value_float, GRN_FALSE)) { + grn_rset_recinfo_set_avg(ctx, ri, a->obj, + GRN_FLOAT_VALUE(&value_float)); + } + GRN_OBJ_FIN(ctx, &value_float); + } + } + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : /* todo : support vector */ if (a->next) { @@ -9283,6 +9339,9 @@ grn_column_name(grn_ctx *ctx, grn_obj *obj, char *namebuf, int buf_size) case GRN_ACCESSOR_GET_SUM : name = GRN_COLUMN_NAME_SUM; break; + case GRN_ACCESSOR_GET_AVG : + name = GRN_COLUMN_NAME_AVG; + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : case GRN_ACCESSOR_GET_DB_OBJ : case GRN_ACCESSOR_LOOKUP : @@ -9361,6 +9420,11 @@ grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf) GRN_COLUMN_NAME_SUM, GRN_COLUMN_NAME_SUM_LEN); break; + case GRN_ACCESSOR_GET_AVG : + GRN_TEXT_PUT(ctx, buf, + GRN_COLUMN_NAME_AVG, + GRN_COLUMN_NAME_AVG_LEN); + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : grn_column_name_(ctx, a->obj, buf); if (a->next) { GRN_TEXT_PUTC(ctx, buf, '.'); } Modified: lib/grn_db.h (+2 -1) =================================================================== --- lib/grn_db.h 2015-01-19 18:43:47 +0900 (ed027d7) +++ lib/grn_db.h 2015-01-19 18:56:43 +0900 (39eb010) @@ -1,5 +1,5 @@ /* -*- c-basic-offset: 2 -*- */ -/* Copyright(C) 2009-2013 Brazil +/* Copyright(C) 2009-2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -224,6 +224,7 @@ enum { GRN_ACCESSOR_GET_MAX, GRN_ACCESSOR_GET_MIN, GRN_ACCESSOR_GET_SUM, + GRN_ACCESSOR_GET_AVG, GRN_ACCESSOR_GET_COLUMN_VALUE, GRN_ACCESSOR_GET_DB_OBJ, GRN_ACCESSOR_LOOKUP, Modified: lib/grn_rset.h (+11 -0) =================================================================== --- lib/grn_rset.h 2015-01-19 18:43:47 +0900 (787eb5b) +++ lib/grn_rset.h 2015-01-19 18:56:43 +0900 (f3effc5) @@ -97,6 +97,17 @@ void grn_rset_recinfo_set_sum(grn_ctx *ctx, grn_obj *table, int64_t sum); +double *grn_rset_recinfo_get_avg_(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table); +double grn_rset_recinfo_get_avg(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table); +void grn_rset_recinfo_set_avg(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table, + double avg); + #ifdef __cplusplus } #endif Modified: lib/output.c (+9 -0) =================================================================== --- lib/output.c 2015-01-19 18:43:47 +0900 (2ae4632) +++ lib/output.c 2015-01-19 18:56:43 +0900 (9dc3147) @@ -560,6 +560,15 @@ grn_text_atoj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, } buf.header.domain = GRN_DB_INT64; break; + case GRN_ACCESSOR_GET_AVG : + { + grn_rset_recinfo *ri = (grn_rset_recinfo *)grn_obj_get_value_(ctx, a->obj, id, &vs); + double avg; + avg = grn_rset_recinfo_get_avg(ctx, ri, a->obj); + GRN_FLOAT_PUT(ctx, &buf, avg); + } + buf.header.domain = GRN_DB_FLOAT; + break; case GRN_ACCESSOR_GET_COLUMN_VALUE : if ((a->obj->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR) { if (a->next) { Modified: lib/rset.c (+62 -1) =================================================================== --- lib/rset.c 2015-01-19 18:43:47 +0900 (59e14a8) +++ lib/rset.c 2015-01-19 18:56:43 +0900 (85a9e1c) @@ -89,7 +89,7 @@ grn_rset_recinfo_update_calc_values(grn_ctx *ctx, } if (flags & GRN_TABLE_GROUP_CALC_AVG) { double current_average = *((double *)values); - int64_t value_raw = GRN_FLOAT_VALUE(&value_float); + double value_raw = GRN_FLOAT_VALUE(&value_float); *((double *)values) += (value_raw - current_average) / ri->n_subrecs; values += GRN_RSET_AVG_SIZE; } @@ -261,3 +261,64 @@ grn_rset_recinfo_set_sum(grn_ctx *ctx, *sum_address = sum; } + +double * +grn_rset_recinfo_get_avg_(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table) +{ + grn_table_group_flags flags; + byte *values; + + flags = DB_OBJ(table)->flags.group; + if (!(flags & GRN_TABLE_GROUP_CALC_AVG)) { + return NULL; + } + + values = (((byte *)ri->subrecs) + + GRN_RSET_SUBRECS_SIZE(DB_OBJ(table)->subrec_size, + DB_OBJ(table)->max_n_subrecs)); + + if (flags & GRN_TABLE_GROUP_CALC_MAX) { + values += GRN_RSET_MAX_SIZE; + } + if (flags & GRN_TABLE_GROUP_CALC_MIN) { + values += GRN_RSET_MIN_SIZE; + } + if (flags & GRN_TABLE_GROUP_CALC_SUM) { + values += GRN_RSET_SUM_SIZE; + } + + return (double *)values; +} + +double +grn_rset_recinfo_get_avg(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table) +{ + double *avg_address; + + avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table); + if (avg_address) { + return *avg_address; + } else { + return 0; + } +} + +void +grn_rset_recinfo_set_avg(grn_ctx *ctx, + grn_rset_recinfo *ri, + grn_obj *table, + double avg) +{ + double *avg_address; + + avg_address = grn_rset_recinfo_get_avg_(ctx, ri, table); + if (!avg_address) { + return; + } + + *avg_address = avg; +} Added: test/command/suite/select/drilldown/labeled/calc_types/avg.expected (+83 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/labeled/calc_types/avg.expected 2015-01-19 18:56:43 +0900 (1fcc60d) @@ -0,0 +1,83 @@ +table_create Tags TABLE_PAT_KEY ShortText +[[0,0.0,0.0],true] +table_create Memos TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Memos tag COLUMN_SCALAR Tags +[[0,0.0,0.0],true] +column_create Memos priority COLUMN_SCALAR Int64 +[[0,0.0,0.0],true] +load --table Memos +[ +{"_key": "Groonga1", "tag": "Groonga", "priority": 10}, +{"_key": "Groonga2", "tag": "Groonga", "priority": 20}, +{"_key": "Groonga3", "tag": "Groonga", "priority": 60}, +{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61}, +{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24}, +{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8}, +{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3}, +{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9}, +{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0} +] +[[0,0.0,0.0],9] +select Memos --limit 0 --drilldown[tag].keys tag --drilldown[tag].calc_types AVG --drilldown[tag].calc_target priority --drilldown[tag].output_columns _key,_avg +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 9 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "priority", + "Int64" + ], + [ + "tag", + "Tags" + ] + ] + ], + { + "tag": [ + [ + 3 + ], + [ + [ + "_key", + "ShortText" + ], + [ + "_avg", + "Float" + ] + ], + [ + "Groonga", + 30.0 + ], + [ + "Mroonga", + 31.0 + ], + [ + "Rroonga", + -2.0 + ] + ] + } + ] +] Added: test/command/suite/select/drilldown/labeled/calc_types/avg.test (+25 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/drilldown/labeled/calc_types/avg.test 2015-01-19 18:56:43 +0900 (cc8d5cd) @@ -0,0 +1,25 @@ +table_create Tags TABLE_PAT_KEY ShortText + +table_create Memos TABLE_HASH_KEY ShortText +column_create Memos tag COLUMN_SCALAR Tags +column_create Memos priority COLUMN_SCALAR Int64 + +load --table Memos +[ +{"_key": "Groonga1", "tag": "Groonga", "priority": 10}, +{"_key": "Groonga2", "tag": "Groonga", "priority": 20}, +{"_key": "Groonga3", "tag": "Groonga", "priority": 60}, +{"_key": "Mroonga1", "tag": "Mroonga", "priority": 61}, +{"_key": "Mroonga2", "tag": "Mroonga", "priority": 24}, +{"_key": "Mroonga3", "tag": "Mroonga", "priority": 8}, +{"_key": "Rroonga1", "tag": "Rroonga", "priority": 3}, +{"_key": "Rroonga2", "tag": "Rroonga", "priority": -9}, +{"_key": "Rroonga3", "tag": "Rroonga", "priority": 0} +] + +select Memos \ + --limit 0 \ + --drilldown[tag].keys tag \ + --drilldown[tag].calc_types AVG \ + --drilldown[tag].calc_target priority \ + --drilldown[tag].output_columns _key,_avg -------------- next part -------------- HTML����������������������������...下載