[Groonga-commit] groonga/groonga at ca90830 [master] sharding: don't open shard table until it's needed

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Jul 22 13:12:33 JST 2015


Kouhei Sutou	2015-07-22 13:12:33 +0900 (Wed, 22 Jul 2015)

  New Revision: ca90830890c486dc055dac94de655d626fd503ab
  https://github.com/groonga/groonga/commit/ca90830890c486dc055dac94de655d626fd503ab

  Message:
    sharding: don't open shard table until it's needed

  Modified files:
    plugins/sharding/logical_count.rb
    plugins/sharding/logical_enumerator.rb
    plugins/sharding/logical_range_filter.rb
    plugins/sharding/logical_select.rb
    plugins/sharding/logical_table_remove.rb

  Modified: plugins/sharding/logical_count.rb (+16 -10)
===================================================================
--- plugins/sharding/logical_count.rb    2015-07-22 13:12:11 +0900 (a2582dc)
+++ plugins/sharding/logical_count.rb    2015-07-22 13:12:33 +0900 (bea79dc)
@@ -17,23 +17,22 @@ module Groonga
         filter = input[:filter]
 
         total = 0
-        enumerator.each do |table, shard_key, shard_range|
-          total += count_n_records(table, filter,
-                                   shard_key, shard_range,
+        enumerator.each do |shard, shard_range|
+          total += count_n_records(filter, shard, shard_range,
                                    enumerator.target_range)
         end
         writer.write(total)
       end
 
       private
-      def log_use_range_index(use, table, line, method)
+      def log_use_range_index(use, table_name, line, method)
         message = "[logical_count]"
         if use
           message << "[range-index]"
         else
           message << "[select]"
         end
-        message << " <#{table.name}>"
+        message << " <#{table_name}>"
         Context.instance.logger.log(Logger::Level::DEBUG,
                                     __FILE__,
                                     line,
@@ -41,17 +40,24 @@ module Groonga
                                     message)
       end
 
-      def count_n_records(table, filter,
-                          shard_key, shard_range,
-                          target_range)
+      def count_n_records(filter, shard, shard_range, target_range)
         cover_type = target_range.cover_type(shard_range)
         return 0 if cover_type == :none
 
+        shard_key = shard.key
+        if shard_key.nil?
+          message = "[logical_count] shard_key doesn't exist: " +
+                    "<#{shard.key_name}>"
+          raise InvalidArgument, message
+        end
+        table = shard.table
+        table_name = shard.table_name
+
         expression_builder = RangeExpressionBuilder.new(shard_key,
                                                         target_range,
                                                         filter)
         if cover_type == :all
-          log_use_range_index(false, table, __LINE__, __method__)
+          log_use_range_index(false, table_name, __LINE__, __method__)
           if filter.nil?
             return table.size
           else
@@ -70,7 +76,7 @@ module Groonga
         end
 
         use_range_index = (!range_index.nil?)
-        log_use_range_index(use_range_index, table, __LINE__, __method__)
+        log_use_range_index(use_range_index, table_name, __LINE__, __method__)
 
         case cover_type
         when :partial_min

  Modified: plugins/sharding/logical_enumerator.rb (+22 -19)
===================================================================
--- plugins/sharding/logical_enumerator.rb    2015-07-22 13:12:11 +0900 (432bcea)
+++ plugins/sharding/logical_enumerator.rb    2015-07-22 13:12:33 +0900 (c34b1a6)
@@ -22,7 +22,6 @@ module Groonga
       def each_internal(order)
         context = Context.instance
         each_shard_with_around(order) do |prev_shard, current_shard, next_shard|
-          table = current_shard.table
           shard_range_data = current_shard.range_data
           shard_range = nil
 
@@ -52,16 +51,7 @@ module Groonga
                                             shard_range_data.day)
           end
 
-          physical_shard_key_name = "#{table.name}.#{@shard_key_name}"
-          shard_key = context[physical_shard_key_name]
-          if shard_key.nil?
-            message =
-              "[#{@command_name}] shard_key doesn't exist: " +
-              "<#{physical_shard_key_name}>"
-            raise InvalidArgument, message
-          end
-
-          yield(table, shard_key, shard_range)
+          yield(current_shard, shard_range)
         end
       end
 
@@ -70,10 +60,10 @@ module Groonga
         prefix = "#{@logical_table}_"
 
         shards = [nil]
-        context.database.each_table(:prefix => prefix,
-                                    :order_by => :key,
-                                    :order => order) do |table|
-          shard_range_raw = table.name[prefix.size..-1]
+        context.database.each_name(:prefix => prefix,
+                                   :order_by => :key,
+                                   :order => order) do |name|
+          shard_range_raw = name[prefix.size..-1]
 
           case shard_range_raw
           when /\A(\d{4})(\d{2})\z/
