Navigation Menu

Skip to content

Commit

Permalink
Add grn_scanner
Browse files Browse the repository at this point in the history
It's for supporting rewriting grn_expr. (Rewriting grn_expr isn't
implemented yet.)
  • Loading branch information
kou committed Oct 7, 2015
1 parent 81aadf4 commit d45a32b
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 26 deletions.
34 changes: 17 additions & 17 deletions lib/expr.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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; }
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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_);
Expand Down Expand Up @@ -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++) {
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions lib/grn_expr.h
Expand Up @@ -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,
Expand Down
43 changes: 43 additions & 0 deletions lib/grn_scanner.h
@@ -0,0 +1,43 @@
/* -*- 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
*/

#ifndef GRN_SCANNER_H
#define GRN_SCANNER_H

#include "grn_expr.h"

#ifdef __cplusplus
extern "C" {
#endif

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_SCANNER_H */
9 changes: 6 additions & 3 deletions lib/mrb/mrb_expr.c
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion lib/mrb/mrb_expr.h
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions lib/mrb/scripts/expression.rb
Expand Up @@ -5,9 +5,9 @@

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)
Expand Down
6 changes: 3 additions & 3 deletions lib/mrb/scripts/scan_info_builder.rb
Expand Up @@ -10,11 +10,11 @@ module Status
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 = [
Expand Down Expand Up @@ -120,7 +120,7 @@ def build
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
Expand Down
76 changes: 76 additions & 0 deletions lib/scanner.c
@@ -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);
}
2 changes: 2 additions & 0 deletions lib/sources.am
Expand Up @@ -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 \
Expand Down

0 comments on commit d45a32b

Please sign in to comment.