Kouhei Sutou
null+****@clear*****
Wed Jul 8 14:30:13 JST 2015
Kouhei Sutou 2015-07-08 14:30:13 +0900 (Wed, 08 Jul 2015) New Revision: 188649a5ab0259e8ab94d0b7f25ec97f0cf6faaf https://github.com/groonga/groonga/commit/188649a5ab0259e8ab94d0b7f25ec97f0cf6faaf Message: mrb estimate_size: support "(... || ...) && (... || ...)" case Modified files: lib/mrb/scripts/expression_size_estimator.rb test/query_optimizer/suite/test_estimate_size.rb Modified: lib/mrb/scripts/expression_size_estimator.rb (+31 -28) =================================================================== --- lib/mrb/scripts/expression_size_estimator.rb 2015-07-08 14:13:11 +0900 (28b80fc) +++ lib/mrb/scripts/expression_size_estimator.rb 2015-07-08 14:30:13 +0900 (ba7cf11) @@ -11,43 +11,46 @@ module Groonga data_list = builder.build return @table_size if data_list.nil? - or_data_list = group_data_list(data_list) - or_sizes = or_data_list.collect do |and_data_list| - and_sizes = and_data_list.collect do |data| - size = estimate_data(data) - if data.logical_op == Operator::AND_NOT - size = @table_size - size - size = 0 if size < 0 - end - size - end - and_sizes.min - end - or_sizes.max - end - - private - def group_data_list(data_list) - or_data_list = [[]] + current_size = 0 + sizes = [] data_list.each do |data| - next if data.op == Operator::NOP - - and_data_list = or_data_list.last - if and_data_list.empty? - and_data_list << data - else + if (data.flags & ScanInfo::Flags::POP) != 0 + size = sizes.pop case data.logical_op when Operator::AND, Operator::AND_NOT - and_data_list << data + current_size = size if size < current_size + when Operator::OR + current_size = size if size > current_size else - and_data_list = [data] - or_data_list << and_data_list + message = "invalid logical operator: <#{data.logical_op.inspect}>" + raise InvalidArgument, message + end + else + if (data.flags & ScanInfo::Flags::PUSH) != 0 + sizes.push(current_size) + current_size = 0 + end + + size = estimate_data(data) + case data.logical_op + when Operator::AND + current_size = size if size < current_size + when Operator::AND_NOT + size = @table_size - size + size = 0 if size < 0 + current_size = size if size < current_size + when Operator::OR + current_size = size if size > current_size + else + message = "invalid logical operator: <#{data.logical_op.inspect}>" + raise InvalidArgument, message end end end - or_data_list + current_size end + private def estimate_data(data) search_index = data.search_indexes.first return @table_size if search_index.nil? Modified: test/query_optimizer/suite/test_estimate_size.rb (+24 -0) =================================================================== --- test/query_optimizer/suite/test_estimate_size.rb 2015-07-08 14:13:11 +0900 (cad86b2) +++ test/query_optimizer/suite/test_estimate_size.rb 2015-07-08 14:30:13 +0900 (3c1d0e1) @@ -488,5 +488,29 @@ class TestEstimateSize < QueryOptimizerTestCase "type == 1" + ")")) end + + def test_or_and + @logs.add(:message => "Groonga is fast", :type => 1) + @logs.add(:message => "Rroonga is fast", :type => 1) + @logs.add(:message => "Mroonga is fast", :type => 1) + @logs.add(:timestamp => "2015-02-19 02:17:00", :type => 2) + @logs.add(:timestamp => "2015-02-19 02:17:00", :type => 2) + @logs.add(:timestamp => "2015-02-19 02:18:00", :type => 2) + @logs.add(:timestamp => "2015-02-19 02:18:00", :type => 2) + @logs.add(:timestamp => "2015-02-19 02:19:00", :type => 3) + @logs.add(:timestamp => "2015-02-19 02:19:00", :type => 3) + @logs.add(:timestamp => "2015-02-19 02:19:00", :type => 3) + @logs.add(:timestamp => "2015-02-19 02:19:00", :type => 3) + + assert_equal(1, + estimate_size("(" + + "timestamp < '2015-02-19 02:19:00' || " + + "type == 2 " + + ") && " + + "(" + + "message @ 'Groonga' || " + + "message @ 'Rroonga'" + + ")")) + end end end -------------- next part -------------- HTML����������������������������...다운로드