@@ -84,7 +74,7 @@ module Groonga
             next
           end
 
-          shards << Shard.new(table, shard_range_data)
+          shards << Shard.new(name, @shard_key_name, shard_range_data)
           next if shards.size < 3
           yield(*shards)
           shards.shift
@@ -119,11 +109,24 @@ module Groonga
       end
 
       class Shard
-        attr_reader :table, :range_data
-        def initialize(table, range_data)
-          @table = table
+        attr_reader :table_name, :key_name, :range_data
+        def initialize(table_name, key_name, range_data)
+          @table_name = table_name
+          @key_name = key_name
           @range_data = range_data
         end
+
+        def table
+          @table ||= Context.instance[@table_name]
+        end
+
+        def full_key_name
+          "#{@table_name}.#{@key_name}"
+        end
+
+        def key
+          @key ||= Context.instance[full_key_name]
+        end
       end
 
       class ShardRangeData

  Modified: plugins/sharding/logical_range_filter.rb (+54 -44)
===================================================================
--- plugins/sharding/logical_range_filter.rb    2015-07-22 13:12:11 +0900 (90c927e)
+++ plugins/sharding/logical_range_filter.rb    2015-07-22 13:12:33 +0900 (fca7a37)
@@ -155,23 +155,21 @@ module Groonga
         end
 
         def execute
-          first_table = nil
+          first_shard = nil
           enumerator =****@conte*****
+          target_range = enumerator.target_range
           if****@conte***** == :descending
             each_method = :reverse_each
           else
             each_method = :each
           end
-          enumerator.send(each_method) do |table, shard_key, shard_range|
-            first_table ||= table
-            next if table.empty?
-
-            shard_executor = ShardExecutor.new(@context,
-                                               table, shard_key, shard_range)
+          enumerator.send(each_method) do |shard, shard_range|
+            first_shard ||= shard
+            shard_executor = ShardExecutor.new(@context, shard, shard_range)
             shard_executor.execute
             break if****@conte*****_limit == 0
           end
-          if first_table.nil?
+          if first_shard.nil?
             message =
               "[logical_range_filter] no shard exists: " +
               "logical_table: <#{enumerator.logical_table}>: " +
@@ -180,17 +178,16 @@ module Groonga
           end
           if****@conte*****_sets.empty?
             result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC,
-                                          :key_type => first_table)
+                                          :key_type => first_shard.table)
             @context.result_sets << result_set
           end
         end
       end
 
       class ShardExecutor
-        def initialize(context, table, shard_key, shard_range)
+        def initialize(context, shard, shard_range)
           @context = context
-          @table = table
-          @shard_key = shard_key
+          @shard = shard
           @shard_range = shard_range
 
           @filter =****@conte*****
@@ -200,26 +197,36 @@ module Groonga
           @target_range =****@conte*****_range
 
           @cover_type = @target_range.cover_type(@shard_range)
-
-          @expression_builder = RangeExpressionBuilder.new(@shard_key,
-                                                           @target_range,
-                                                           @filter)
         end
 
         def execute
           return if @cover_type == :none
+          return if****@shard*****?
 
-          index_info = @shard_key.find_index(Operator::LESS)
+          shard_key =****@shard*****
+          if shard_key.nil?
+            message = "[logical_range_filter] shard_key doesn't exist: " +
+                      "<#{@shard.key_name}>"
+            raise InvalidArgument, message
+          end
+
+          expression_builder = RangeExpressionBuilder.new(shard_key,
+                                                          @target_range,
+                                                          @filter)
+
+          index_info = shard_key.find_index(Operator::LESS)
           if index_info
             range_index = index_info.index
-            range_index = nil unless use_range_index?(range_index)
+            unless use_range_index?(range_index, expression_builder)
+              range_index = nil
+            end
           else
             range_index = nil
           end
 
           case @cover_type
           when :all
-            filter_shard_all(range_index)
+            filter_shard_all(range_index, expression_builder)
           when :partial_min
             if range_index
               filter_by_range(range_index,
@@ -227,7 +234,7 @@ module Groonga
                               nil, nil)
             else
               filter_table do |expression|
-                @expression_builder.build_partial_min(expression)
+                expression_builder.build_partial_min(expression)
               end
             end
           when :partial_max
@@ -237,7 +244,7 @@ module Groonga
                               @target_range.max, @target_range.max_border)
             else
               filter_table do |expression|
-                @expression_builder.build_partial_max(expression)
+                expression_builder.build_partial_max(expression)
               end
             end
           when :partial_min_and_max
