From 77f68d3093b1ecf7b0a4944ccc589de80df03ead Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 1 Nov 2023 12:00:05 -0400 Subject: [PATCH] walk: Remove a few unnecessary Arcs --- src/main.rs | 2 +- src/walk.rs | 78 ++++++++++++++++++++++++----------------------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/main.rs b/src/main.rs index b661f672b..a5f77b805 100644 --- a/src/main.rs +++ b/src/main.rs @@ -103,7 +103,7 @@ fn run() -> Result { .map(|pat| build_regex(pat, &config)) .collect::>>()?; - walk::scan(&search_paths, Arc::new(regexps), Arc::new(config)) + walk::scan(&search_paths, regexps, config) } #[cfg(feature = "completions")] diff --git a/src/walk.rs b/src/walk.rs index 837976230..64eef2bf5 100644 --- a/src/walk.rs +++ b/src/walk.rs @@ -49,13 +49,13 @@ const MAX_BUFFER_LENGTH: usize = 1000; const DEFAULT_MAX_BUFFER_TIME: Duration = Duration::from_millis(100); /// Wrapper for the receiver thread's buffering behavior. -struct ReceiverBuffer { +struct ReceiverBuffer<'a, W> { /// The configuration. - config: Arc, + config: &'a Config, /// For shutting down the senders. - quit_flag: Arc, + quit_flag: &'a AtomicBool, /// The ^C notifier. - interrupt_flag: Arc, + interrupt_flag: &'a AtomicBool, /// Receiver for worker results. rx: Receiver, /// Standard output. @@ -70,15 +70,12 @@ struct ReceiverBuffer { num_results: usize, } -impl ReceiverBuffer { +impl<'a, W: Write> ReceiverBuffer<'a, W> { /// Create a new receiver buffer. - fn new( - config: Arc, - quit_flag: Arc, - interrupt_flag: Arc, - rx: Receiver, - stdout: W, - ) -> Self { + fn new(state: &'a WorkerState, rx: Receiver, stdout: W) -> Self { + let config = &state.config; + let quit_flag = state.quit_flag.as_ref(); + let interrupt_flag = state.interrupt_flag.as_ref(); let max_buffer_time = config.max_buffer_time.unwrap_or(DEFAULT_MAX_BUFFER_TIME); let deadline = Instant::now() + max_buffer_time; @@ -214,12 +211,10 @@ impl ReceiverBuffer { /// State shared by the sender and receiver threads. struct WorkerState { - /// The paths to scan. - paths: Vec, /// The search patterns. - patterns: Arc>, + patterns: Vec, /// The command line configuration. - config: Arc, + config: Config, /// Flag for cleanly shutting down the parallel walk quit_flag: Arc, /// Flag specifically for quitting due to ^C @@ -227,14 +222,11 @@ struct WorkerState { } impl WorkerState { - fn new(paths: &[PathBuf], patterns: Arc>, config: Arc) -> Self { - let paths = paths.iter().cloned().collect(); - + fn new(patterns: Vec, config: Config) -> Self { let quit_flag = Arc::new(AtomicBool::new(false)); let interrupt_flag = Arc::new(AtomicBool::new(false)); Self { - paths, patterns, config, quit_flag, @@ -242,9 +234,9 @@ impl WorkerState { } } - fn build_overrides(&self) -> Result { - let first_path = &self.paths[0]; - let config = self.config.as_ref(); + fn build_overrides(&self, paths: &[PathBuf]) -> Result { + let first_path = &paths[0]; + let config = &self.config; let mut builder = OverrideBuilder::new(first_path); @@ -263,9 +255,10 @@ impl WorkerState { .map_err(|_| anyhow!("Mismatch in exclude patterns")) } - fn build_walker(&self) -> Result { - let first_path = &self.paths[0]; - let config = self.config.as_ref(); + fn build_walker(&self, paths: &[PathBuf]) -> Result { + let first_path = &paths[0]; + let config = &self.config; + let overrides = self.build_overrides(paths)?; let mut builder = WalkBuilder::new(first_path); builder @@ -276,7 +269,7 @@ impl WorkerState { .git_global(config.read_vcsignore) .git_exclude(config.read_vcsignore) .require_git(config.require_git_to_read_vcsignore) - .overrides(self.build_overrides()?) + .overrides(overrides) .follow_links(config.follow_links) // No need to check for supported platforms, option is unavailable on unsupported ones .same_file_system(config.one_file_system) @@ -316,18 +309,18 @@ impl WorkerState { } } - for path in &self.paths[1..] { + for path in &paths[1..] { builder.add(path); } - Ok(builder.threads(config.threads).build_parallel()) + let walker = builder.threads(config.threads).build_parallel(); + Ok(walker) } - /// Run the receiver thread. + /// Run the receiver work, either on this thread or a pool of background + /// threads (for --exec). fn receive(&self, rx: Receiver) -> ExitCode { - let config = Arc::clone(&self.config); - let quit_flag = Arc::clone(&self.quit_flag); - let interrupt_flag = Arc::clone(&self.interrupt_flag); + let config = &self.config; // This will be set to `Some` if the `--exec` argument was supplied. if let Some(ref cmd) = config.command { @@ -354,19 +347,18 @@ impl WorkerState { }) } } else { - let stdout = io::stdout(); - let stdout = stdout.lock(); + let stdout = io::stdout().lock(); let stdout = io::BufWriter::new(stdout); - ReceiverBuffer::new(config, quit_flag, interrupt_flag, rx, stdout).process() + ReceiverBuffer::new(self, rx, stdout).process() } } /// Spawn the sender threads. fn spawn_senders(&self, walker: WalkParallel, tx: Sender) { walker.run(|| { - let config = self.config.as_ref(); - let patterns = self.patterns.as_ref(); + let patterns = &self.patterns; + let config = &self.config; let quit_flag = self.quit_flag.as_ref(); let tx = tx.clone(); @@ -534,9 +526,9 @@ impl WorkerState { } /// Perform the recursive scan. - fn scan(&self) -> Result { - let config = self.config.as_ref(); - let walker = self.build_walker()?; + fn scan(&self, paths: &[PathBuf]) -> Result { + let config = &self.config; + let walker = self.build_walker(paths)?; if config.ls_colors.is_some() && config.is_printing() { let quit_flag = Arc::clone(&self.quit_flag); @@ -575,6 +567,6 @@ impl WorkerState { /// If the `--exec` argument was supplied, this will create a thread pool for executing /// jobs in parallel from a given command line and the discovered paths. Otherwise, each /// path will simply be written to standard output. -pub fn scan(paths: &[PathBuf], patterns: Arc>, config: Arc) -> Result { - WorkerState::new(paths, patterns, config).scan() +pub fn scan(paths: &[PathBuf], patterns: Vec, config: Config) -> Result { + WorkerState::new(patterns, config).scan(paths) }