[Groonga-commit] groonga/groonga at b98cca8 [master] Add in_values optimizer

Back to archive index

Kouhei Sutou null+****@clear*****
Tue May 22 14:06:44 JST 2018


Kouhei Sutou	2018-05-22 14:06:44 +0900 (Tue, 22 May 2018)

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

  Message:
    Add in_values optimizer

  Modified files:
    plugins/expression_rewriters/optimizer.rb

  Modified: plugins/expression_rewriters/optimizer.rb (+57 -7)
===================================================================
--- plugins/expression_rewriters/optimizer.rb    2018-05-22 10:15:15 +0900 (3dfee681d)
+++ plugins/expression_rewriters/optimizer.rb    2018-05-22 14:06:44 +0900 (fcf0982de)
@@ -27,6 +27,9 @@ module Groonga
           when Operator::AND
             optimized_sub_nodes =
               optimize_and_sub_nodes(table, optimized_sub_nodes)
+          when Operator::OR
+            optimized_sub_nodes =
+              optimize_or_sub_nodes(table, optimized_sub_nodes)
           end
           ExpressionTree::LogicalOperation.new(node.operator,
                                                optimized_sub_nodes)
@@ -50,12 +53,12 @@ module Groonga
         end
       end
 
-      def optimize_and_sub_nodes(table, sub_nodes)
-        grouped_sub_nodes = sub_nodes.group_by do |sub_node|
-          case sub_node
+      def group_nodes(nodes)
+        nodes.group_by do |node|
+          case node
           when ExpressionTree::BinaryOperation
-            if sub_node.left.is_a?(ExpressionTree::Variable)
-              sub_node.left.column
+            if node.left.is_a?(ExpressionTree::Variable)
+              node.left.column
             else
               nil
             end
@@ -63,11 +66,15 @@ module Groonga
             nil
           end
         end
+      end
+
+      def optimize_and_sub_nodes(table, sub_nodes)
+        grouped_sub_nodes = group_nodes(sub_nodes)
 
         optimized_nodes = []
         grouped_sub_nodes.each do |column, grouped_nodes|
           if column
-            grouped_nodes = optimize_grouped_nodes(column, grouped_nodes)
+            grouped_nodes = optimize_grouped_and_nodes(column, grouped_nodes)
           end
           optimized_nodes.concat(grouped_nodes)
         end
@@ -85,7 +92,7 @@ module Groonga
         Operator::LESS_EQUAL,
         Operator::GREATER_EQUAL,
       ]
-      def optimize_grouped_nodes(column, grouped_nodes)
+      def optimize_grouped_and_nodes(column, grouped_nodes)
         target_nodes, done_nodes = grouped_nodes.partition do |node|
           node.is_a?(ExpressionTree::BinaryOperation) and
             COMPARISON_OPERATORS.include?(node.operator) and
@@ -142,6 +149,49 @@ module Groonga
         ]
         ExpressionTree::FunctionCall.new(between, arguments)
       end
+
+      def optimize_or_sub_nodes(table, sub_nodes)
+        grouped_sub_nodes = group_nodes(sub_nodes)
+
+        optimized_nodes = []
+        grouped_sub_nodes.each do |column, grouped_nodes|
+          if column
+            grouped_nodes = optimize_grouped_or_nodes(column, grouped_nodes)
+          end
+          optimized_nodes.concat(grouped_nodes)
+        end
+        optimized_nodes
+      end
+
+      def optimize_grouped_or_nodes(column, grouped_nodes)
+        target_nodes, done_nodes = grouped_nodes.partition do |node|
+          node.is_a?(ExpressionTree::BinaryOperation) and
+            node.operator == Operator::EQUAL and
+            node.right.is_a?(ExpressionTree::Constant)
+        end
+
+        if target_nodes.size > 1
+          in_values_node = try_optimize_in_values(column, target_nodes)
+          if in_values_node
+            done_nodes << in_values_node
+          else
+            done_nodes.concat(target_nodes)
+          end
+        else
+          done_nodes.concat(target_nodes)
+        end
+
+        done_nodes
+      end
+
+      def try_optimize_in_values(column, target_nodes)
+        in_values = ExpressionTree::Procedure.new(context["in_values"])
+        arguments = [ExpressionTree::Variable.new(column)]
+        target_nodes.each do |node|
+          arguments << node.right
+        end
+        ExpressionTree::FunctionCall.new(in_values, arguments)
+      end
     end
   end
 end
-------------- next part --------------
HTML����������������������������...
URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180522/bca8e15e/attachment-0001.htm 



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