@@ -247,7 +254,7 @@ module Groonga
                               @target_range.max, @target_range.max_border)
             else
               filter_table do |expression|
-                @expression_builder.build_partial_min_and_max(expression)
+                expression_builder.build_partial_min_and_max(expression)
               end
             end
           end
@@ -261,7 +268,7 @@ module Groonga
           else
             message << "[select] "
           end
-          message << "<#{@table.name}>: "
+          message << "<#{@shard.table_name}>: "
           message << reason
           Context.instance.logger.log(Logger::Level::DEBUG,
                                       __FILE__,
@@ -272,7 +279,7 @@ module Groonga
           use
         end
 
-        def use_range_index?(range_index)
+        def use_range_index?(range_index, expression_builder)
           case****@conte*****_range_index
           when true
             return decide_use_range_index(true,
@@ -292,7 +299,7 @@ module Groonga
           end
 
           required_n_records =****@conte*****_offset + current_limit
-          max_n_records =****@table*****
+          max_n_records =****@shard*****
           if max_n_records <= required_n_records
             reason = "the number of required records (#{required_n_records}) "
             reason << ">= "
@@ -313,47 +320,48 @@ module Groonga
                                           __LINE__, __method__)
           end
 
+          table =****@shard*****
           estimated_n_records = 0
           case @cover_type
           when :all
             if @filter
-              create_expression(@table) do |expression|
-                @expression_builder.build_all(expression)
+              create_expression(table) do |expression|
+                expression_builder.build_all(expression)
                 unless range_index_available_expression?(expression,
                                                          __LINE__, __method__)
                   return false
                 end
-                estimated_n_records = expression.estimate_size(@table)
+                estimated_n_records = expression.estimate_size(table)
               end
             else
               estimated_n_records = max_n_records
             end
           when :partial_min
-            create_expression(@table) do |expression|
-              @expression_builder.build_partial_min(expression)
+            create_expression(table) do |expression|
+              expression_builder.build_partial_min(expression)
               unless range_index_available_expression?(expression,
                                                        __LINE__, __method__)
                 return false
               end
-              estimated_n_records = expression.estimate_size(@table)
+              estimated_n_records = expression.estimate_size(table)
             end
           when :partial_max
-            create_expression(@table) do |expression|
-              @expression_builder.build_partial_max(expression)
+            create_expression(table) do |expression|
+              expression_builder.build_partial_max(expression)
               unless range_index_available_expression?(expression,
                                                        __LINE__, __method__)
                 return false
               end
-              estimated_n_records = expression.estimate_size(@table)
+              estimated_n_records = expression.estimate_size(table)
             end
           when :partial_min_and_max
-            create_expression(@table) do |expression|
-              @expression_builder.build_partial_min_and_max(expression)
+            create_expression(table) do |expression|
+              expression_builder.build_partial_min_and_max(expression)
               unless range_index_available_expression?(expression,
                                                        __LINE__, __method__)
                 return false
               end
-              estimated_n_records = expression.estimate_size(@table)
+              estimated_n_records = expression.estimate_size(table)
             end
           end
 
@@ -421,10 +429,11 @@ module Groonga
           nil
         end
 
-        def filter_shard_all(range_index)
+        def filter_shard_all(range_index, expression_builder)
+          table =****@shard*****
           if****@filte*****?
-            if****@table***** <=****@conte*****_offset
-              @context.current_offset -=****@table*****
+            if table.size <=****@conte*****_offset
+              @context.current_offset -= table.size
               return
             end
             if range_index
@@ -432,7 +441,7 @@ module Groonga
                               nil, nil,
                               nil, nil)
             else
-              sort_result_set(@table)
+              sort_result_set(table)
             end
           else
             if range_index
@@ -441,7 +450,7 @@ module Groonga
                               nil, nil)
             else
               filter_table do |expression|
-                @expression_builder.build_all(expression)
+                expression_builder.build_all(expression)
               end
             end
           end
@@ -537,9 +546,10 @@ module Groonga
         end
 
         def filter_table
-          create_expression(@table) do |expression|
+          table =****@shard*****
+          create_expression(table) do |expression|
             yield(expression)
-            result_set =****@table*****(expression)
+            result_set = table.select(expression)
             sort_result_set(result_set)
           end
         end

  Modified: plugins/sharding/logical_select.rb (+29 -25)
===================================================================
--- plugins/sharding/logical_select.rb    2015-07-22 13:12:11 +0900 (3261a89)
+++ plugins/sharding/logical_select.rb    2015-07-22 13:12:33 +0900 (3761ecd)
@@ -412,17 +412,14 @@ module Groonga
 
         private
         def execute_search
-          first_table = nil
+          first_shard = nil
           enumerator =****@conte*****
