[Groonga-commit] groonga/groonga at cf60218 [master] logical_range_filter: retry index search when sequential search is slow

Back to archive index

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����������������������������...
Télécharger 



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