[Groonga-commit] groonga/groonga at a25659e [master] functions/number: add a new plugin

アーカイブの一覧に戻る

Kouhei Sutou null+****@clear*****
Thu May 5 16:35:15 JST 2016


Kouhei Sutou	2016-05-05 16:35:15 +0900 (Thu, 05 May 2016)

  New Revision: a25659e2fc043d1b9e81e5de435c17955f59afb1
  https://github.com/groonga/groonga/commit/a25659e2fc043d1b9e81e5de435c17955f59afb1

  Message:
    functions/number: add a new plugin
    
    Add number_classify(). It computes class of number data.

  Added files:
    plugins/functions/number.c
    plugins/functions/number_sources.am
    test/command/suite/select/function/number/number_classify/float.expected
    test/command/suite/select/function/number/number_classify/float.test
    test/command/suite/select/function/number/number_classify/int32.expected
    test/command/suite/select/function/number/number_classify/int32.test
    test/command/suite/select/function/number/number_classify/uint32.expected
    test/command/suite/select/function/number/number_classify/uint32.test
  Modified files:
    plugins/functions/CMakeLists.txt
    plugins/functions/Makefile.am

  Modified: plugins/functions/CMakeLists.txt (+21 -1)
===================================================================
--- plugins/functions/CMakeLists.txt    2016-05-05 16:05:11 +0900 (59cf6f0)
+++ plugins/functions/CMakeLists.txt    2016-05-05 16:35:15 +0900 (b339aa5)
@@ -1,4 +1,4 @@
-# Copyright(C) 2015 Brazil
+# Copyright(C) 2015-2016 Brazil
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -58,3 +58,23 @@ else()
   install(TARGETS string_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
 endif()
 target_link_libraries(string_functions libgroonga)
+
+read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/number_sources.am
+  VECTOR_SOURCES)
+set_source_files_properties(${VECTOR_SOURCES}
+  PROPERTIES
+  COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}")
+if(GRN_EMBED)
+  add_library(number_functions STATIC ${VECTOR_SOURCES})
+  set_target_properties(
+    number_functions
+    PROPERTIES
+    POSITION_INDEPENDENT_CODE ON)
+else()
+  add_library(number_functions MODULE ${VECTOR_SOURCES})
+  set_target_properties(number_functions PROPERTIES
+    PREFIX ""
+    OUTPUT_NAME "number")
+  install(TARGETS number_functions DESTINATION "${GRN_FUNCTIONS_PLUGIN_DIR}")
+endif()
+target_link_libraries(number_functions libgroonga)

  Modified: plugins/functions/Makefile.am (+2 -0)
===================================================================
--- plugins/functions/Makefile.am    2016-05-05 16:05:11 +0900 (a76cd01)
+++ plugins/functions/Makefile.am    2016-05-05 16:35:15 +0900 (f385ce5)
@@ -17,6 +17,8 @@ LIBS =						\
 function_plugins_LTLIBRARIES =
 function_plugins_LTLIBRARIES += vector.la
 function_plugins_LTLIBRARIES += string.la
+function_plugins_LTLIBRARIES += number.la
 
 include vector_sources.am
 include string_sources.am
+include number_sources.am

  Added: plugins/functions/number.c (+187 -0) 100644
