From 18b380c931cc1e8ebdba350ecb6bff36904ea304 Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 14:15:58 +0100 Subject: [PATCH 1/6] feat: dont do needless search when we reach max depth --- crates/ignore/src/dir.rs | 19 ++++++++++++++++--- crates/ignore/src/walk.rs | 10 +++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index 2577665d5c..9963f2517b 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -198,7 +198,7 @@ impl Ignore { ig = prebuilt.clone(); continue; } - let (mut igtmp, err) = ig.add_child_path(parent); + let (mut igtmp, err) = ig.add_child_path(parent, false); errs.maybe_push(err); igtmp.is_absolute_parent = true; igtmp.absolute_base = Some(absolute_base.clone()); @@ -226,12 +226,25 @@ impl Ignore { &self, dir: P, ) -> (Ignore, Option) { - let (ig, err) = self.add_child_path(dir.as_ref()); + let (ig, err) = self.add_child_path(dir.as_ref(), false); + (Ignore(Arc::new(ig)), err) + } + + pub(crate) fn add_child2>( + &self, + dir: P, + is_leaf: bool, + ) -> (Ignore, Option) { + let (ig, err) = self.add_child_path(dir.as_ref(), is_leaf); (Ignore(Arc::new(ig)), err) } /// Like add_child, but takes a full path and returns an IgnoreInner. - fn add_child_path(&self, dir: &Path) -> (IgnoreInner, Option) { + fn add_child_path( + &self, + dir: &Path, + is_leaf: bool, + ) -> (IgnoreInner, Option) { let git_type = if self.0.opts.require_git && (self.0.opts.git_ignore || self.0.opts.git_exclude) { diff --git a/crates/ignore/src/walk.rs b/crates/ignore/src/walk.rs index 1f7d06e55c..d1445c2929 100644 --- a/crates/ignore/src/walk.rs +++ b/crates/ignore/src/walk.rs @@ -585,6 +585,7 @@ impl WalkBuilder { max_filesize: self.max_filesize, skip: self.skip.clone(), filter: self.filter.clone(), + max_depth: max_depth, } } @@ -918,6 +919,7 @@ pub struct Walk { max_filesize: Option, skip: Option>, filter: Option, + max_depth: Option, } impl Walk { @@ -1019,7 +1021,13 @@ impl Iterator for Walk { self.ig = igtmp; continue; } - let (igtmp, err) = self.ig.add_child(ent.path()); + + let is_leaf = self + .max_depth + .map(|max| ent.depth() >= max) + .unwrap_or(false); + + let (igtmp, err) = self.ig.add_child2(ent.path(), is_leaf); self.ig = igtmp; ent.err = err; return Some(Ok(ent)); From d4e1756077f9d11083349f6b81c16aab3ac79e73 Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 14:19:36 +0100 Subject: [PATCH 2/6] actually use is_leaf --- crates/ignore/src/dir.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index 9963f2517b..409d957610 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -267,7 +267,7 @@ impl Ignore { errs.maybe_push(err); m }; - let ig_matcher = if !self.0.opts.ignore { + let ig_matcher = if is_leaf || !self.0.opts.ignore { Gitignore::empty() } else { let (m, err) = create_gitignore( @@ -279,7 +279,7 @@ impl Ignore { errs.maybe_push(err); m }; - let gi_matcher = if !self.0.opts.git_ignore { + let gi_matcher = if is_leaf || !self.0.opts.git_ignore { Gitignore::empty() } else { let (m, err) = create_gitignore( @@ -291,7 +291,7 @@ impl Ignore { errs.maybe_push(err); m }; - let gi_exclude_matcher = if !self.0.opts.git_exclude { + let gi_exclude_matcher = if is_leaf || !self.0.opts.git_exclude { Gitignore::empty() } else { match resolve_git_commondir(dir, git_type) { From 96bd451985599dd05aed491e4cc6f036b48a942b Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 14:31:17 +0100 Subject: [PATCH 3/6] use is_leaf more --- crates/ignore/src/dir.rs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index 409d957610..527c809a03 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -245,8 +245,9 @@ impl Ignore { dir: &Path, is_leaf: bool, ) -> (IgnoreInner, Option) { - let git_type = if self.0.opts.require_git - && (self.0.opts.git_ignore || self.0.opts.git_exclude) + let git_type = if !is_leaf + && (self.0.opts.require_git + && (self.0.opts.git_ignore || self.0.opts.git_exclude)) { dir.join(".git").metadata().ok().map(|md| md.file_type()) } else { @@ -255,18 +256,19 @@ impl Ignore { let has_git = git_type.map(|_| true).unwrap_or(false); let mut errs = PartialErrorBuilder::default(); - let custom_ig_matcher = if self.0.custom_ignore_filenames.is_empty() { - Gitignore::empty() - } else { - let (m, err) = create_gitignore( - &dir, - &dir, - &self.0.custom_ignore_filenames, - self.0.opts.ignore_case_insensitive, - ); - errs.maybe_push(err); - m - }; + let custom_ig_matcher = + if is_leaf || self.0.custom_ignore_filenames.is_empty() { + Gitignore::empty() + } else { + let (m, err) = create_gitignore( + &dir, + &dir, + &self.0.custom_ignore_filenames, + self.0.opts.ignore_case_insensitive, + ); + errs.maybe_push(err); + m + }; let ig_matcher = if is_leaf || !self.0.opts.ignore { Gitignore::empty() } else { From 2ff16aa53adc394c348e42160a87066a6c4d9ae7 Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 14:45:30 +0100 Subject: [PATCH 4/6] add some comments --- crates/ignore/src/dir.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/ignore/src/dir.rs b/crates/ignore/src/dir.rs index 527c809a03..82d9e8f156 100644 --- a/crates/ignore/src/dir.rs +++ b/crates/ignore/src/dir.rs @@ -230,6 +230,8 @@ impl Ignore { (Ignore(Arc::new(ig)), err) } + /// Like add_child but takes `is_leaf` boolean, if set to true, we assume that the search won't recurse inside + /// the provided dir which allows us to do some optimizations like not searching for ignore files. pub(crate) fn add_child2>( &self, dir: P, @@ -240,6 +242,8 @@ impl Ignore { } /// Like add_child, but takes a full path and returns an IgnoreInner. + /// Also takes `is_leaf` boolean, if set to true, we assume that the search won't recurse inside + /// the provided dir which allows us to do some optimizations like not searching for ignore files. fn add_child_path( &self, dir: &Path, From ce854d56b594945e5ac75e5c07112c1f63f13afc Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 15:16:12 +0100 Subject: [PATCH 5/6] do the same optimization for skipped dirs --- crates/ignore/src/walk.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/ignore/src/walk.rs b/crates/ignore/src/walk.rs index d1445c2929..390793499d 100644 --- a/crates/ignore/src/walk.rs +++ b/crates/ignore/src/walk.rs @@ -1012,21 +1012,21 @@ impl Iterator for Walk { Err(err) => return Some(Err(err)), Ok(should_skip) => should_skip, }; + let is_leaf = self + .max_depth + .map(|max| ent.depth() >= max) + .unwrap_or(false); if should_skip { self.it.as_mut().unwrap().it.skip_current_dir(); // Still need to push this on the stack because // we'll get a WalkEvent::Exit event for this dir. // We don't care if it errors though. - let (igtmp, _) = self.ig.add_child(ent.path()); + let (igtmp, _) = + self.ig.add_child2(ent.path(), is_leaf); self.ig = igtmp; continue; } - let is_leaf = self - .max_depth - .map(|max| ent.depth() >= max) - .unwrap_or(false); - let (igtmp, err) = self.ig.add_child2(ent.path(), is_leaf); self.ig = igtmp; ent.err = err; From 0bb22fbf54d359621503135bac616e1028ec0239 Mon Sep 17 00:00:00 2001 From: Nbiba Bedis Date: Sun, 23 Jul 2023 15:17:46 +0100 Subject: [PATCH 6/6] fmt --- crates/ignore/src/walk.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/ignore/src/walk.rs b/crates/ignore/src/walk.rs index 390793499d..0f476451aa 100644 --- a/crates/ignore/src/walk.rs +++ b/crates/ignore/src/walk.rs @@ -1026,7 +1026,6 @@ impl Iterator for Walk { self.ig = igtmp; continue; } - let (igtmp, err) = self.ig.add_child2(ent.path(), is_leaf); self.ig = igtmp; ent.err = err;