Kouhei Sutou
null+****@clear*****
Fri Nov 13 17:08:21 JST 2015
Kouhei Sutou 2015-11-13 17:08:21 +0900 (Fri, 13 Nov 2015) New Revision: cf60218c3457f5c2afed231c988eed02fac9e440 https://github.com/groonga/groonga/commit/cf60218c3457f5c2afed231c988eed02fac9e440 Message: logical_range_filter: retry index search when sequential search is slow Modified files: lib/mrb/mrb_index_cursor.c plugins/sharding/logical_range_filter.rb Modified: lib/mrb/mrb_index_cursor.c (+21 -4) =================================================================== --- lib/mrb/mrb_index_cursor.c 2015-11-13 13:46:54 +0900 (42b3fa2) +++ lib/mrb/mrb_index_cursor.c 2015-11-13 17:08:21 +0900 (ac3b6b3) @@ -123,7 +123,9 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self) grn_obj *expr_variable = NULL; int offset = 0; int limit = 10; + int max_n_unmatched_records = -1; int n_matched_records = 0; + int n_unmatched_records = 0; mrb_value mrb_index; grn_obj *index; grn_obj *lexicon; @@ -142,6 +144,7 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self) mrb_value mrb_expr; mrb_value mrb_offset; mrb_value mrb_limit; + mrb_value mrb_max_n_unmatched_records; mrb_expr = grn_mrb_options_get_lit(mrb, mrb_options, "expression"); if (!mrb_nil_p(mrb_expr)) { @@ -158,6 +161,12 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self) if (!mrb_nil_p(mrb_limit)) { limit = mrb_fixnum(mrb_limit); } + + mrb_max_n_unmatched_records = + grn_mrb_options_get_lit(mrb, mrb_options, "max_n_unmatched_records"); + if (!mrb_nil_p(mrb_max_n_unmatched_records)) { + max_n_unmatched_records = mrb_fixnum(mrb_max_n_unmatched_records); + } } if (limit <= 0) { @@ -169,19 +178,27 @@ mrb_grn_index_cursor_select(mrb_state *mrb, mrb_value self) lexicon = ((grn_ii *)index)->lexicon; data_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, index)); + if (max_n_unmatched_records < 0) { + max_n_unmatched_records = INT32_MAX; + } while ((posting = grn_index_cursor_next(ctx, index_cursor, &term_id))) { if (expr) { - grn_bool matched_raw; + grn_bool matched_raw = GRN_FALSE; grn_obj *matched; GRN_RECORD_SET(ctx, expr_variable, posting->rid); matched = grn_expr_exec(ctx, expr, 0); - if (!matched) { + if (matched) { + GRN_OBJ_IS_TRUE(ctx, matched, matched_raw); + } else { grn_mrb_ctx_check(mrb); - continue; } - GRN_OBJ_IS_TRUE(ctx, matched, matched_raw); + if (!matched_raw) { + n_unmatched_records++; + if (n_unmatched_records > max_n_unmatched_records) { + return mrb_fixnum_value(-1); + } continue; } } Modified: plugins/sharding/logical_range_filter.rb (+47 -37) =================================================================== --- plugins/sharding/logical_range_filter.rb 2015-11-13 13:46:54 +0900 (66570c0) +++ plugins/sharding/logical_range_filter.rb 2015-11-13 17:08:21 +0900 (993ccb4) @@ -224,40 +224,7 @@ module Groonga range_index = nil end - case @cover_type - when :all - filter_shard_all(range_index, expression_builder) - when :partial_min - if range_index - filter_by_range(range_index, - @target_range.min, @target_range.min_border, - nil, nil) - else - filter_table do |expression| - expression_builder.build_partial_min(expression) - end - end - when :partial_max - if range_index - filter_by_range(range_index, - nil, nil, - @target_range.max, @target_range.max_border) - else - filter_table do |expression| - expression_builder.build_partial_max(expression) - end - end - when :partial_min_and_max - if range_index - filter_by_range(range_index, - @target_range.min, @target_range.min_border, - @target_range.max, @target_range.max_border) - else - filter_table do |expression| - expression_builder.build_partial_min_and_max(expression) - end - end - end + execute_filter(range_index, expression_builder) end private @@ -444,6 +411,43 @@ module Groonga nil end + def execute_filter(range_index, expression_builder) + case @cover_type + when :all + filter_shard_all(range_index, expression_builder) + when :partial_min + if range_index + filter_by_range(range_index, expression_builder, + @target_range.min, @target_range.min_border, + nil, nil) + else + filter_table do |expression| + expression_builder.build_partial_min(expression) + end + end + when :partial_max + if range_index + filter_by_range(range_index, expression_builder, + nil, nil, + @target_range.max, @target_range.max_border) + else + filter_table do |expression| + expression_builder.build_partial_max(expression) + end + end + when :partial_min_and_max + if range_index + filter_by_range(range_index, expression_builder, + @target_range.min, @target_range.min_border, + @target_range.max, @target_range.max_border) + else + filter_table do |expression| + expression_builder.build_partial_min_and_max(expression) + end + end + end + end + def filter_shard_all(range_index, expression_builder) table =****@shard***** if****@filte*****? @@ -452,7 +456,7 @@ module Groonga return end if range_index - filter_by_range(range_index, + filter_by_range(range_index, expression_builder, nil, nil, nil, nil) else @@ -460,7 +464,7 @@ module Groonga end else if range_index - filter_by_range(range_index, + filter_by_range(range_index, expression_builder, nil, nil, nil, nil) else @@ -480,7 +484,7 @@ module Groonga end end - def filter_by_range(range_index, + def filter_by_range(range_index, expression_builder, min, min_border, max, max_border) lexicon = range_index.domain data_table = range_index.range @@ -503,6 +507,7 @@ module Groonga else options[:limit] = current_limit end + options[:max_n_unmatched_records] = options[:limit] * 100 if @filter create_expression(data_table) do |expression| expression.parse(@filter) @@ -516,6 +521,11 @@ module Groonga n_matched_records = index_cursor.select(result_set, options) end end + if n_matched_records == -1 + result_set.close + execute_filter(nil, expression_builder) + return + end end rescue result_set.close -------------- next part -------------- HTML����������������������������... Download