Kouhei Sutou
null+****@clear*****
Wed Oct 7 12:49:42 JST 2015
Kouhei Sutou 2015-10-07 12:49:42 +0900 (Wed, 07 Oct 2015) New Revision: d45a32b6cd3acd7e2bdc4d5859ee687bdb6f0528 https://github.com/groonga/groonga/commit/d45a32b6cd3acd7e2bdc4d5859ee687bdb6f0528 Message: Add grn_scanner It's for supporting rewriting grn_expr. (Rewriting grn_expr isn't implemented yet.) Added files: lib/scanner.c Copied files: lib/grn_scanner.h (from lib/mrb/mrb_expr.h) Modified files: lib/expr.c lib/grn_expr.h lib/mrb/mrb_expr.c lib/mrb/mrb_expr.h lib/mrb/scripts/expression.rb lib/mrb/scripts/scan_info_builder.rb lib/sources.am Modified: lib/expr.c (+17 -17) =================================================================== --- lib/expr.c 2015-10-07 12:42:06 +0900 (b4830a3) +++ lib/expr.c 2015-10-07 12:49:42 +0900 (9f8e4fd) @@ -23,6 +23,7 @@ #include "grn_geo.h" #include "grn_expr.h" #include "grn_expr_code.h" +#include "grn_scanner.h" #include "grn_util.h" #include "grn_report.h" #include "grn_mrb.h" @@ -4379,9 +4380,9 @@ scan_info_build_match(grn_ctx *ctx, scan_info *si) } } -static scan_info ** -scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, - grn_operator op, uint32_t size) +scan_info ** +grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, + grn_operator op, grn_bool record_exist) { grn_obj *var; scan_stat stat; @@ -4391,7 +4392,7 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, 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); + return grn_mrb_scan_info_build(ctx, expr, n, op, record_exist); } #endif if (!(var = grn_expr_get_var_by_offset(ctx, expr, 0))) { return NULL; } @@ -4612,7 +4613,7 @@ scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, break; } } - if (op == GRN_OP_OR && !size) { + if (op == GRN_OP_OR && !record_exist) { // for debug if (!(sis[0]->flags & SCAN_PUSH) || (sis[0]->logical_op != op)) { int j; @@ -5456,16 +5457,17 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, GRN_API_ENTER; res_size = GRN_HASH_SIZE((grn_hash *)res); if (op == GRN_OP_OR || res_size) { - int i, n; - scan_info **sis; - if ((sis = scan_info_build(ctx, expr, &n, op, res_size))) { + int i; + grn_scanner *scanner; + scanner = grn_scanner_open(ctx, expr, op, res_size > 0); + if (scanner) { grn_obj res_stack; grn_expr *e = (grn_expr *)expr; grn_expr_code *codes = e->codes; uint32_t codes_curr = e->codes_curr; GRN_PTR_INIT(&res_stack, GRN_OBJ_VECTOR, GRN_ID_NIL); - for (i = 0; i < n; i++) { - scan_info *si = sis[i]; + for (i = 0; i < scanner->n_sis; i++) { + scan_info *si = scanner->sis[i]; if (si->flags & SCAN_POP) { grn_obj *res_; GRN_PTR_POP(&res_stack, res_); @@ -5503,10 +5505,7 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, break; } } - for (i = 0; i < n; i++) { - scan_info *si = sis[i]; - SI_FREE(si); - } + i = 0; if (!res_created) { i++; } for (; i < GRN_BULK_VSIZE(&res_stack) / sizeof(grn_obj *); i++) { @@ -5515,9 +5514,10 @@ grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr, grn_obj_close(ctx, stacked_res); } GRN_OBJ_FIN(ctx, &res_stack); - GRN_FREE(sis); e->codes = codes; e->codes_curr = codes_curr; + + grn_scanner_close(ctx, scanner); } else { if (!ctx->rc) { grn_table_select_sequential(ctx, table, expr, v, res, op); @@ -6857,7 +6857,7 @@ grn_expr_get_keywords(grn_ctx *ctx, grn_obj *expr, grn_obj *keywords) int i, n; scan_info **sis, *si; GRN_API_ENTER; - if ((sis = scan_info_build(ctx, expr, &n, GRN_OP_OR, 0))) { + if ((sis = grn_scan_info_build(ctx, expr, &n, GRN_OP_OR, GRN_FALSE))) { int butp = 0, nparens = 0, npbut = 0; grn_obj but_stack; GRN_UINT32_INIT(&but_stack, GRN_OBJ_VECTOR); @@ -7063,7 +7063,7 @@ grn_expr_dump_plan(grn_ctx *ctx, grn_obj *expr, grn_obj *buffer) scan_info **sis; GRN_API_ENTER; - sis = scan_info_build(ctx, expr, &n, GRN_OP_OR, 0); + sis = grn_scan_info_build(ctx, expr, &n, GRN_OP_OR, GRN_FALSE); if (sis) { int i; grn_inspect_scan_info_list(ctx, buffer, sis, n); Modified: lib/grn_expr.h (+3 -0) =================================================================== --- lib/grn_expr.h 2015-10-07 12:42:06 +0900 (7587149) +++ lib/grn_expr.h 2015-10-07 12:49:42 +0900 (e5f6bb9) @@ -41,6 +41,9 @@ typedef enum { typedef struct _grn_scan_info scan_info; typedef grn_bool (*grn_scan_info_each_arg_callback)(grn_ctx *ctx, grn_obj *obj, void *user_data); +scan_info **grn_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, + grn_operator op, grn_bool record_exist); + scan_info *grn_scan_info_open(grn_ctx *ctx, int start); void grn_scan_info_close(grn_ctx *ctx, scan_info *si); void grn_scan_info_put_index(grn_ctx *ctx, scan_info *si, grn_obj *index, Copied: lib/grn_scanner.h (+15 -11) 62% =================================================================== --- lib/mrb/mrb_expr.h 2015-10-07 12:42:06 +0900 (0564401) +++ lib/grn_scanner.h 2015-10-07 12:49:42 +0900 (5c86ecb) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2015 Brazil + Copyright(C) 2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,24 +16,28 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRN_MRB_EXPR_H -#define GRN_MRB_EXPR_H +#ifndef GRN_SCANNER_H +#define GRN_SCANNER_H -#include "../grn_ctx.h" -#include "../grn_expr.h" +#include "grn_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); -unsigned int grn_mrb_expr_estimate_size(grn_ctx *ctx, - grn_obj *expr, - grn_obj *table); +typedef struct _grn_scaner { + grn_obj *expr; + grn_obj *rewritten_expr; + scan_info **sis; + unsigned int n_sis; +} grn_scanner; + +grn_scanner *grn_scanner_open(grn_ctx *ctx, grn_obj *expr, + grn_operator op, grn_bool record_exist); +void grn_scanner_close(grn_ctx *ctx, grn_scanner *scanner); #ifdef __cplusplus } #endif -#endif /* GRN_MRB_EXPR_H */ +#endif /* GRN_SCANNER_H */ Modified: lib/mrb/mrb_expr.c (+6 -3) =================================================================== --- lib/mrb/mrb_expr.c 2015-10-07 12:42:06 +0900 (822e465) +++ lib/mrb/mrb_expr.c 2015-10-07 12:49:42 +0900 (285f047) @@ -810,8 +810,11 @@ 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) +grn_mrb_scan_info_build(grn_ctx *ctx, + grn_obj *expr, + int *n, + grn_operator op, + grn_bool record_exist) { grn_mrb_data *data = &(ctx->impl->mrb); mrb_state *mrb = data->state; @@ -826,7 +829,7 @@ grn_mrb_scan_info_build(grn_ctx *ctx, grn_obj *expr, int *n, mrb_expression = grn_mrb_value_from_grn_obj(mrb, expr); mrb_sis = mrb_funcall(mrb, mrb_expression, "build_scan_info", 2, grn_mrb_value_from_operator(mrb, op), - mrb_fixnum_value(size)); + mrb_bool_value(record_exist)); if (mrb_nil_p(mrb_sis)) { goto exit; Modified: lib/mrb/mrb_expr.h (+5 -1) =================================================================== --- lib/mrb/mrb_expr.h 2015-10-07 12:42:06 +0900 (0564401) +++ lib/mrb/mrb_expr.h 2015-10-07 12:49:42 +0900 (6838aeb) @@ -27,7 +27,11 @@ 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); +scan_info **grn_mrb_scan_info_build(grn_ctx *ctx, + grn_obj *expr, + int *n, + grn_operator op, + grn_bool record_exist); unsigned int grn_mrb_expr_estimate_size(grn_ctx *ctx, grn_obj *expr, grn_obj *table); Modified: lib/mrb/scripts/expression.rb (+2 -2) =================================================================== --- lib/mrb/scripts/expression.rb 2015-10-07 12:42:06 +0900 (7b1199b) +++ lib/mrb/scripts/expression.rb 2015-10-07 12:49:42 +0900 (a3c79f6) @@ -5,9 +5,9 @@ require "expression_size_estimator" module Groonga class Expression - def build_scan_info(op, size) + def build_scan_info(op, record_exist) begin - builder = ScanInfoBuilder.new(self, op, size) + builder = ScanInfoBuilder.new(self, op, record_exist) builder.build rescue => error Context.instance.record_error(:invalid_argument, error) Modified: lib/mrb/scripts/scan_info_builder.rb (+3 -3) =================================================================== --- lib/mrb/scripts/scan_info_builder.rb 2015-10-07 12:42:06 +0900 (dc003f8) +++ lib/mrb/scripts/scan_info_builder.rb 2015-10-07 12:49:42 +0900 (9baed0d) @@ -10,11 +10,11 @@ module Groonga CONST = 4 end - def initialize(expression, operator, size) + def initialize(expression, operator, record_exist) @data_list = [] @expression = expression @operator = operator - @size = size + @record_exist = record_exist end RELATION_OPERATORS = [ @@ -120,7 +120,7 @@ module Groonga end end - if @operator == Operator::OR and @size == 0 + if @operator == Operator::OR and !@record_exist first_data = @data_list.first if (first_data.flags & ScanInfo::Flags::PUSH) == 0 or first_data.logical_op != @operator Added: lib/scanner.c (+76 -0) 100644 =================================================================== --- /dev/null +++ lib/scanner.c 2015-10-07 12:49:42 +0900 (62bdf7c) @@ -0,0 +1,76 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "grn_scanner.h" + +static void +sis_free(grn_ctx *ctx, scan_info **sis, unsigned int n_sis) +{ + int i; + for (i = 0; i < n_sis; i++) { + grn_scan_info_close(ctx, sis[i]); + } + GRN_FREE(sis); +} + +grn_scanner * +grn_scanner_open(grn_ctx *ctx, + grn_obj *expr, + grn_operator op, + grn_bool record_exist) +{ + grn_scanner *scanner; + scan_info **sis; + unsigned int n_sis; + + sis = grn_scan_info_build(ctx, expr, &n_sis, op, record_exist); + if (!sis) { + return NULL; + } + + scanner = GRN_MALLOC(sizeof(grn_scanner)); + if (!scanner) { + sis_free(ctx, sis, n_sis); + return NULL; + } + + scanner->expr = expr; + scanner->rewritten_expr = NULL; + scanner->sis = sis; + scanner->n_sis = n_sis; + + return scanner; +} + +void +grn_scanner_close(grn_ctx *ctx, grn_scanner *scanner) +{ + if (!scanner) { + return; + } + + if (scanner->rewritten_expr) { + grn_obj_close(ctx, scanner->rewritten_expr); + } + + if (scanner->sis) { + sis_free(ctx, scanner->sis, scanner->n_sis); + } + + GRN_FREE(scanner); +} Modified: lib/sources.am (+2 -0) =================================================================== --- lib/sources.am 2015-10-07 12:42:06 +0900 (70306da) +++ lib/sources.am 2015-10-07 12:49:42 +0900 (5fdb9cc) @@ -52,6 +52,8 @@ libgroonga_la_SOURCES = \ grn_request_canceler.h \ rset.c \ grn_rset.h \ + scanner.c \ + grn_scanner.h \ scorer.c \ grn_scorer.h \ scorers.c \ -------------- next part -------------- HTML����������������������������...Download