[Groonga-commit] groonga/groonga at 1a67ed6 [master] Improve performance for sequential search with binary operation

Back to archive index

Kouhei Sutou null+****@clear*****
Fri Jan 15 17:28:23 JST 2016


Kouhei Sutou	2016-01-15 17:28:23 +0900 (Fri, 15 Jan 2016)

  New Revision: 1a67ed67b89a60bbf135a850492f88967e7fe204
  https://github.com/groonga/groonga/commit/1a67ed67b89a60bbf135a850492f88967e7fe204

  Message:
    Improve performance for sequential search with binary operation
    
    Here are binary operations:
    
      * x == 29
      * x != 29
      * x < 29
      * x > 29
      * x <= 29
      * x >= 29

  Modified files:
    lib/expr.c

  Modified: lib/expr.c (+191 -0)
===================================================================
--- lib/expr.c    2016-01-15 17:26:11 +0900 (893ed8a)
+++ lib/expr.c    2016-01-15 17:28:23 +0900 (97cd019)
@@ -4773,6 +4773,14 @@ typedef union {
     grn_obj *normalizer;
 #endif /* GRN_SUPPORT_REGEXP */
   } simple_regexp;
+  struct {
+    grn_obj *expr;
+    grn_obj *variable;
+    grn_obj value_buffer;
+    grn_obj constant_buffer;
+    int32_t score;
+    grn_bool (*exec)(grn_ctx *ctx, grn_obj *x, grn_obj *y);
+  } simple_condition;
 } grn_table_select_sequential_data;
 
 typedef void (*grn_table_select_sequential_init_func)(grn_ctx *ctx,
@@ -5060,6 +5068,185 @@ grn_table_select_sequential_fin_simple_regexp(grn_ctx *ctx,
 }
 #endif /* GRN_SUPPORT_REGEXP */
 
+static grn_bool
+grn_table_select_sequential_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 :
+  case GRN_OP_NOT_EQUAL :
+  case GRN_OP_LESS :
+  case GRN_OP_GREATER :
+  case GRN_OP_LESS_EQUAL :
+  case GRN_OP_GREATER_EQUAL :
+    break;
+  default :
+    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 (!target->value) {
+    return GRN_FALSE;
+  }
+  if ((target->value->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) !=
+      GRN_OBJ_COLUMN_SCALAR) {
+    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_table_select_sequential_init_simple_condition(
+  grn_ctx *ctx,
+  grn_table_select_sequential_data *data)
+{
+  grn_expr *e = (grn_expr *)(data->simple_condition.expr);
+  grn_obj *target;
+  grn_obj *constant;
+  grn_operator op;
+  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;
+
+  data->simple_condition.score = 0;
+
+  value_buffer = &(data->simple_condition.value_buffer);
+  GRN_VOID_INIT(value_buffer);
+  grn_obj_reinit_for(ctx, value_buffer, target);
+
+  switch (op) {
+  case GRN_OP_EQUAL :
+    data->simple_condition.exec = grn_operator_exec_equal;
+    break;
+  case GRN_OP_NOT_EQUAL :
+    data->simple_condition.exec = grn_operator_exec_not_equal;
+    break;
+  case GRN_OP_LESS :
+    data->simple_condition.exec = grn_operator_exec_less;
+    break;
+  case GRN_OP_GREATER :
+    data->simple_condition.exec = grn_operator_exec_greater;
+    break;
+  case GRN_OP_LESS_EQUAL :
+    data->simple_condition.exec = grn_operator_exec_less_equal;
+    break;
+  case GRN_OP_GREATER_EQUAL :
+    data->simple_condition.exec = grn_operator_exec_greater_equal;
+    break;
+  default :
+    break;
+  }
+
+  constant_buffer = &(data->simple_condition.constant_buffer);
+  GRN_VOID_INIT(constant_buffer);
+  grn_obj_reinit_for(ctx, constant_buffer, target);
+  rc = grn_obj_cast(ctx, constant, constant_buffer, GRN_FALSE);
+  if (rc != GRN_SUCCESS) {
+    grn_obj *type;
+
+    type = grn_ctx_at(ctx, constant_buffer->header.domain);
+    if (grn_obj_is_table(ctx, type)) {
+      if (op == GRN_OP_NOT_EQUAL) {
+        data->simple_condition.score = 1;
+      } else {
+        data->simple_condition.score = -1;
+      }
+    } else {
+      int type_name_size;
+      char type_name[GRN_TABLE_MAX_KEY_SIZE];
+      grn_obj inspected;
+
+      type_name_size = grn_obj_name(ctx, type, type_name,
+                                    GRN_TABLE_MAX_KEY_SIZE);
+      GRN_TEXT_INIT(&inspected, 0);
+      grn_inspect(ctx, &inspected, constant);
+      ERR(rc,
+          "[table][select][sequential][condition] "
+          "failed to cast to <%.*s>: <%.*s>",
+          type_name_size, type_name,
+          (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected));
+    }
+    return;
+  }
+}
+
+static int32_t
+grn_table_select_sequential_exec_simple_condition(
+  grn_ctx *ctx,
+  grn_id id,
+  grn_table_select_sequential_data *data)
+{
+  grn_expr *e = (grn_expr *)(data->simple_condition.expr);
+  grn_obj *target;
+  grn_obj *value_buffer = &(data->simple_condition.value_buffer);
+  grn_obj *constant_buffer = &(data->simple_condition.constant_buffer);
+
+  if (ctx->rc) {
+    return -1;
+  }
+
+  if (data->simple_condition.score != 0) {
+    return data->simple_condition.score;
+  }
+
+  target = e->codes[0].value;
+  GRN_BULK_REWIND(value_buffer);
+  grn_obj_get_value(ctx, target, id, value_buffer);
+
+  if (data->simple_condition.exec(ctx, value_buffer, constant_buffer)) {
+    return 1;
+  } else {
+    return -1;
+  }
+}
+
+static void
+grn_table_select_sequential_fin_simple_condition(
+  grn_ctx *ctx,
+  grn_table_select_sequential_data *data)
+{
+  GRN_OBJ_FIN(ctx, &(data->simple_condition.value_buffer));
+  GRN_OBJ_FIN(ctx, &(data->simple_condition.constant_buffer));
+}
+
 static void
 grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
                             grn_obj *v, grn_obj *res, grn_operator op)
@@ -5089,6 +5276,10 @@ grn_table_select_sequential(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
     exec = grn_table_select_sequential_exec_simple_regexp;
     fin = grn_table_select_sequential_fin_simple_regexp;
 #endif /* GRN_SUPPORT_REGEXP */
+  } else if (grn_table_select_sequential_is_simple_condition(ctx, expr)) {
+    init = grn_table_select_sequential_init_simple_condition;
+    exec = grn_table_select_sequential_exec_simple_condition;
+    fin = grn_table_select_sequential_fin_simple_condition;
   }
 
   init(ctx, &data);
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index