-          enumerator.each do |table, shard_key, shard_range|
-            first_table ||= table
-            next if table.empty?
-
-            shard_executor = ShardExecutor.new(@context,
-                                               table, shard_key, shard_range)
+          enumerator.each do |shard, shard_range|
+            first_shard ||= shard
+            shard_executor = ShardExecutor.new(@context, shard, shard_range)
             shard_executor.execute
           end
-          if first_table.nil?
+          if first_shard.nil?
             message =
               "[logical_select] no shard exists: " +
               "logical_table: <#{enumerator.logical_table}>: " +
@@ -431,7 +428,7 @@ module Groonga
           end
           if****@conte*****_sets.empty?
             result_set = HashTable.create(:flags => ObjectFlags::WITH_SUBREC,
-                                          :key_type => first_table)
+                                          :key_type => first_shard.table)
             @context.result_sets << result_set
           end
         end
@@ -511,10 +508,9 @@ module Groonga
       end
 
       class ShardExecutor
-        def initialize(context, table, shard_key, shard_range)
+        def initialize(context, shard, shard_range)
           @context = context
-          @table = table
-          @shard_key = shard_key
+          @shard = shard
           @shard_range = shard_range
 
           @filter =****@conte*****
@@ -525,40 +521,47 @@ module Groonga
           @target_range =****@conte*****_range
 
           @cover_type = @target_range.cover_type(@shard_range)
-
-          @expression_builder = RangeExpressionBuilder.new(@shard_key,
-                                                           @target_range,
-                                                           @filter)
         end
 
         def execute
           return if @cover_type == :none
+          return if****@shard*****?
+
+          shard_key =****@shard*****
+          if shard_key.nil?
+            message = "[logical_select] shard_key doesn't exist: " +
+                      "<#{@shard.key_name}>"
+            raise InvalidArgument, message
+          end
 
+          expression_builder = RangeExpressionBuilder.new(shard_key,
+                                                          @target_range,
+                                                          @filter)
           case @cover_type
           when :all
-            filter_shard_all
+            filter_shard_all(expression_builder)
           when :partial_min
             filter_table do |expression|
-              @expression_builder.build_partial_min(expression)
+              expression_builder.build_partial_min(expression)
             end
           when :partial_max
             filter_table do |expression|
-              @expression_builder.build_partial_max(expression)
+              expression_builder.build_partial_max(expression)
             end
           when :partial_min_and_max
             filter_table do |expression|
-              @expression_builder.build_partial_min_and_max(expression)
+              expression_builder.build_partial_min_and_max(expression)
             end
           end
         end
 
         private
-        def filter_shard_all
+        def filter_shard_all(expression_builder)
           if****@filte*****?
-            add_result_set(@table)
+            add_result_set(@shard.table)
           else
             filter_table do |expression|
-              @expression_builder.build_all(expression)
+              expression_builder.build_all(expression)
             end
           end
         end
@@ -573,9 +576,10 @@ module Groonga
         end
 
         def filter_table
-          create_expression(@table) do |expression|
+          table =****@shard*****
+          create_expression(table) do |expression|
             yield(expression)
-            add_result_set(@table.select(expression))
+            add_result_set(table.select(expression))
           end
         end
 

  Modified: plugins/sharding/logical_table_remove.rb (+11 -6)
===================================================================
--- plugins/sharding/logical_table_remove.rb    2015-07-22 13:12:11 +0900 (f5c31c7)
+++ plugins/sharding/logical_table_remove.rb    2015-07-22 13:12:33 +0900 (6e988f6)
@@ -15,20 +15,25 @@ module Groonga
         enumerator = LogicalEnumerator.new("logical_table_remove", input)
 
         succeess = true
-        enumerator.each do |table, shard_key, shard_range|
-          remove_table(table,
-                       shard_key,
-                       shard_range,
-                       enumerator.target_range)
+        enumerator.each do |shard, shard_range|
+          remove_table(shard, shard_range, enumerator.target_range)
         end
         writer.write(succeess)
       end
 
       private
-      def remove_table(table, shard_key, shard_range, target_range)
+      def remove_table(shard, shard_range, target_range)
         cover_type = target_range.cover_type(shard_range)
         return if cover_type == :none
 
+        shard_key = shard.key
+        if shard_key.nil?
+          message = "[logical_table_remove] shard_key doesn't exist: " +
+                    "<#{shard.key_name}>"
+          raise InvalidArgument, message
+        end
+        table = shard.table
+
         expression_builder = RangeExpressionBuilder.new(shard_key,
                                                         target_range,
                                                         nil)
-------------- next part --------------
HTML����������������������������...
Descargar 



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