Kouhei Sutou
null+****@clear*****
Mon Jun 12 16:45:42 JST 2017
Kouhei Sutou 2017-06-12 16:45:42 +0900 (Mon, 12 Jun 2017) New Revision: 540e23a22d6df2a91de37b377e6de14ea95850bb https://github.com/groonga/groonga/commit/540e23a22d6df2a91de37b377e6de14ea95850bb Message: Improve performance for "FIXED_SIZE_COLUMN OP CONSTANT" Supported OPs: * == * != * < * > * <= * >= Modified files: lib/expr_executor.c Modified: lib/expr_executor.c (+170 -23) =================================================================== --- lib/expr_executor.c 2017-06-12 16:16:30 +0900 (8b94355) +++ lib/expr_executor.c 2017-06-12 16:45:42 +0900 (4fcf93a) @@ -50,11 +50,20 @@ typedef union { int n_args; } proc; struct { + grn_obj result_buffer; + grn_ra *ra; + grn_ra_cache ra_cache; + unsigned int ra_element_size; + grn_obj value_buffer; + grn_obj constant_buffer; + grn_operator_exec_func *exec; + } simple_condition_ra; + struct { grn_bool need_exec; grn_obj result_buffer; grn_obj value_buffer; grn_obj constant_buffer; - grn_bool (*exec)(grn_ctx *ctx, grn_obj *x, grn_obj *y); + grn_operator_exec_func *exec; } simple_condition; } grn_expr_executor_data; @@ -516,7 +525,7 @@ grn_expr_executor_fin_proc(grn_ctx *ctx, } static grn_bool -grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr) +grn_expr_executor_is_simple_condition_ra(grn_ctx *ctx, grn_obj *expr) { grn_expr *e = (grn_expr *)expr; grn_expr_code *target; @@ -552,7 +561,7 @@ grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr) if (target->nargs != 1) { return GRN_FALSE; } - if (!grn_obj_is_scalar_column(ctx, target->value)) { + if (target->value->header.type != GRN_COLUMN_FIX_SIZE) { return GRN_FALSE; } @@ -569,12 +578,24 @@ grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr) return GRN_FALSE; } + { + grn_obj constant_buffer; + grn_rc rc; + GRN_VOID_INIT(&constant_buffer); + grn_obj_reinit_for(ctx, &constant_buffer, target->value); + rc = grn_obj_cast(ctx, constant->value, &constant_buffer, GRN_FALSE); + GRN_OBJ_FIN(ctx, &constant_buffer); + if (rc != GRN_SUCCESS) { + return GRN_FALSE; + } + } + return GRN_TRUE; } static void -grn_expr_executor_init_simple_condition(grn_ctx *ctx, - grn_expr_executor *executor) +grn_expr_executor_init_simple_condition_ra(grn_ctx *ctx, + grn_expr_executor *executor) { grn_expr *e = (grn_expr *)(executor->expr); grn_obj *target; @@ -583,45 +604,167 @@ grn_expr_executor_init_simple_condition(grn_ctx *ctx, grn_obj *result_buffer; grn_obj *value_buffer; grn_obj *constant_buffer; - grn_rc rc; target = e->codes[0].value; constant = e->codes[1].value; op = e->codes[2].op; - executor->data.simple_condition.need_exec = GRN_TRUE; - - result_buffer = &(executor->data.simple_condition.result_buffer); + result_buffer = &(executor->data.simple_condition_ra.result_buffer); GRN_BOOL_INIT(result_buffer, 0); GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE); - value_buffer = &(executor->data.simple_condition.value_buffer); + value_buffer = &(executor->data.simple_condition_ra.value_buffer); GRN_VOID_INIT(value_buffer); grn_obj_reinit_for(ctx, value_buffer, target); - switch (op) { + executor->data.simple_condition_ra.ra = (grn_ra *)target; + GRN_RA_CACHE_INIT(executor->data.simple_condition_ra.ra, + &(executor->data.simple_condition_ra.ra_cache)); + grn_ra_info(ctx, + executor->data.simple_condition_ra.ra, + &(executor->data.simple_condition_ra.ra_element_size)); + + executor->data.simple_condition_ra.exec = grn_operator_to_exec_func(op); + + constant_buffer = &(executor->data.simple_condition_ra.constant_buffer); + GRN_VOID_INIT(constant_buffer); + grn_obj_reinit_for(ctx, constant_buffer, target); + grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE); +} + +static grn_obj * +grn_expr_executor_exec_simple_condition_ra(grn_ctx *ctx, + grn_expr_executor *executor, + grn_id id) +{ + grn_obj *result_buffer = &(executor->data.simple_condition_ra.result_buffer); + grn_obj *value_buffer = &(executor->data.simple_condition_ra.value_buffer); + grn_obj *constant_buffer = + &(executor->data.simple_condition_ra.constant_buffer); + + if (ctx->rc) { + GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE); + return result_buffer; + } + + { + grn_ra *ra = executor->data.simple_condition_ra.ra; + grn_ra_cache *ra_cache = &(executor->data.simple_condition_ra.ra_cache); + unsigned int ra_element_size = + executor->data.simple_condition_ra.ra_element_size; + void *raw_value; + raw_value = grn_ra_ref_cache(ctx, ra, id, ra_cache); + GRN_BULK_REWIND(value_buffer); + grn_bulk_write(ctx, value_buffer, raw_value, ra_element_size); + } + + if (executor->data.simple_condition_ra.exec(ctx, + value_buffer, + constant_buffer)) { + GRN_BOOL_SET(ctx, result_buffer, GRN_TRUE); + } else { + GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE); + } + return result_buffer; +} + +static void +grn_expr_executor_fin_simple_condition_ra(grn_ctx *ctx, + grn_expr_executor *executor) +{ + GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.result_buffer)); + GRN_RA_CACHE_FIN(executor->data.simple_condition_ra.ra, + &(executor->data.simple_condition_ra.ra_cache)); + GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.value_buffer)); + GRN_OBJ_FIN(ctx, &(executor->data.simple_condition_ra.constant_buffer)); +} + +static grn_bool +grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr) +{ + grn_expr *e = (grn_expr *)expr; + grn_expr_code *target; + grn_expr_code *constant; + grn_expr_code *operator; + + if (e->codes_curr != 3) { + return GRN_FALSE; + } + + target = &(e->codes[0]); + constant = &(e->codes[1]); + operator = &(e->codes[2]); + + switch (operator->op) { case GRN_OP_EQUAL : - executor->data.simple_condition.exec = grn_operator_exec_equal; - break; case GRN_OP_NOT_EQUAL : - executor->data.simple_condition.exec = grn_operator_exec_not_equal; - break; case GRN_OP_LESS : - executor->data.simple_condition.exec = grn_operator_exec_less; - break; case GRN_OP_GREATER : - executor->data.simple_condition.exec = grn_operator_exec_greater; - break; case GRN_OP_LESS_EQUAL : - executor->data.simple_condition.exec = grn_operator_exec_less_equal; - break; case GRN_OP_GREATER_EQUAL : - executor->data.simple_condition.exec = grn_operator_exec_greater_equal; break; default : - break; + return GRN_FALSE; + } + if (operator->nargs != 2) { + return GRN_FALSE; + } + + if (target->op != GRN_OP_GET_VALUE) { + return GRN_FALSE; + } + if (target->nargs != 1) { + return GRN_FALSE; + } + if (!grn_obj_is_scalar_column(ctx, target->value)) { + return GRN_FALSE; + } + + if (constant->op != GRN_OP_PUSH) { + return GRN_FALSE; + } + if (constant->nargs != 1) { + return GRN_FALSE; + } + if (!constant->value) { + return GRN_FALSE; + } + if (constant->value->header.type != GRN_BULK) { + return GRN_FALSE; } + return GRN_TRUE; +} + +static void +grn_expr_executor_init_simple_condition(grn_ctx *ctx, + grn_expr_executor *executor) +{ + grn_expr *e = (grn_expr *)(executor->expr); + grn_obj *target; + grn_obj *constant; + grn_operator op; + grn_obj *result_buffer; + grn_obj *value_buffer; + grn_obj *constant_buffer; + grn_rc rc; + + target = e->codes[0].value; + constant = e->codes[1].value; + op = e->codes[2].op; + + executor->data.simple_condition.need_exec = GRN_TRUE; + + result_buffer = &(executor->data.simple_condition.result_buffer); + GRN_BOOL_INIT(result_buffer, 0); + GRN_BOOL_SET(ctx, result_buffer, GRN_FALSE); + + value_buffer = &(executor->data.simple_condition.value_buffer); + GRN_VOID_INIT(value_buffer); + grn_obj_reinit_for(ctx, value_buffer, target); + + executor->data.simple_condition.exec = grn_operator_to_exec_func(op); + constant_buffer = &(executor->data.simple_condition.constant_buffer); GRN_VOID_INIT(constant_buffer); grn_obj_reinit_for(ctx, constant_buffer, target); @@ -753,6 +896,10 @@ grn_expr_executor_open(grn_ctx *ctx, grn_obj *expr) grn_expr_executor_init_proc(ctx, executor); executor->exec = grn_expr_executor_exec_proc; executor->fin = grn_expr_executor_fin_proc; + } else if (grn_expr_executor_is_simple_condition_ra(ctx, expr)) { + grn_expr_executor_init_simple_condition_ra(ctx, executor); + executor->exec = grn_expr_executor_exec_simple_condition_ra; + executor->fin = grn_expr_executor_fin_simple_condition_ra; } else if (grn_expr_executor_is_simple_condition(ctx, expr)) { grn_expr_executor_init_simple_condition(ctx, executor); executor->exec = grn_expr_executor_exec_simple_condition; -------------- next part -------------- HTML����������������������������... Download