Auto merge of #13243 - Veykril:search-memchr, r=Veykril

Use memmem when searching for usages in ide-db

We already have this dependency, so there is no reason not to use it as it is generally faster than std in our use case.
This commit is contained in:
bors 2022-09-16 14:28:12 +00:00
commit b6e3f41c2a
3 changed files with 21 additions and 11 deletions

1
Cargo.lock generated
View File

@ -660,6 +660,7 @@ dependencies = [
"indexmap",
"itertools",
"limit",
"memchr",
"once_cell",
"parser",
"profile",

View File

@ -20,6 +20,7 @@ either = "1.7.0"
itertools = "0.10.3"
arrayvec = "0.7.2"
indexmap = "1.9.1"
memchr = "2.5.0"
stdx = { path = "../stdx", version = "0.0.0" }
parser = { path = "../parser", version = "0.0.0" }

View File

@ -8,6 +8,7 @@
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
use memchr::memmem::Finder;
use once_cell::unsync::Lazy;
use parser::SyntaxKind;
use stdx::hash::NoHashHashMap;
@ -411,14 +412,17 @@ fn search(&self, sink: &mut dyn FnMut(FileId, FileReference) -> bool) {
Some(s) => s.as_str(),
None => return,
};
let finder = &Finder::new(name);
let include_self_kw_refs =
self.include_self_kw_refs.as_ref().map(|ty| (ty, Finder::new("Self")));
// these can't be closures because rust infers the lifetimes wrong ...
// for<'a> |text: &'a str, name: &'a str, search_range: TextRange| -> impl Iterator<Item = TextSize> + 'a { ... }
fn match_indices<'a>(
text: &'a str,
name: &'a str,
finder: &'a Finder<'a>,
search_range: TextRange,
) -> impl Iterator<Item = TextSize> + 'a {
text.match_indices(name).filter_map(move |(idx, _)| {
finder.find_iter(text.as_bytes()).filter_map(move |idx| {
let offset: TextSize = idx.try_into().unwrap();
if !search_range.contains_inclusive(offset) {
return None;
@ -427,6 +431,7 @@ fn match_indices<'a>(
})
}
// for<'a> |scope: &'a SearchScope| -> impl Iterator<Item = (Arc<String>, FileId, TextRange)> + 'a { ... }
fn scope_files<'a>(
sema: &'a Semantics<'_, RootDatabase>,
scope: &'a SearchScope,
@ -450,7 +455,7 @@ fn scope_files<'a>(
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
// Search for occurrences of the items name
for offset in match_indices(&text, name, search_range) {
for offset in match_indices(&text, finder, search_range) {
for name in sema.find_nodes_at_offset_with_descend(&tree, offset) {
if match name {
ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink),
@ -462,8 +467,8 @@ fn scope_files<'a>(
}
}
// Search for occurrences of the `Self` referring to our type
if let Some(self_ty) = &self.include_self_kw_refs {
for offset in match_indices(&text, "Self", search_range) {
if let Some((self_ty, finder)) = &include_self_kw_refs {
for offset in match_indices(&text, finder, search_range) {
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
return;
@ -479,20 +484,22 @@ fn scope_files<'a>(
let scope = search_scope
.intersection(&SearchScope::module_and_children(self.sema.db, module));
let is_crate_root = module.is_crate_root(self.sema.db);
let is_crate_root =
module.is_crate_root(self.sema.db).then(|| Finder::new("crate"));
let finder = &Finder::new("super");
for (text, file_id, search_range) in scope_files(sema, &scope) {
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
for offset in match_indices(&text, "super", search_range) {
for offset in match_indices(&text, finder, search_range) {
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
if self.found_name_ref(&name_ref, sink) {
return;
}
}
}
if is_crate_root {
for offset in match_indices(&text, "crate", search_range) {
if let Some(finder) = &is_crate_root {
for offset in match_indices(&text, finder, search_range) {
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
if self.found_name_ref(&name_ref, sink) {
return;
@ -533,8 +540,9 @@ fn scope_files<'a>(
search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(text.as_str())));
let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
let finder = &Finder::new("self");
for offset in match_indices(&text, "self", search_range) {
for offset in match_indices(&text, finder, search_range) {
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
if self.found_self_module_name_ref(&name_ref, sink) {
return;