Kouhei Sutou
null+****@clear*****
Mon Jun 5 16:47:46 JST 2017
Kouhei Sutou 2017-06-05 16:47:46 +0900 (Mon, 05 Jun 2017) New Revision: 4eaaca6cd59f9ef79ac818b624859cee4f5e9d5a https://github.com/groonga/groonga/commit/4eaaca6cd59f9ef79ac818b624859cee4f5e9d5a Message: in_records: support only once initialization execution flow It just improve performance a bit... Modified files: lib/proc/proc_in_records.c Modified: lib/proc/proc_in_records.c (+215 -133) =================================================================== --- lib/proc/proc_in_records.c 2017-06-05 16:44:43 +0900 (308655d) +++ lib/proc/proc_in_records.c 2017-06-05 16:47:46 +0900 (a1fc2b5) @@ -17,44 +17,87 @@ */ #include "../grn_proc.h" +#include "../grn_db.h" #include <groonga/plugin.h> +typedef struct { + int n_conditions; + grn_obj *condition_table; + grn_obj condition_columns; + grn_operator_exec_func **condition_functions; +} grn_in_records_data; + +static void +grn_in_records_data_free(grn_ctx *ctx, grn_in_records_data *data) +{ + int i; + + if (!data) { + return; + } + + GRN_PLUGIN_FREE(ctx, data->condition_functions); + + for (i = 0; i < data->n_conditions; i++) { + grn_obj *condition_column; + condition_column = GRN_PTR_VALUE_AT(&(data->condition_columns), i); + if (condition_column && condition_column->header.type == GRN_ACCESSOR) { + grn_obj_unlink(ctx, condition_column); + } + } + GRN_OBJ_FIN(ctx, &(data->condition_columns)); + + GRN_PLUGIN_FREE(ctx, data); +} + static grn_obj * -func_in_records(grn_ctx *ctx, - int n_args, - grn_obj **args, - grn_user_data *user_data) +func_in_records_init(grn_ctx *ctx, + int n_args, + grn_obj **args, + grn_user_data *user_data) { - grn_obj *found; + grn_in_records_data *data; grn_obj *condition_table; - grn_obj condition_columns; - grn_operator_exec_func **condition_functions = NULL; + grn_expr_code *codes; + int n_arg_codes; + int n_logical_args; + int n_conditions; int i; + int nth; - found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0); - if (!found) { - return NULL; + { + grn_obj *caller; + grn_expr *expr; + grn_expr_code *call_code; + + caller = grn_plugin_proc_get_caller(ctx, user_data); + expr = (grn_expr *)caller; + call_code = expr->codes + expr->codes_curr - 1; + n_logical_args = call_code->nargs - 1; + codes = expr->codes + 1; + n_arg_codes = expr->codes_curr - 2; } - GRN_BOOL_SET(ctx, found, GRN_FALSE); - if (n_args < 4) { + if (n_logical_args < 4) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "in_records(): wrong number of arguments (%d for 4..)", - n_args); - return found; + n_logical_args); + return NULL; } - if ((n_args % 3) != 1) { + if ((n_logical_args % 3) != 1) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "in_records(): the number of arguments must be 1 + 3n (%d)", - n_args); - return found; + n_logical_args); + return NULL; } - condition_table = args[0]; + n_conditions = (n_logical_args - 1) / 3; + + condition_table = codes[0].value; if (!grn_obj_is_table(ctx, condition_table)) { grn_obj inspected; GRN_TEXT_INIT(&inspected, 0); @@ -65,64 +108,31 @@ func_in_records(grn_ctx *ctx, (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); GRN_OBJ_FIN(ctx, &inspected); - return found; + return NULL; } - GRN_PTR_INIT(&condition_columns, GRN_OBJ_VECTOR, GRN_ID_NIL); - for (i = 1; i < n_args; i += 3) { - int column_name_i = i + 2; - grn_obj *column_name; - grn_obj *condition_column; - - column_name = args[column_name_i]; - if (!grn_obj_is_text_family_bulk(ctx, column_name)) { - grn_obj inspected; - GRN_TEXT_INIT(&inspected, 0); - grn_inspect(ctx, &inspected, condition_table); - GRN_PLUGIN_ERROR(ctx, - GRN_INVALID_ARGUMENT, - "in_records(): " - "the %dth argument must be column name as string: " - "<%.*s>", - column_name_i, - (int)GRN_TEXT_LEN(&inspected), - GRN_TEXT_VALUE(&inspected)); - GRN_OBJ_FIN(ctx, &inspected); - goto exit; - } + data = GRN_PLUGIN_CALLOC(ctx, sizeof(grn_in_records_data)); + user_data->ptr = data; - condition_column = grn_obj_column(ctx, condition_table, - GRN_TEXT_VALUE(column_name), - GRN_TEXT_LEN(column_name)); - if (!condition_column) { - grn_obj inspected; - GRN_TEXT_INIT(&inspected, 0); - grn_inspect(ctx, &inspected, condition_table); - GRN_PLUGIN_ERROR(ctx, - GRN_INVALID_ARGUMENT, - "in_records(): " - "the %dth argument must be existing column name: " - "<%.*s>: <%.*s>", - column_name_i, - (int)GRN_TEXT_LEN(column_name), - GRN_TEXT_VALUE(column_name), - (int)GRN_TEXT_LEN(&inspected), - GRN_TEXT_VALUE(&inspected)); - GRN_OBJ_FIN(ctx, &inspected); - goto exit; - } - GRN_PTR_PUT(ctx, &condition_columns, condition_column); - } + data->condition_table = condition_table; + GRN_PTR_INIT(&(data->condition_columns), GRN_OBJ_VECTOR, GRN_ID_NIL); + data->condition_functions = + GRN_PLUGIN_MALLOCN(ctx, grn_operator_exec_func *, n_conditions); + data->n_conditions = n_conditions; - condition_functions = - GRN_PLUGIN_MALLOCN(ctx, grn_operator_exec_func *, (n_args - 1 / 3)); - for (i = 1; i < n_args; i += 3) { - int nth = (i - 1) / 3; - int mode_name_i = i + 1; + for (i = 1, nth = 0; i < n_arg_codes; nth++) { + int value_i = i; + int mode_name_i; grn_obj *mode_name; grn_operator mode; + int column_name_i; + grn_obj *column_name; + grn_obj *condition_column; + + value_i += codes[value_i].modify; - mode_name = args[mode_name_i]; + mode_name_i = value_i + 1; + mode_name = codes[mode_name_i].value; mode = grn_proc_option_value_mode(ctx, mode_name, GRN_OP_EQUAL, @@ -133,31 +143,31 @@ func_in_records(grn_ctx *ctx, switch (mode) { case GRN_OP_EQUAL : - condition_functions[nth] = grn_operator_exec_equal; + data->condition_functions[nth] = grn_operator_exec_equal; break; case GRN_OP_NOT_EQUAL : - condition_functions[nth] = grn_operator_exec_not_equal; + data->condition_functions[nth] = grn_operator_exec_not_equal; break; case GRN_OP_LESS : - condition_functions[nth] = grn_operator_exec_less; + data->condition_functions[nth] = grn_operator_exec_less; break; case GRN_OP_GREATER : - condition_functions[nth] = grn_operator_exec_greater; + data->condition_functions[nth] = grn_operator_exec_greater; break; case GRN_OP_LESS_EQUAL : - condition_functions[nth] = grn_operator_exec_less_equal; + data->condition_functions[nth] = grn_operator_exec_less_equal; break; case GRN_OP_GREATER_EQUAL : - condition_functions[nth] = grn_operator_exec_greater_equal; + data->condition_functions[nth] = grn_operator_exec_greater_equal; break; case GRN_OP_MATCH : - condition_functions[nth] = grn_operator_exec_match; + data->condition_functions[nth] = grn_operator_exec_match; break; case GRN_OP_PREFIX : - condition_functions[nth] = grn_operator_exec_prefix; + data->condition_functions[nth] = grn_operator_exec_prefix; break; case GRN_OP_REGEXP : - condition_functions[nth] = grn_operator_exec_regexp; + data->condition_functions[nth] = grn_operator_exec_regexp; break; default : GRN_PLUGIN_ERROR(ctx, @@ -170,77 +180,149 @@ func_in_records(grn_ctx *ctx, goto exit; break; } + + + column_name_i = mode_name_i + 1; + column_name = codes[column_name_i].value; + if (!grn_obj_is_text_family_bulk(ctx, column_name)) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, condition_table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): " + "the %dth argument must be column name as string: " + "<%.*s>", + column_name_i, + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + goto exit; + } + + condition_column = grn_obj_column(ctx, condition_table, + GRN_TEXT_VALUE(column_name), + GRN_TEXT_LEN(column_name)); + if (!condition_column) { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, condition_table); + GRN_PLUGIN_ERROR(ctx, + GRN_INVALID_ARGUMENT, + "in_records(): " + "the %dth argument must be existing column name: " + "<%.*s>: <%.*s>", + column_name_i, + (int)GRN_TEXT_LEN(column_name), + GRN_TEXT_VALUE(column_name), + (int)GRN_TEXT_LEN(&inspected), + GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + goto exit; + } + GRN_PTR_PUT(ctx, &(data->condition_columns), condition_column); + + i = column_name_i + 1; } - { - grn_obj condition_column_value; - - GRN_VOID_INIT(&condition_column_value); - GRN_TABLE_EACH_BEGIN(ctx, condition_table, cursor, id) { - grn_bool found_record = GRN_TRUE; - - for (i = 1; i < n_args; i += 3) { - int nth = (i - 1) / 3; - grn_obj *condition_column; - grn_operator_exec_func *condition_function; - grn_obj *value = args[i]; - - condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth); - condition_function = condition_functions[nth]; - if (grn_obj_is_data_column(ctx, condition_column)) { - grn_bool found_value = GRN_FALSE; - - GRN_BULK_REWIND(&condition_column_value); - grn_obj_get_value(ctx, - condition_column, - id, - &condition_column_value); - - found_value = condition_function(ctx, - value, - &condition_column_value); - if (ctx->rc != GRN_SUCCESS) { - found_record = GRN_FALSE; - break; - } - - if (!found_value) { - found_record = GRN_FALSE; - break; - } - } else { + return NULL; + +exit : + grn_in_records_data_free(ctx, data); + + return NULL; +} + +static grn_obj * +func_in_records_next(grn_ctx *ctx, + int n_args, + grn_obj **args, + grn_user_data *user_data) +{ + grn_in_records_data *data = user_data->ptr; + grn_obj *found; + grn_obj condition_column_value; + int i; + + found = grn_plugin_proc_alloc(ctx, user_data, GRN_DB_BOOL, 0); + if (!found) { + return NULL; + } + GRN_BOOL_SET(ctx, found, GRN_FALSE); + + if (!data) { + return found; + } + + GRN_VOID_INIT(&condition_column_value); + GRN_TABLE_EACH_BEGIN(ctx, data->condition_table, cursor, id) { + grn_bool found_record = GRN_TRUE; + + for (i = 1; i < n_args; i += 3) { + int nth = (i - 1) / 3; + grn_obj *condition_column; + grn_operator_exec_func *condition_function; + grn_obj *value = args[i]; + + condition_column = GRN_PTR_VALUE_AT(&(data->condition_columns), nth); + condition_function = data->condition_functions[nth]; + if (grn_obj_is_data_column(ctx, condition_column)) { + grn_bool found_value = GRN_FALSE; + + GRN_BULK_REWIND(&condition_column_value); + grn_obj_get_value(ctx, + condition_column, + id, + &condition_column_value); + + found_value = condition_function(ctx, + value, + &condition_column_value); + if (ctx->rc != GRN_SUCCESS) { found_record = GRN_FALSE; break; } - } - if (found_record) { - GRN_BOOL_SET(ctx, found, GRN_TRUE); + if (!found_value) { + found_record = GRN_FALSE; + break; + } + } else { + found_record = GRN_FALSE; break; } - } GRN_TABLE_EACH_END(ctx, cursor); - GRN_OBJ_FIN(ctx, &condition_column_value); - } - -exit : - GRN_PLUGIN_FREE(ctx, condition_functions); + } - for (i = 1; i < n_args; i += 2) { - int nth = (i - 1) / 3; - grn_obj *condition_column; - condition_column = GRN_PTR_VALUE_AT(&condition_columns, nth); - if (condition_column && condition_column->header.type == GRN_ACCESSOR) { - grn_obj_unlink(ctx, condition_column); + if (found_record) { + GRN_BOOL_SET(ctx, found, GRN_TRUE); + break; } - } - GRN_OBJ_FIN(ctx, &condition_columns); + } GRN_TABLE_EACH_END(ctx, cursor); + GRN_OBJ_FIN(ctx, &condition_column_value); return found; } +static grn_obj * +func_in_records_fin(grn_ctx *ctx, + int n_args, + grn_obj **args, + grn_user_data *user_data) +{ + grn_in_records_data *data = user_data->ptr; + + grn_in_records_data_free(ctx, data); + + return NULL; +} + void grn_proc_init_in_records(grn_ctx *ctx) { grn_proc_create(ctx, "in_records", -1, GRN_PROC_FUNCTION, - func_in_records, NULL, NULL, 0, NULL); + func_in_records_init, + func_in_records_next, + func_in_records_fin, + 0, + NULL); } -------------- next part -------------- HTML����������������������������...Download