Skip to content

Commit b6e3f41

Browse files
committed
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.
2 parents 870bfc7 + b73fa0b commit b6e3f41

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ide-db/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ either = "1.7.0"
2020
itertools = "0.10.3"
2121
arrayvec = "0.7.2"
2222
indexmap = "1.9.1"
23+
memchr = "2.5.0"
2324

2425
stdx = { path = "../stdx", version = "0.0.0" }
2526
parser = { path = "../parser", version = "0.0.0" }

crates/ide-db/src/search.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{mem, sync::Arc};
88

99
use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
1010
use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
11+
use memchr::memmem::Finder;
1112
use once_cell::unsync::Lazy;
1213
use parser::SyntaxKind;
1314
use stdx::hash::NoHashHashMap;
@@ -411,14 +412,17 @@ impl<'a> FindUsages<'a> {
411412
Some(s) => s.as_str(),
412413
None => return,
413414
};
415+
let finder = &Finder::new(name);
416+
let include_self_kw_refs =
417+
self.include_self_kw_refs.as_ref().map(|ty| (ty, Finder::new("Self")));
414418

415-
// these can't be closures because rust infers the lifetimes wrong ...
419+
// for<'a> |text: &'a str, name: &'a str, search_range: TextRange| -> impl Iterator<Item = TextSize> + 'a { ... }
416420
fn match_indices<'a>(
417421
text: &'a str,
418-
name: &'a str,
422+
finder: &'a Finder<'a>,
419423
search_range: TextRange,
420424
) -> impl Iterator<Item = TextSize> + 'a {
421-
text.match_indices(name).filter_map(move |(idx, _)| {
425+
finder.find_iter(text.as_bytes()).filter_map(move |idx| {
422426
let offset: TextSize = idx.try_into().unwrap();
423427
if !search_range.contains_inclusive(offset) {
424428
return None;
@@ -427,6 +431,7 @@ impl<'a> FindUsages<'a> {
427431
})
428432
}
429433

434+
// for<'a> |scope: &'a SearchScope| -> impl Iterator<Item = (Arc<String>, FileId, TextRange)> + 'a { ... }
430435
fn scope_files<'a>(
431436
sema: &'a Semantics<'_, RootDatabase>,
432437
scope: &'a SearchScope,
@@ -450,7 +455,7 @@ impl<'a> FindUsages<'a> {
450455
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
451456

452457
// Search for occurrences of the items name
453-
for offset in match_indices(&text, name, search_range) {
458+
for offset in match_indices(&text, finder, search_range) {
454459
for name in sema.find_nodes_at_offset_with_descend(&tree, offset) {
455460
if match name {
456461
ast::NameLike::NameRef(name_ref) => self.found_name_ref(&name_ref, sink),
@@ -462,8 +467,8 @@ impl<'a> FindUsages<'a> {
462467
}
463468
}
464469
// Search for occurrences of the `Self` referring to our type
465-
if let Some(self_ty) = &self.include_self_kw_refs {
466-
for offset in match_indices(&text, "Self", search_range) {
470+
if let Some((self_ty, finder)) = &include_self_kw_refs {
471+
for offset in match_indices(&text, finder, search_range) {
467472
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
468473
if self.found_self_ty_name_ref(self_ty, &name_ref, sink) {
469474
return;
@@ -479,20 +484,22 @@ impl<'a> FindUsages<'a> {
479484
let scope = search_scope
480485
.intersection(&SearchScope::module_and_children(self.sema.db, module));
481486

482-
let is_crate_root = module.is_crate_root(self.sema.db);
487+
let is_crate_root =
488+
module.is_crate_root(self.sema.db).then(|| Finder::new("crate"));
489+
let finder = &Finder::new("super");
483490

484491
for (text, file_id, search_range) in scope_files(sema, &scope) {
485492
let tree = Lazy::new(move || sema.parse(file_id).syntax().clone());
486493

487-
for offset in match_indices(&text, "super", search_range) {
494+
for offset in match_indices(&text, finder, search_range) {
488495
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
489496
if self.found_name_ref(&name_ref, sink) {
490497
return;
491498
}
492499
}
493500
}
494-
if is_crate_root {
495-
for offset in match_indices(&text, "crate", search_range) {
501+
if let Some(finder) = &is_crate_root {
502+
for offset in match_indices(&text, finder, search_range) {
496503
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
497504
if self.found_name_ref(&name_ref, sink) {
498505
return;
@@ -533,8 +540,9 @@ impl<'a> FindUsages<'a> {
533540
search_range.unwrap_or_else(|| TextRange::up_to(TextSize::of(text.as_str())));
534541

535542
let tree = Lazy::new(|| sema.parse(file_id).syntax().clone());
543+
let finder = &Finder::new("self");
536544

537-
for offset in match_indices(&text, "self", search_range) {
545+
for offset in match_indices(&text, finder, search_range) {
538546
for name_ref in sema.find_nodes_at_offset_with_descend(&tree, offset) {
539547
if self.found_self_module_name_ref(&name_ref, sink) {
540548
return;

0 commit comments

Comments
 (0)