===================================================================
--- /dev/null
+++ plugins/functions/number.c    2016-05-05 16:35:15 +0900 (285c88f)
@@ -0,0 +1,187 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2016 Brazil
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License version 2.1 as published by the Free Software Foundation.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifdef GRN_EMBEDDED
+#  define GRN_PLUGIN_FUNCTION_TAG functions_number
+#endif
+
+#include <groonga/plugin.h>
+
+#include <math.h>
+
+static grn_obj *
+func_number_classify(grn_ctx *ctx, int n_args, grn_obj **args,
+                     grn_user_data *user_data)
+{
+  grn_obj *number;
+  grn_obj *interval;
+  grn_obj casted_interval;
+  grn_obj *classed_number;
+
+  if (n_args != 2) {
+    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                     "number_classify(): wrong number of arguments (%d for 2)",
+                     n_args);
+    return NULL;
+  }
+
+  number = args[0];
+  if (!(number->header.type == GRN_BULK &&
+        grn_type_id_is_number_family(ctx, number->header.domain))) {
+    grn_obj inspected;
+
+    GRN_TEXT_INIT(&inspected, 0);
+    grn_inspect(ctx, &inspected, number);
+    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                     "number_classify(): the first argument must be a number: "
+                     "<%.*s>",
+                     (int)GRN_TEXT_LEN(&inspected),
+                     GRN_TEXT_VALUE(&inspected));
+    GRN_OBJ_FIN(ctx, &inspected);
+    return NULL;
+  }
+
+  interval = args[1];
+  if (!(interval->header.type == GRN_BULK &&
+        grn_type_id_is_number_family(ctx, interval->header.domain))) {
+    grn_obj inspected;
+
+    GRN_TEXT_INIT(&inspected, 0);
+    grn_inspect(ctx, &inspected, interval);
+    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
+                     "number_classify(): the second argument must be a number: "
+                     "<%.*s>",
+                     (int)GRN_TEXT_LEN(&inspected),
+                     GRN_TEXT_VALUE(&inspected));
+    GRN_OBJ_FIN(ctx, &inspected);
+    return NULL;
+  }
+
+  classed_number = grn_plugin_proc_alloc(ctx,
+                                         user_data,
+                                         number->header.domain,
+                                         0);
+  if (!classed_number) {
+    return NULL;
+  }
+
+  GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, number->header.domain);
+  grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE);
+
+#define CLASSIFY_RAW(type, getter, setter, classifier) {                \
+    type number_raw;                                                    \
+    type interval_raw;                                                  \
+    type class_raw;                                                     \
+    type classed_number_raw;                                            \
+                                                                        \
+    number_raw = getter(number);                                        \
+    interval_raw = getter(&casted_interval);                            \
+    class_raw = classifier(number_raw, interval_raw);                   \
+    classed_number_raw = class_raw * interval_raw;                      \
+    setter(ctx, classed_number, classed_number_raw);                    \
+  }
+
+#define CLASSIFIER_INT(number_raw, interval_raw)        \
+  (number_raw) < 0 ?                                    \
+    ((((number_raw) + 1) / (interval_raw)) - 1) :       \
+    (((number_raw) / (interval_raw)))
+
+#define CLASSIFY_INT(type, getter, setter)              \
+  CLASSIFY_RAW(type, getter, setter, CLASSIFIER_INT)
+
+#define CLASSIFIER_UINT(number_raw, interval_raw)       \
+  ((number_raw) / (interval_raw))
+
+#define CLASSIFY_UINT(type, getter, setter)             \
+  CLASSIFY_RAW(type, getter, setter, CLASSIFIER_UINT)
+
+#define CLASSIFIER_FLOAT(number_raw, interval_raw)      \
+  floor((number_raw) / (interval_raw))
+
+#define CLASSIFY_FLOAT(getter, setter)                          \
+  CLASSIFY_RAW(double, getter, setter, CLASSIFIER_FLOAT)
+
+  switch (number->header.domain) {
+  case GRN_DB_INT8 :
+    CLASSIFY_INT(int8_t, GRN_INT8_VALUE, GRN_INT8_SET);
+    break;
+  case GRN_DB_UINT8 :
+    CLASSIFY_UINT(uint8_t, GRN_UINT8_VALUE, GRN_UINT8_SET);
+    break;
+  case GRN_DB_INT16 :
+    CLASSIFY_INT(int16_t, GRN_INT16_VALUE, GRN_INT16_SET);
+    break;
+  case GRN_DB_UINT16 :
+    CLASSIFY_UINT(uint16_t, GRN_UINT16_VALUE, GRN_UINT16_SET);
+    break;
+  case GRN_DB_INT32 :
+    CLASSIFY_INT(int32_t, GRN_INT32_VALUE, GRN_INT32_SET);
+    break;
+  case GRN_DB_UINT32 :
+    CLASSIFY_UINT(uint32_t, GRN_UINT32_VALUE, GRN_UINT32_SET);
+    break;
+  case GRN_DB_INT64 :
+    CLASSIFY_INT(int64_t, GRN_INT64_VALUE, GRN_INT64_SET);
+    break;
+  case GRN_DB_UINT64 :
+    CLASSIFY_UINT(uint64_t, GRN_UINT64_VALUE, GRN_UINT64_SET);
+    break;
+  case GRN_DB_FLOAT :
+    CLASSIFY_FLOAT(GRN_FLOAT_VALUE, GRN_FLOAT_SET);
+    break;
+  default :
+    break;
+  }
+#undef CLASSIFY_FLOAT
+#undef CLASSIFIER_FLAOT
+#undef CLASSIFY_UINT
+#undef CLASSIFIER_UINT
+#undef CLASSIFY_INT
+#undef CLASSIFIER_INT
+#undef CLASSIFY_RAW
+
+  GRN_OBJ_FIN(ctx, &casted_interval);
+
+  return classed_number;
+}
+
+grn_rc
+GRN_PLUGIN_INIT(grn_ctx *ctx)
+{
+  return ctx->rc;
+}
+
+grn_rc
+GRN_PLUGIN_REGISTER(grn_ctx *ctx)
+{
+  grn_rc rc = GRN_SUCCESS;
+
+  grn_proc_create(ctx,
+                  "number_classify", -1,
+                  GRN_PROC_FUNCTION,
+                  func_number_classify,
+                  NULL, NULL, 0, NULL);
+
+  return rc;
+}
+
+grn_rc
+GRN_PLUGIN_FIN(grn_ctx *ctx)
+{
+  return GRN_SUCCESS;
+}

  Added: plugins/functions/number_sources.am (+2 -0) 100644
