[Groonga-commit] groonga/groonga at 0079a25 [master] expr-executor: support (init + N next + fin) execution

Back to archive index

Kouhei Sutou null+****@clear*****
Mon Jun 5 16:44:43 JST 2017


Kouhei Sutou	2017-06-05 16:44:43 +0900 (Mon, 05 Jun 2017)

  New Revision: 0079a256c64b10f86ef9fa1a6b65847400eb80be
  https://github.com/groonga/groonga/commit/0079a256c64b10f86ef9fa1a6b65847400eb80be

  Message:
    expr-executor: support (init + N next + fin) execution
    
    Function needs at least "init" and "next" callback to use the execution
    flow. If initialization is heavy, this execution flow will improve
    performance.

  Modified files:
    lib/expr.c
    lib/expr_executor.c

  Modified: lib/expr.c (+15 -3)
===================================================================
--- lib/expr.c    2017-06-05 16:39:33 +0900 (0687a0f)
+++ lib/expr.c    2017-06-05 16:44:43 +0900 (c4bb6cd)
@@ -1451,15 +1451,27 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller)
   pctx.caller = caller;
   pctx.user_data.ptr = NULL;
   if (p->funcs[PROC_INIT]) {
-    obj = p->funcs[PROC_INIT](ctx, nargs, args, &pctx.user_data);
+    grn_obj *sub_obj;
+    sub_obj = p->funcs[PROC_INIT](ctx, nargs, args, &pctx.user_data);;
+    if (sub_obj) {
+      obj = sub_obj;
+    }
   }
   pctx.phase = PROC_NEXT;
   if (p->funcs[PROC_NEXT]) {
-    obj = p->funcs[PROC_NEXT](ctx, nargs, args, &pctx.user_data);
+    grn_obj *sub_obj;
+    sub_obj = p->funcs[PROC_NEXT](ctx, nargs, args, &pctx.user_data);
+    if (sub_obj) {
+      obj = sub_obj;
+    }
   }
   pctx.phase = PROC_FIN;
   if (p->funcs[PROC_FIN]) {
-    obj = p->funcs[PROC_FIN](ctx, nargs, args, &pctx.user_data);
+    grn_obj *sub_obj;
+    sub_obj = p->funcs[PROC_FIN](ctx, nargs, args, &pctx.user_data);
+    if (sub_obj) {
+      obj = sub_obj;
+    }
   }
   ctx->impl->stack_curr -= nargs;
   grn_ctx_push(ctx, obj);

  Modified: lib/expr_executor.c (+114 -0)
===================================================================
--- lib/expr_executor.c    2017-06-05 16:39:33 +0900 (b2ddb53)
+++ lib/expr_executor.c    2017-06-05 16:44:43 +0900 (8b94355)
@@ -17,6 +17,7 @@
 */
 
 #include "grn.h"
+#include "grn_ctx_impl.h"
 #include "grn_expr_executor.h"
 
 #ifdef GRN_WITH_ONIGMO
