Skip to content

Commit

Permalink
Improve performance for "FIXED_SIZE_COLUMN OP CONSTANT"
Browse files Browse the repository at this point in the history
Supported OPs:

  * ==
  * !=
  * <
  * >
  * <=
  * >=
  • Loading branch information
kou committed Jun 12, 2017
1 parent e2819ec commit 540e23a
Showing 1 changed file with 170 additions and 23 deletions.
193 changes: 170 additions & 23 deletions lib/expr_executor.c
Expand Up @@ -49,12 +49,21 @@ typedef union {
grn_proc_ctx proc_ctx;
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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 540e23a

Please sign in to comment.