[Groonga-commit] groonga/groonga at 3b911cf [master] Support avg in drilldown

Back to archive index

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����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index