Skip to content

Commit

Permalink
Support estimating prefix search
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Jun 10, 2016
1 parent 9c3b780 commit eb6816e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
26 changes: 26 additions & 0 deletions lib/mrb/scripts/expression_size_estimator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def estimate_data(data)
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
Expand Down Expand Up @@ -134,6 +136,30 @@ def estimate_range(data, index_column)
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|
Expand Down
31 changes: 31 additions & 0 deletions test/mruby/suite/query_optimizer/test_estimate_size.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,37 @@ def test_have_record
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|
Expand Down

0 comments on commit eb6816e

Please sign in to comment.