refactor: replace scoped_threadpool with rayon

This commit is contained in:
Terts Diepraam 2024-02-05 17:53:28 +01:00 committed by Christina E. Sørensen
parent 8bb5cb546a
commit 8ea827207e
3 changed files with 62 additions and 121 deletions

39
Cargo.lock generated
View file

@ -283,16 +283,6 @@ dependencies = [
"itertools",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
@ -398,7 +388,6 @@ dependencies = [
"locale",
"log",
"natord",
"num_cpus",
"number_prefix",
"once_cell",
"palette",
@ -406,7 +395,7 @@ dependencies = [
"phf",
"plist",
"proc-mounts",
"scoped_threadpool",
"rayon",
"terminal_size",
"timeago",
"trycmd",
@ -696,16 +685,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
@ -942,9 +921,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "rayon"
version = "1.7.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051"
dependencies = [
"either",
"rayon-core",
@ -952,14 +931,12 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.11.0"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
@ -1040,12 +1017,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
[[package]]
name = "scopeguard"
version = "1.2.0"

View file

@ -78,19 +78,18 @@ libc = "0.2"
locale = "0.2"
log = "0.4"
natord = "1.0"
num_cpus = "1.16"
number_prefix = "0.4"
palette = { version = "0.7.4", default-features = false, features = ["std"] }
once_cell = "1.19.0"
percent-encoding = "2.3.1"
phf = { version = "0.11.2", features = ["macros"] }
plist = { version = "1.6.0", default-features = false }
scoped_threadpool = "0.1"
uutils_term_grid = "0.3"
terminal_size = "0.3.0"
timeago = { version = "0.4.2", default-features = false }
unicode-width = "0.1"
zoneinfo_compiled = "0.5.1"
rayon = "1.8.1"
[dependencies.git2]
version = "0.18"

View file

@ -60,12 +60,11 @@
//! can be displayed, in order to make sure that every column is wide enough.
use std::io::{self, Write};
use std::mem::MaybeUninit;
use std::path::PathBuf;
use std::vec::IntoIter as VecIntoIter;
use ansiterm::Style;
use scoped_threadpool::Pool;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use log::*;
@ -158,11 +157,6 @@ impl<'a> AsRef<File<'a>> for Egg<'a> {
impl<'a> Render<'a> {
pub fn render<W: Write>(mut self, w: &mut W) -> io::Result<()> {
let n_cpus = match num_cpus::get() as u32 {
0 => 1,
n => n,
};
let mut pool = Pool::new(n_cpus);
let mut rows = Vec::new();
let color_scale_info = ColorScaleInformation::from_color_scale(
@ -201,7 +195,6 @@ impl<'a> Render<'a> {
// https://internals.rust-lang.org/t/should-option-mut-t-implement-copy/3715/6
let mut table = Some(table);
self.add_files_to_table(
&mut pool,
&mut table,
&mut rows,
&self.files,
@ -214,7 +207,6 @@ impl<'a> Render<'a> {
}
} else {
self.add_files_to_table(
&mut pool,
&mut None,
&mut rows,
&self.files,
@ -247,7 +239,6 @@ impl<'a> Render<'a> {
/// parallelisable, and uses a pool of threads.
fn add_files_to_table<'dir>(
&self,
pool: &mut Pool,
table: &mut Option<Table<'a>>,
rows: &mut Vec<Row>,
src: &[File<'dir>],
@ -255,83 +246,70 @@ impl<'a> Render<'a> {
color_scale_info: Option<ColorScaleInformation>,
) {
use crate::fs::feature::xattr;
use std::sync::{Arc, Mutex};
let mut file_eggs = (0..src.len())
.map(|_| MaybeUninit::uninit())
.collect::<Vec<_>>();
let mut file_eggs: Vec<_> = src
.par_iter()
.map(|file| {
let mut errors = Vec::new();
pool.scoped(|scoped| {
let file_eggs = Arc::new(Mutex::new(&mut file_eggs));
let table = table.as_ref();
// There are three “levels” of extended attribute support:
//
// 1. If were compiling without that feature, then
// exa pretends all files have no attributes.
// 2. If the feature is enabled and the --extended flag
// has been specified, then display an @ in the
// permissions column for files with attributes, the
// names of all attributes and their values, and any
// errors encountered when getting them.
// 3. If the --extended flag *hasnt* been specified, then
// display the @, but dont display anything else.
//
// For a while, exa took a stricter approach to (3):
// if an error occurred while checking a files xattrs to
// see if it should display the @, exa would display that
// error even though the attributes werent actually being
// shown! This was confusing, as users were being shown
// errors for something they didnt explicitly ask for,
// and just cluttered up the output. So now errors arent
// printed unless the user passes --extended to signify
// that they want to see them.
for (idx, file) in src.iter().enumerate() {
let file_eggs = Arc::clone(&file_eggs);
let xattrs: &[Attribute] = if xattr::ENABLED && self.opts.xattr {
file.extended_attributes()
} else {
&[]
};
scoped.execute(move || {
let mut errors = Vec::new();
let table_row = table
.as_ref()
.map(|t| t.row_for_file(file, self.show_xattr_hint(file), color_scale_info));
// There are three “levels” of extended attribute support:
//
// 1. If were compiling without that feature, then
// exa pretends all files have no attributes.
// 2. If the feature is enabled and the --extended flag
// has been specified, then display an @ in the
// permissions column for files with attributes, the
// names of all attributes and their values, and any
// errors encountered when getting them.
// 3. If the --extended flag *hasnt* been specified, then
// display the @, but dont display anything else.
//
// For a while, exa took a stricter approach to (3):
// if an error occurred while checking a files xattrs to
// see if it should display the @, exa would display that
// error even though the attributes werent actually being
// shown! This was confusing, as users were being shown
// errors for something they didnt explicitly ask for,
// and just cluttered up the output. So now errors arent
// printed unless the user passes --extended to signify
// that they want to see them.
let xattrs: &[Attribute] = if xattr::ENABLED && self.opts.xattr {
file.extended_attributes()
} else {
&[]
};
let table_row = table.as_ref().map(|t| {
t.row_for_file(file, self.show_xattr_hint(file), color_scale_info)
});
let mut dir = None;
if let Some(r) = self.recurse {
if file.is_directory() && r.tree && !r.is_too_deep(depth.0) {
trace!("matching on to_dir");
match file.to_dir() {
Ok(d) => {
dir = Some(d);
}
Err(e) => {
errors.push((e, None));
}
let mut dir = None;
if let Some(r) = self.recurse {
if file.is_directory() && r.tree && !r.is_too_deep(depth.0) {
trace!("matching on to_dir");
match file.to_dir() {
Ok(d) => {
dir = Some(d);
}
Err(e) => {
errors.push((e, None));
}
}
};
}
};
let egg = Egg {
table_row,
xattrs,
errors,
dir,
file,
};
unsafe { std::ptr::write(file_eggs.lock().unwrap()[idx].as_mut_ptr(), egg) }
});
}
});
Egg {
table_row,
xattrs,
errors,
dir,
file,
}
})
.collect();
// this is safe because all entries have been initialized above
let mut file_eggs = unsafe { std::mem::transmute::<_, Vec<Egg<'_>>>(file_eggs) };
self.filter.sort_files(&mut file_eggs);
for (tree_params, egg) in depth.iterate_over(file_eggs.into_iter()) {
@ -391,14 +369,7 @@ impl<'a> Render<'a> {
));
}
self.add_files_to_table(
pool,
table,
rows,
&files,
depth.deeper(),
color_scale_info,
);
self.add_files_to_table(table, rows, &files, depth.deeper(), color_scale_info);
continue;
}
}