Navigation Menu

Skip to content

Commit

Permalink
Support avg in drilldown
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Jan 19, 2015
1 parent c3cf8b8 commit 3b911cf
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/groonga/groonga.h
Expand Up @@ -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,
Expand Down
64 changes: 64 additions & 0 deletions lib/db.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 :
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 :
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 :
Expand Down Expand Up @@ -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, '.'); }
Expand Down
3 changes: 2 additions & 1 deletion lib/grn_db.h
@@ -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
Expand Down Expand Up @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions lib/grn_rset.h
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions lib/output.c
Expand Up @@ -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) {
Expand Down
63 changes: 62 additions & 1 deletion lib/rset.c
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
@@ -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
]
]
}
]
]
25 changes: 25 additions & 0 deletions test/command/suite/select/drilldown/labeled/calc_types/avg.test
@@ -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

0 comments on commit 3b911cf

Please sign in to comment.