Skip to content

Commit 646872d

Browse files
committed
Filter out indexed entries before fuzzy searching
We're doing extra work fuzzy matching across the whole index, even though only a subset of entries are considered valid results. We can filter out dependency/private entries *before* fuzzy matching, which should speed things up, assuming that fuzzy matching is more expensive than filtering.
1 parent 5802a0b commit 646872d

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

lib/ruby_indexer/lib/ruby_indexer/index.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,13 @@ def prefix_search(query, nesting = nil)
195195
end
196196

197197
# Fuzzy searches index entries based on Jaro-Winkler similarity. If no query is provided, all entries are returned
198-
#: (String? query) -> Array[Entry]
199-
def fuzzy_search(query)
198+
#: (String? query) ?{ (Entry) -> bool? } -> Array[Entry]
199+
def fuzzy_search(query, &condition)
200200
unless query
201201
entries = @entries.filter_map do |_name, entries|
202202
next if entries.first.is_a?(Entry::SingletonClass)
203203

204+
entries = entries.select(&condition) if condition
204205
entries
205206
end
206207

@@ -212,6 +213,9 @@ def fuzzy_search(query)
212213
results = @entries.filter_map do |name, entries|
213214
next if entries.first.is_a?(Entry::SingletonClass)
214215

216+
entries = entries.select(&condition) if condition
217+
next if entries.empty?
218+
215219
similarity = DidYouMean::JaroWinkler.distance(name.gsub("::", "").downcase, normalized_query)
216220
[entries, -similarity] if similarity > ENTRY_SIMILARITY_THRESHOLD
217221
end

lib/ruby_lsp/requests/workspace_symbol.rb

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,7 @@ def initialize(global_state, query)
2020
# @override
2121
#: -> Array[Interface::WorkspaceSymbol]
2222
def perform
23-
@index.fuzzy_search(@query).filter_map do |entry|
24-
uri = entry.uri
25-
file_path = uri.full_path
26-
27-
# We only show symbols declared in the workspace
28-
in_dependencies = file_path && !not_in_dependencies?(file_path)
29-
next if in_dependencies
30-
31-
# We should never show private symbols when searching the entire workspace
32-
next if entry.private?
33-
23+
fuzzy_search.filter_map do |entry|
3424
kind = kind_for_entry(entry)
3525
loc = entry.location
3626

@@ -44,7 +34,7 @@ def perform
4434
container_name: container.join("::"),
4535
kind: kind,
4636
location: Interface::Location.new(
47-
uri: uri.to_s,
37+
uri: entry.uri.to_s,
4838
range: Interface::Range.new(
4939
start: Interface::Position.new(line: loc.start_line - 1, character: loc.start_column),
5040
end: Interface::Position.new(line: loc.end_line - 1, character: loc.end_column),
@@ -53,6 +43,24 @@ def perform
5343
)
5444
end
5545
end
46+
47+
private
48+
49+
#: -> Array[RubyIndexer::Entry]
50+
def fuzzy_search
51+
@index.fuzzy_search(@query) do |entry|
52+
file_path = entry.uri.full_path
53+
54+
# We only show symbols declared in the workspace
55+
in_dependencies = file_path && !not_in_dependencies?(file_path)
56+
next if in_dependencies
57+
58+
# We should never show private symbols when searching the entire workspace
59+
next if entry.private?
60+
61+
true
62+
end
63+
end
5664
end
5765
end
5866
end

0 commit comments

Comments
 (0)