===================================================================
--- /dev/null
+++ plugins/functions/number_sources.am    2016-05-05 16:35:15 +0900 (b3d9483)
@@ -0,0 +1,2 @@
+number_la_SOURCES =				\
+	number.c

  Added: test/command/suite/select/function/number/number_classify/float.expected (+108 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/float.expected    2016-05-05 16:35:15 +0900 (e6907f8)
@@ -0,0 +1,108 @@
+plugin_register functions/number
+[[0,0.0,0.0],true]
+table_create Prices TABLE_PAT_KEY Float
+[[0,0.0,0.0],true]
+load --table Prices
+[
+{"_key": -200.5},
+{"_key": -200},
+{"_key": -199.5},
+{"_key": -100.5},
+{"_key": -100},
+{"_key": -99.5},
+{"_key": -0.5},
+{"_key": 0.0},
+{"_key": 0.5},
+{"_key": 99.5},
+{"_key": 100},
+{"_key": 100.5},
+{"_key": 199.5},
+{"_key": 200},
+{"_key": 200.5}
+]
+[[0,0.0,0.0],15]
+select Prices   --sortby _id   --limit -1   --output_columns '_key, number_classify(_key, 100)'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        15
+      ],
+      [
+        [
+          "_key",
+          "Float"
+        ],
+        [
+          "number_classify",
+          "null"
+        ]
+      ],
+      [
+        -200.5,
+        -300.0
+      ],
+      [
+        -200.0,
+        -200.0
+      ],
+      [
+        -199.5,
+        -200.0
+      ],
+      [
+        -100.5,
+        -200.0
+      ],
+      [
+        -100.0,
+        -100.0
+      ],
+      [
+        -99.5,
+        -100.0
+      ],
+      [
+        -0.5,
+        -100.0
+      ],
+      [
+        0.0,
+        0.0
+      ],
+      [
+        0.5,
+        0.0
+      ],
+      [
+        99.5,
+        0.0
+      ],
+      [
+        100.0,
+        100.0
+      ],
+      [
+        100.5,
+        100.0
+      ],
+      [
+        199.5,
+        100.0
+      ],
+      [
+        200.0,
+        200.0
+      ],
+      [
+        200.5,
+        200.0
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/number/number_classify/float.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/float.test    2016-05-05 16:35:15 +0900 (a4ec921)
@@ -0,0 +1,27 @@
+plugin_register functions/number
+
+table_create Prices TABLE_PAT_KEY Float
+
+load --table Prices
+[
+{"_key": -200.5},
+{"_key": -200},
+{"_key": -199.5},
+{"_key": -100.5},
+{"_key": -100},
+{"_key": -99.5},
+{"_key": -0.5},
+{"_key": 0.0},
+{"_key": 0.5},
+{"_key": 99.5},
+{"_key": 100},
+{"_key": 100.5},
+{"_key": 199.5},
+{"_key": 200},
+{"_key": 200.5}
+]
+
+select Prices \
+  --sortby _id \
+  --limit -1 \
+  --output_columns '_key, number_classify(_key, 100)'

  Added: test/command/suite/select/function/number/number_classify/int32.expected (+108 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/int32.expected    2016-05-05 16:35:15 +0900 (5682b4b)
@@ -0,0 +1,108 @@
+plugin_register functions/number
+[[0,0.0,0.0],true]
+table_create Prices TABLE_PAT_KEY Int32
+[[0,0.0,0.0],true]
+load --table Prices
+[
+{"_key": -201},
+{"_key": -200},
+{"_key": -199},
+{"_key": -101},
+{"_key": -100},
+{"_key": -99},
+{"_key": -1},
+{"_key": 0},
+{"_key": 1},
+{"_key": 99},
+{"_key": 100},
+{"_key": 101},
+{"_key": 199},
+{"_key": 200},
+{"_key": 201}
+]
+[[0,0.0,0.0],15]
+select Prices   --sortby _id   --limit -1   --output_columns '_key, number_classify(_key, 100)'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        15
+      ],
+      [
+        [
+          "_key",
+          "Int32"
+        ],
+        [
+          "number_classify",
+          "null"
+        ]
+      ],
+      [
+        -201,
+        -300
+      ],
+      [
+        -200,
+        -200
+      ],
+      [
+        -199,
+        -200
+      ],
+      [
+        -101,
+        -200
+      ],
+      [
+        -100,
+        -100
+      ],
+      [
+        -99,
+        -100
+      ],
+      [
+        -1,
+        -100
+      ],
+      [
+        0,
+        0
+      ],
+      [
+        1,
+        0
+      ],
+      [
+        99,
+        0
+      ],
+      [
+        100,
+        100
+      ],
+      [
+        101,
+        100
+      ],
+      [
+        199,
+        100
+      ],
+      [
+        200,
+        200
+      ],
+      [
+        201,
+        200
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/number/number_classify/int32.test (+27 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/int32.test    2016-05-05 16:35:15 +0900 (f18aa04)
@@ -0,0 +1,27 @@
+plugin_register functions/number
+
+table_create Prices TABLE_PAT_KEY Int32
+
+load --table Prices
+[
+{"_key": -201},
+{"_key": -200},
+{"_key": -199},
+{"_key": -101},
+{"_key": -100},
+{"_key": -99},
+{"_key": -1},
+{"_key": 0},
+{"_key": 1},
+{"_key": 99},
+{"_key": 100},
+{"_key": 101},
+{"_key": 199},
+{"_key": 200},
+{"_key": 201}
+]
+
+select Prices \
+  --sortby _id \
+  --limit -1 \
+  --output_columns '_key, number_classify(_key, 100)'

  Added: test/command/suite/select/function/number/number_classify/uint32.expected (+73 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/uint32.expected    2016-05-05 16:35:15 +0900 (86cc2bc)
@@ -0,0 +1,73 @@
+plugin_register functions/number
+[[0,0.0,0.0],true]
+table_create Prices TABLE_PAT_KEY UInt32
+[[0,0.0,0.0],true]
+load --table Prices
+[
+{"_key": 0},
+{"_key": 1},
+{"_key": 99},
+{"_key": 100},
+{"_key": 101},
+{"_key": 199},
+{"_key": 200},
+{"_key": 201}
+]
+[[0,0.0,0.0],8]
+select Prices   --sortby _id   --limit -1   --output_columns '_key, number_classify(_key, 100)'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        8
+      ],
+      [
+        [
+          "_key",
+          "UInt32"
+        ],
+        [
+          "number_classify",
+          "null"
+        ]
+      ],
+      [
+        0,
+        0
+      ],
+      [
+        1,
+        0
+      ],
+      [
+        99,
+        0
+      ],
+      [
+        100,
+        100
+      ],
+      [
+        101,
+        100
+      ],
+      [
+        199,
+        100
+      ],
+      [
+        200,
+        200
+      ],
+      [
+        201,
+        200
+      ]
+    ]
+  ]
+]

  Added: test/command/suite/select/function/number/number_classify/uint32.test (+20 -0) 100644
===================================================================
--- /dev/null
+++ test/command/suite/select/function/number/number_classify/uint32.test    2016-05-05 16:35:15 +0900 (69f3bed)
@@ -0,0 +1,20 @@
+plugin_register functions/number
+
+table_create Prices TABLE_PAT_KEY UInt32
+
+load --table Prices
+[
+{"_key": 0},
+{"_key": 1},
+{"_key": 99},
+{"_key": 100},
+{"_key": 101},
+{"_key": 199},
+{"_key": 200},
+{"_key": 201}
+]
+
+select Prices \
+  --sortby _id \
+  --limit -1 \
+  --output_columns '_key, number_classify(_key, 100)'
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る