Kouhei Sutou
null+****@clear*****
Fri Feb 20 14:41:11 JST 2015
Kouhei Sutou 2015-02-20 14:41:11 +0900 (Fri, 20 Feb 2015) New Revision: efcebbf70283299c2a16cd9ca8a8f884105f977f https://github.com/groonga/groonga/commit/efcebbf70283299c2a16cd9ca8a8f884105f977f Message: mrb: support estimating between() result 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 (+35 -0) =================================================================== --- lib/mrb/scripts/expression_size_estimator.rb 2015-02-20 14:40:38 +0900 (3d34321) +++ lib/mrb/scripts/expression_size_estimator.rb 2015-02-20 14:41:11 +0900 (234b05d) @@ -24,6 +24,11 @@ module Groonga Operator::GREATER, Operator::GREATER_EQUAL size = estimate_range(data, search_index) + when Operator::CALL + procedure = data.args.first + if procedure.is_a?(Procedure) and procedure.name == "between" + size = estimate_between(data, search_index) + end end size || @table.size end @@ -70,5 +75,35 @@ module Groonga index_column.estimate_size(:lexicon_cursor => cursor) end end + + def estimate_between(data, search_index) + index_column = search_index.index_column + if index_column.is_a?(Accessor) + # TODO + return nil + end + + lexicon = index_column.lexicon + _, _, min, min_border, max, max_border = data.args + options = { + :min => min, + :max => max, + :flags => 0, + } + if min_border == "include" + options[:flags] |= TableCursorFlags::LT + else + options[:flags] |= TableCursorFlags::LE + end + if max_border == "include" + options[:flags] |= TableCursorFlags::GT + else + options[:flags] |= TableCursorFlags::GE + end + + TableCursor.open(lexicon, options) do |cursor| + index_column.estimate_size(:lexicon_cursor => cursor) + end + end end end Modified: test/query_optimizer/suite/test_estimate_size.rb (+41 -0) =================================================================== --- test/query_optimizer/suite/test_estimate_size.rb 2015-02-20 14:40:38 +0900 (cc51e27) +++ test/query_optimizer/suite/test_estimate_size.rb 2015-02-20 14:41:11 +0900 (f13bb92) @@ -166,4 +166,45 @@ class TestEstimateSize < QueryOptimizerTestCase assert_equal(8, estimate_size("timestamp >= '2015-02-19 02:18:00'")) end end + + class TestBetweenSearch < self + def setup + Groonga::Schema.define do |schema| + schema.create_table("Logs") do |table| + table.time("timestamp") + end + + schema.create_table("Times", + :type => :patricia_trie, + :key_type => :time) do |table| + table.index("Logs", "timestamp") + end + end + super + end + + def test_no_record + assert_equal(0, + estimate_size("between(timestamp, " + + "'2015-02-19 02:18:00', 'include', " + + "'2015-02-19 02:20:00', 'exclude')")) + end + + def test_have_record + @logs.add(:timestamp => "2015-02-19 02:17:00") + @logs.add(:timestamp => "2015-02-19 02:17:00") + @logs.add(:timestamp => "2015-02-19 02:18:00") + @logs.add(:timestamp => "2015-02-19 02:18:00") + @logs.add(:timestamp => "2015-02-19 02:19:00") + @logs.add(:timestamp => "2015-02-19 02:19:00") + @logs.add(:timestamp => "2015-02-19 02:20:00") + @logs.add(:timestamp => "2015-02-19 02:20:00") + @logs.add(:timestamp => "2015-02-19 02:21:00") + @logs.add(:timestamp => "2015-02-19 02:21:00") + assert_equal(12, + estimate_size("between(timestamp, " + + "'2015-02-19 02:18:00', 'include', " + + "'2015-02-19 02:20:00', 'exclude')")) + end + end end -------------- next part -------------- HTML����������������������������... ダウンロード