@@ -45,6 +46,10 @@ typedef union {
   } simple_regexp;
 #endif /* GRN_SUPPORT_REGEXP */
   struct {
+    grn_proc_ctx proc_ctx;
+    int n_args;
+  } proc;
+  struct {
     grn_bool need_exec;
     grn_obj result_buffer;
     grn_obj value_buffer;
@@ -406,6 +411,111 @@ grn_expr_executor_fin_simple_regexp(grn_ctx *ctx,
 #endif /* GRN_SUPPORT_REGEXP */
 
 static grn_bool
+grn_expr_executor_is_proc(grn_ctx *ctx, grn_obj *expr)
+{
+  grn_expr *e = (grn_expr *)expr;
+  grn_obj *first;
+  grn_proc *proc;
+
+  if (e->codes_curr < 2) {
+    return GRN_FALSE;
+  }
+
+  first = e->codes[0].value;
+  if (!grn_obj_is_function_proc(ctx, first)) {
+    return GRN_FALSE;
+  }
+
+  proc = (grn_proc *)first;
+  if (!(proc->funcs[PROC_INIT] &&
+        proc->funcs[PROC_NEXT])) {
+    return GRN_FALSE;
+  }
+
+  if (e->codes[e->codes_curr - 1].op != GRN_OP_CALL) {
+    return GRN_FALSE;
+  }
+
+  return GRN_TRUE;
+}
+
+static void
+grn_expr_executor_init_proc(grn_ctx *ctx,
+                            grn_expr_executor *executor)
+{
+  grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+  grn_expr *expr;
+  grn_proc *proc;
+
+  expr = (grn_expr *)(executor->expr);
+  proc = (grn_proc *)(expr->codes[0].value);
+  proc_ctx->proc = proc;
+  proc_ctx->caller = executor->expr;
+  proc_ctx->phase = PROC_INIT;
+
+  executor->data.proc.n_args = expr->codes[expr->codes_curr - 1].nargs - 1;
+
+  proc->funcs[PROC_INIT](ctx, 0, NULL, &(proc_ctx->user_data));
+}
+
+static grn_obj *
+grn_expr_executor_exec_proc(grn_ctx *ctx,
+                            grn_expr_executor *executor,
+                            grn_id id)
+{
+  grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+  int n_args = executor->data.proc.n_args;
+  grn_proc *proc;
+  grn_expr *expr;
+  grn_obj **args;
+  uint32_t values_curr;
+  uint32_t values_tail;
+  grn_obj *result;
+
+  proc = proc_ctx->proc;
+  proc_ctx->phase = PROC_NEXT;
+  GRN_RECORD_SET(ctx, executor->variable, id);
+
+  expr = (grn_expr *)(executor->expr);
+  values_curr = expr->values_curr;
+  values_tail = expr->values_tail;
+
+  expr->codes += 1;
+  expr->codes_curr -= 2;
+  grn_expr_exec(ctx, executor->expr, 0);
+  expr->codes_curr += 2;
+  expr->codes -= 1;
+
+  args = ctx->impl->stack + ctx->impl->stack_curr;
+  ctx->impl->stack_curr += n_args;
+  expr->values_curr = expr->values_tail;
+  result = proc->funcs[PROC_NEXT](ctx,
+                                  n_args,
+                                  args,
+                                  &(proc_ctx->user_data));
+  ctx->impl->stack_curr -= n_args;
+
+  expr->values_tail = values_tail;
+  expr->values_curr = values_curr;
+
+  return result;
+}
+
+static void
+grn_expr_executor_fin_proc(grn_ctx *ctx,
+                           grn_expr_executor *executor)
+{
+  grn_proc_ctx *proc_ctx = &(executor->data.proc.proc_ctx);
+  grn_proc *proc;
+
+  proc = proc_ctx->proc;
+  proc_ctx->phase = PROC_FIN;
+  if (proc->funcs[PROC_FIN]) {
+    proc->funcs[PROC_FIN](ctx, 0, NULL, &(proc_ctx->user_data));
+  }
+}
+
+static grn_bool
 grn_expr_executor_is_simple_condition(grn_ctx *ctx, grn_obj *expr)
 {
   grn_expr *e = (grn_expr *)expr;
@@ -639,6 +749,10 @@ grn_expr_executor_open(grn_ctx *ctx, grn_obj *expr)
     executor->exec = grn_expr_executor_exec_simple_regexp;
     executor->fin = grn_expr_executor_fin_simple_regexp;
 #endif /* GRN_SUPPORT_REGEXP */
+  } else if (grn_expr_executor_is_proc(ctx, 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(ctx, expr)) {
     grn_expr_executor_init_simple_condition(ctx, executor);
     executor->exec = grn_expr_executor_exec_simple_condition;
-------------- next part --------------
HTML����������������������������...
下載 



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