Kouhei Sutou
null+****@clear*****
Fri Jun 10 23:46:42 JST 2016
Kouhei Sutou 2016-06-10 23:46:42 +0900 (Fri, 10 Jun 2016) New Revision: eb6816eb47f50e4ae93506b32d08c4b2f9e85453 https://github.com/groonga/groonga/commit/eb6816eb47f50e4ae93506b32d08c4b2f9e85453 Message: Support estimating prefix search Modified files: lib/mrb/scripts/expression_size_estimator.rb test/mruby/suite/query_optimizer/test_estimate_size.rb Modified: lib/mrb/scripts/expression_size_estimator.rb (+26 -0) =================================================================== --- lib/mrb/scripts/expression_size_estimator.rb 2016-06-08 10:23:56 +0900 (4b7a139) +++ lib/mrb/scripts/expression_size_estimator.rb 2016-06-10 23:46:42 +0900 (0b0a19b) @@ -73,6 +73,8 @@ module Groonga Operator::GREATER, Operator::GREATER_EQUAL size = estimate_range(data, index_column) + when Operator::PREFIX + size = estimate_prefix(data, index_column) when Operator::CALL size = estimate_call(data, index_column) end @@ -134,6 +136,30 @@ module Groonga end end + def estimate_prefix(data, index_column) + lexicon = index_column.lexicon + n_terms = lexicon.size + return 0 if n_terms.zero? + + value = data.query.value + limit = n_terms / 0.01 + if limit < 10 + limit = 10 + elsif limit > 1000 + limit = 1000 + end + options = { + :min => value, + :limit => limit, + :flags => TableCursorFlags::PREFIX, + } + TableCursor.open(lexicon, options) do |cursor| + size = index_column.estimate_size(:lexicon_cursor => cursor) + size += 1 if cursor.next != ID::NIL + size + end + end + def estimate_call(data, index_column) procedure = data.args[0] arguments = data.args[1..-1].collect do |arg| Modified: test/mruby/suite/query_optimizer/test_estimate_size.rb (+31 -0) =================================================================== --- test/mruby/suite/query_optimizer/test_estimate_size.rb 2016-06-08 10:23:56 +0900 (99cb0bf) +++ test/mruby/suite/query_optimizer/test_estimate_size.rb 2016-06-10 23:46:42 +0900 (3515349) @@ -198,6 +198,37 @@ class TestEstimateSize < QueryOptimizerTestCase end end + class TestPrefixSearch < self + def setup + Groonga::Schema.define do |schema| + schema.create_table("Logs") do |table| + table.short_text("user") + end + + schema.create_table("Users", + :type => :patricia_trie, + :key_type => :short_text) do |table| + table.index("Logs", "user") + end + end + super + end + + def test_no_record + assert_equal(0, estimate_size("user @^ 'al'")) + end + + def test_have_record + @logs.add(:user => "bob") + @logs.add(:user => "alice") + @logs.add(:user => "alian") + @logs.add(:user => "alice") + @logs.add(:user => "alfread") + @logs.add(:user => "calros") + assert_equal(6, estimate_size("user @^ 'al'")) + end + end + class TestBetweenSearch < self def setup Groonga::Schema.define do |schema| -------------- next part -------------- HTML����������������������������... Download