wanabe
null+****@clear*****
Sun Oct 6 00:06:06 JST 2013
wanabe 2013-10-06 00:06:06 +0900 (Sun, 06 Oct 2013) New Revision: e82e8b73554629f093e65796028711076bb5fe0c https://github.com/groonga/groonga/commit/e82e8b73554629f093e65796028711076bb5fe0c Merged d127d05: Merge pull request #110 from wanabe/scaninfo-with-mruby Message: Copy scan_info_build() to lib/mrb/mrb_expr.c Modified files: lib/expr.c lib/mrb/mrb_expr.c lib/mrb/mrb_expr.h Modified: lib/expr.c (+6 -0) =================================================================== --- lib/expr.c 2013-10-05 09:35:33 +0900 (ca80385) +++ lib/expr.c 2013-10-06 00:06:06 +0900 (9819d68) @@ -25,6 +25,7 @@ #include "expr.h" #include "util.h" #include "normalizer_in.h" +#include "mrb.h" static inline int function_proc_p(grn_obj *obj) @@ -4071,6 +4072,11 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, scan_info **sis, *si = NULL; grn_expr_code *c, *ce; grn_expr *e = (grn_expr *)expr; +#ifdef GRN_WITH_MRUBY + if (ctx->impl->mrb.state) { + return grn_mrb_scan_info_build(ctx, expr, n, op, size); + } +#endif if (!(var = grn_expr_get_var_by_offset(ctx, expr, 0))) { return NULL; } for (stat = SCAN_START, c = e->codes, ce = &e->codes[e->codes_curr]; c < ce; c++) { switch (c->op) { Modified: lib/mrb/mrb_expr.c (+302 -0) =================================================================== --- lib/mrb/mrb_expr.c 2013-10-05 09:35:33 +0900 (23af9b9) +++ lib/mrb/mrb_expr.c 2013-10-06 00:06:06 +0900 (c01ae13) @@ -22,12 +22,314 @@ #include <mruby.h> #include <mruby/class.h> +#include "../util.h" #include "mrb_expr.h" +static scan_info ** +scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, + grn_operator op, uint32_t size) +{ + grn_obj *var; + scan_stat stat; + int i, m = 0, o = 0; + scan_info **sis, *si = NULL; + grn_expr_code *c, *ce; + grn_expr *e = (grn_expr *)expr; + + if (!(var = grn_expr_get_var_by_offset(ctx, expr, 0))) { return NULL; } + for (stat = SCAN_START, c = e->codes, ce = &e->codes[e->codes_curr]; c < ce; c++) { + switch (c->op) { + case GRN_OP_MATCH : + case GRN_OP_NEAR : + case GRN_OP_NEAR2 : + case GRN_OP_SIMILAR : + case GRN_OP_PREFIX : + case GRN_OP_SUFFIX : + 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 : + case GRN_OP_GEO_WITHINP5 : + case GRN_OP_GEO_WITHINP6 : + case GRN_OP_GEO_WITHINP8 : + case GRN_OP_TERM_EXTRACT : + if (stat < SCAN_COL1 || SCAN_CONST < stat) { return NULL; } + stat = SCAN_START; + m++; + break; + case GRN_OP_AND : + case GRN_OP_OR : + case GRN_OP_AND_NOT : + case GRN_OP_ADJUST : + if (stat != SCAN_START) { return NULL; } + o++; + if (o >= m) { return NULL; } + break; + case GRN_OP_PUSH : + stat = (c->value == var) ? SCAN_VAR : SCAN_CONST; + break; + case GRN_OP_GET_VALUE : + switch (stat) { + case SCAN_START : + case SCAN_CONST : + case SCAN_VAR : + stat = SCAN_COL1; + break; + case SCAN_COL1 : + stat = SCAN_COL2; + break; + case SCAN_COL2 : + break; + default : + return NULL; + break; + } + break; + case GRN_OP_CALL : + if ((c->flags & GRN_EXPR_CODE_RELATIONAL_EXPRESSION) || c + 1 == ce) { + stat = SCAN_START; + m++; + } else { + stat = SCAN_COL2; + } + break; + default : + return NULL; + break; + } + } + if (stat || m != o + 1) { return NULL; } + if (!(sis = GRN_MALLOCN(scan_info *, m + m + o))) { return NULL; } + for (i = 0, stat = SCAN_START, c = e->codes, ce = &e->codes[e->codes_curr]; c < ce; c++) { + switch (c->op) { + case GRN_OP_MATCH : + case GRN_OP_NEAR : + case GRN_OP_NEAR2 : + case GRN_OP_SIMILAR : + case GRN_OP_PREFIX : + case GRN_OP_SUFFIX : + 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 : + case GRN_OP_GEO_WITHINP5 : + case GRN_OP_GEO_WITHINP6 : + case GRN_OP_GEO_WITHINP8 : + case GRN_OP_TERM_EXTRACT : + stat = SCAN_START; + grn_scan_info_set_op(si, c->op); + grn_scan_info_set_end(si, c - e->codes); + sis[i++] = si; + { + int sid, k; + grn_obj *index, *arg, **p = &arg; + for (k = 0; (arg = grn_scan_info_get_arg(ctx, si, k)) ; k++) { + if ((*p)->header.type == GRN_EXPR) { + uint32_t j; + grn_expr_code *ec; + grn_expr *e = (grn_expr *)(*p); + for (j = e->codes_curr, ec = e->codes; j--; ec++) { + if (ec->value) { + switch (ec->value->header.type) { + case GRN_ACCESSOR : + if (grn_column_index(ctx, ec->value, c->op, &index, 1, &sid)) { + int32_t weight = grn_expr_code_get_weight(ctx, ec); + grn_scan_info_set_flags(si, grn_scan_info_get_flags(si) | SCAN_ACCESSOR); + if (((grn_accessor *)ec->value)->next) { + grn_scan_info_put_index(ctx, si, ec->value, sid, weight); + } else { + grn_scan_info_put_index(ctx, si, index, sid, weight); + } + } + break; + case GRN_COLUMN_FIX_SIZE : + case GRN_COLUMN_VAR_SIZE : + if (grn_column_index(ctx, ec->value, c->op, &index, 1, &sid)) { + grn_scan_info_put_index(ctx, si, index, sid, grn_expr_code_get_weight(ctx, ec)); + } + break; + case GRN_COLUMN_INDEX : + sid = 0; + index = ec->value; + if (j > 2 && + ec[1].value && + ec[1].value->header.domain == GRN_DB_UINT32 && + ec[2].op == GRN_OP_GET_MEMBER) { + sid = GRN_UINT32_VALUE(ec[1].value) + 1; + j -= 2; + ec += 2; + } + grn_scan_info_put_index(ctx, si, index, sid, grn_expr_code_get_weight(ctx, ec)); + break; + } + } + } + } else if (GRN_DB_OBJP(*p)) { + if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { + grn_scan_info_put_index(ctx, si, index, sid, 1); + } + } else if (GRN_ACCESSORP(*p)) { + grn_scan_info_set_flags(si, grn_scan_info_get_flags(si) | SCAN_ACCESSOR); + if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { + if (((grn_accessor *)(*p))->next) { + grn_scan_info_put_index(ctx, si, *p, sid, 1); + } else { + grn_scan_info_put_index(ctx, si, index, sid, 1); + } + } + } else { + grn_scan_info_set_query(si, *p); + } + } + } + si = NULL; + break; + case GRN_OP_AND : + case GRN_OP_OR : + case GRN_OP_AND_NOT : + case GRN_OP_ADJUST : + if (!grn_scan_info_put_logical_op(ctx, sis, &i, c->op, c - e->codes)) { return NULL; } + stat = SCAN_START; + break; + case GRN_OP_PUSH : + if (!si) { + si = grn_scan_info_open(ctx, c - e->codes); + if (!si) { + int j; + for (j = 0; j < i; j++) { grn_scan_info_close(ctx, sis[j]); } + GRN_FREE(sis); + return NULL; + } + } + if (c->value == var) { + stat = SCAN_VAR; + } else { + grn_scan_info_push_arg(si, c->value); + if (stat == SCAN_START) { grn_scan_info_set_flags(si, grn_scan_info_get_flags(si) | SCAN_PRE_CONST); } + stat = SCAN_CONST; + } + break; + case GRN_OP_GET_VALUE : + switch (stat) { + case SCAN_START : + if (!si) { + si = grn_scan_info_open(ctx, c - e->codes); + if (!si) { + int j; + for (j = 0; j < i; j++) { grn_scan_info_close(ctx, sis[j]); } + GRN_FREE(sis); + return NULL; + } + } + // fallthru + case SCAN_CONST : + case SCAN_VAR : + stat = SCAN_COL1; + grn_scan_info_push_arg(si, c->value); + break; + case SCAN_COL1 : + { + int j; + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + GRN_TEXT_PUTS(ctx, &inspected, "<"); + grn_inspect_name(ctx, &inspected, c->value); + GRN_TEXT_PUTS(ctx, &inspected, ">: <"); + grn_inspect(ctx, &inspected, expr); + GRN_TEXT_PUTS(ctx, &inspected, ">"); + ERR(GRN_INVALID_ARGUMENT, + "invalid expression: can't use column as a value: %.*s", + (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + for (j = 0; j < i; j++) { grn_scan_info_close(ctx, sis[j]); } + GRN_FREE(sis); + return NULL; + } + stat = SCAN_COL2; + break; + case SCAN_COL2 : + break; + default : + break; + } + break; + case GRN_OP_CALL : + if (!si) { + si = grn_scan_info_open(ctx, c - e->codes); + if (!si) { + int j; + for (j = 0; j < i; j++) { grn_scan_info_close(ctx, sis[j]); } + GRN_FREE(sis); + return NULL; + } + } + if ((c->flags & GRN_EXPR_CODE_RELATIONAL_EXPRESSION) || c + 1 == ce) { + stat = SCAN_START; + grn_scan_info_set_op(si, c->op); + grn_scan_info_set_end(si, c - e->codes); + sis[i++] = si; + /* better index resolving framework for functions should be implemented */ + { + int sid, k; + grn_obj *index, *arg, **p = &arg; + for (k = 0; (arg = grn_scan_info_get_arg(ctx, si, k)) ; k++) { + if (GRN_DB_OBJP(*p)) { + if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { + grn_scan_info_put_index(ctx, si, index, sid, 1); + } + } else if (GRN_ACCESSORP(*p)) { + grn_scan_info_set_flags(si, grn_scan_info_get_flags(si) | SCAN_ACCESSOR); + if (grn_column_index(ctx, *p, c->op, &index, 1, &sid)) { + grn_scan_info_put_index(ctx, si, index, sid, 1); + } + } else { + grn_scan_info_set_query(si, *p); + } + } + } + si = NULL; + } else { + stat = SCAN_COL2; + } + break; + default : + break; + } + } + if (op == GRN_OP_OR && !size) { + // for debug + if (!(grn_scan_info_get_flags(sis[0]) & SCAN_PUSH) || (grn_scan_info_get_logical_op(sis[0]) != op)) { + int j; + ERR(GRN_INVALID_ARGUMENT, "invalid expr"); + for (j = 0; j < i; j++) { grn_scan_info_close(ctx, sis[j]); } + GRN_FREE(sis); + return NULL; + } else { + grn_scan_info_set_flags(sis[0], grn_scan_info_get_flags(sis[0]) & ~SCAN_PUSH); + grn_scan_info_set_logical_op(sis[0], op); + } + } else { + if (!grn_scan_info_put_logical_op(ctx, sis, &i, op, c - e->codes)) { return NULL; } + } + *n = i; + return sis; +} + void grn_mrb_expr_init(grn_ctx *ctx) { mrb_state *mrb = ctx->impl->mrb.state; struct RClass *module = ctx->impl->mrb.module; } + +scan_info ** +grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, + grn_operator op, uint32_t size) +{ + return scan_info_build(ctx, expr, n, op, size); +} #endif Modified: lib/mrb/mrb_expr.h (+2 -0) =================================================================== --- lib/mrb/mrb_expr.h 2013-10-05 09:35:33 +0900 (ad99863) +++ lib/mrb/mrb_expr.h 2013-10-06 00:06:06 +0900 (7fd5c66) @@ -20,12 +20,14 @@ #define GRN_MRB_EXPR_H #include "../ctx.h" +#include "../expr.h" #ifdef __cplusplus extern "C" { #endif void grn_mrb_expr_init(grn_ctx *ctx); +scan_info **grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, grn_operator op, uint32_t size); #ifdef __cplusplus } -------------- next part -------------- HTML����������������������������...Download