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����������������������������...ダウンロード