summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2021-06-02 13:45:12 +0200
committerCanop <cano.petrole@gmail.com>2021-06-02 13:45:12 +0200
commit77f40f74c38392a5213f99006138d74772ac5c6c (patch)
tree145732e2e45e0dd3bf17e2a2f3e07027cc5d3338
parent7635373786d1c0fbc45c326d4a0a8914396f7051 (diff)
make the number of threads used for file summing configurable
Also replace lazy_static with once_cell
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock42
-rw-r--r--Cargo.toml8
-rw-r--r--src/app/app.rs1
-rw-r--r--src/app/app_context.rs11
-rw-r--r--src/conf/conf.rs3
-rw-r--r--src/conf/mod.rs7
-rw-r--r--src/display/mod.rs8
-rw-r--r--src/errors.rs1
-rw-r--r--src/file_sum/mod.rs16
-rw-r--r--src/file_sum/sum_computation.rs344
-rw-r--r--src/filesystems/mod.rs6
-rw-r--r--src/git/ignore.rs6
-rw-r--r--src/git/status_computer.rs9
-rw-r--r--src/help/help_content.rs7
-rw-r--r--src/kitty/mod.rs8
-rw-r--r--src/permissions/permissions_unix.rs17
-rw-r--r--src/shell_install/bash.rs1
-rw-r--r--src/shell_install/mod.rs2
-rw-r--r--src/syntactic/syntactic_view.rs6
-rw-r--r--src/verb/mod.rs12
21 files changed, 283 insertions, 233 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 525f841..f96bf24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
- new standard verb arguments: `{file-stem}`, `{file-extension}`, and `{file-dot-extension}`,
- new `:toggle_second_tree` internal - Fix #388
- total size of staging area computed and displayed if sizes displayed elsewhere
+- new `file_sum_threads_count` conf property to define the number of threads used for file summing (size, count, last modified). The goal is to more easily search what's the best value depending on the cpu, OS and disk type/speed
- fix a few minor bugs
<a name="v1.4.0"></a>
diff --git a/Cargo.lock b/Cargo.lock
index d303da9..2eec5b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -162,11 +162,11 @@ dependencies = [
"image",
"is_executable",
"lazy-regex",
- "lazy_static",
"lfs-core",
"libc",
"memmap",
- "minimad",
+ "minimad 0.8.0",
+ "once_cell",
"open",
"pathdiff",
"phf",
@@ -179,7 +179,7 @@ dependencies = [
"strict",
"syntect",
"tempfile",
- "termimad",
+ "termimad 0.11.0",
"terminal-clipboard",
"toml",
"umask",
@@ -630,14 +630,14 @@ dependencies = [
"csv2svg",
"git2",
"lazy_static",
- "minimad",
+ "minimad 0.7.1",
"open",
"rusqlite",
"serde",
"serde_json",
"svg",
"tempfile",
- "termimad",
+ "termimad 0.10.3",
"thiserror",
]
@@ -773,9 +773,9 @@ dependencies = [
[[package]]
name = "lazy-regex"
-version = "2.0.2"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ccd39a8bca82b0a9c186d5ae0a73a79cc68ac3ff8dd35712baae188ea3b61d1"
+checksum = "7b00f3e4d8dc7bedf8f0947c7079bfe11f5dba7a96d95c8340c851eec8ffc41e"
dependencies = [
"lazy-regex-proc_macros",
"once_cell",
@@ -784,9 +784,9 @@ dependencies = [
[[package]]
name = "lazy-regex-proc_macros"
-version = "2.0.2"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "495df213e9f7f0defedfe0138d038e8ef3dc662facefa0c6ab91e6f4bf34ab13"
+checksum = "cd6f321bbea1296f0fe12342fdf3e8eaf0b871b80b8a2dc37337e05cfe364c8d"
dependencies = [
"proc-macro2",
"quote",
@@ -931,6 +931,15 @@ dependencies = [
]
[[package]]
+name = "minimad"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8957f240ecb82a4e699bcf4db189fe8a7f5aa68b9e6d5abf829c62a9ee4630ed"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
name = "miniz_oxide"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1597,7 +1606,20 @@ dependencies = [
"crossbeam",
"crossterm",
"lazy_static",
- "minimad",
+ "minimad 0.7.1",
+ "thiserror",
+ "unicode-width",
+]
+
+[[package]]
+name = "termimad"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf5f65b9464ce6ab282052f984ba2beead5937829fd9f0347f716fa8edf9cd0"
+dependencies = [
+ "crossbeam",
+ "crossterm",
+ "minimad 0.8.0",
"thiserror",
"unicode-width",
]
diff --git a/Cargo.toml b/Cargo.toml
index bcb3a09..20ddeba 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,10 +38,10 @@ git2 = { version="0.13", default-features=false }
glob = "0.3"
id-arena = "2.2.1"
image = "0.23.14"
-lazy-regex = "2.0.2"
-lazy_static = "1.4"
+lazy-regex = "2.1.0"
libc = "0.2"
-minimad = "0.7.1"
+minimad = "0.8.0"
+once_cell = "1.7"
open = "1.4"
memmap = "0.7"
pathdiff = "0.2"
@@ -55,7 +55,7 @@ splitty = "0.1"
strict = "0.1.4"
syntect = "4.5"
tempfile = "3.2"
-termimad = { version = "0.10.3" }
+termimad = { version = "0.11.0" }
terminal-clipboard = { version = "0.2.1", optional = true }
toml = "0.5"
umask = "1.0"
diff --git a/src/app/app.rs b/src/app/app.rs
index c99b71c..cfd8aae 100644
--- a/src/app/app.rs
+++ b/src/app/app.rs
@@ -690,6 +690,7 @@ impl App {
if !self.quitting {
self.display_panels(w, &skin, &app_state, con)?;
time!(
+ Info,
"pending_tasks",
self.do_pending_tasks(w, &skin, &mut dam, &mut app_state, con)?,
);
diff --git a/src/app/app_context.rs b/src/app/app_context.rs
index 7af3502..adb27ad 100644
--- a/src/app/app_context.rs
+++ b/src/app/app_context.rs
@@ -4,6 +4,7 @@ use {
cli::AppLaunchArgs,
conf::Conf,
errors::ConfError,
+ file_sum,
icon::*,
pattern::SearchModeMap,
path::SpecialPath,
@@ -69,6 +70,10 @@ pub struct AppContext {
/// whether to quit broot when the user hits "escape"
/// and there's nothing to cancel
pub quit_on_last_cancel: bool,
+
+ /// number of threads used by file_sum (count, size, date)
+ /// computation
+ pub file_sum_threads_count: usize,
}
impl AppContext {
@@ -97,6 +102,11 @@ impl AppContext {
.transpose()?
.unwrap_or_default();
let ext_colors = ExtColorMap::try_from(&config.ext_colors)?;
+ let file_sum_threads_count = config.file_sum_threads_count
+ .unwrap_or(file_sum::DEFAULT_THREAD_COUNT);
+ if file_sum_threads_count < 1 || file_sum_threads_count > 50 {
+ return Err(ConfError::InvalidThreadsCount{ count: file_sum_threads_count });
+ }
let max_panels_count = config.max_panels_count
.unwrap_or(2)
.clamp(2, 100);
@@ -116,6 +126,7 @@ impl AppContext {
mouse_capture_disabled: config.disable_mouse_capture.unwrap_or(false),
max_panels_count,
quit_on_last_cancel: config.quit_on_last_cancel.unwrap_or(false),
+ file_sum_threads_count,
})
}
}
diff --git a/src/conf/conf.rs b/src/conf/conf.rs
index 9cff5c5..dde306c 100644
--- a/src/conf/conf.rs
+++ b/src/conf/conf.rs
@@ -87,6 +87,8 @@ pub struct Conf {
#[serde(alias="quit-on-last-cancel")]
pub quit_on_last_cancel: Option<bool>,
+ pub file_sum_threads_count: Option<usize>,
+
}
impl Conf {
@@ -153,6 +155,7 @@ impl Conf {
overwrite!(self, max_panels_count, conf);
overwrite!(self, modal, conf);
overwrite!(self, quit_on_last_cancel, conf);
+ overwrite!(self, file_sum_threads_count, conf);
self.verbs.append(&mut conf.verbs);
// the following maps are "additive": we can add entries from several
// config files and they still make sense
diff --git a/src/conf/mod.rs b/src/conf/mod.rs
index 09a6c67..cc84322 100644
--- a/src/conf/mod.rs
+++ b/src/conf/mod.rs
@@ -10,7 +10,7 @@ mod verb_conf;
pub use {
conf::Conf,
format::*,
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
verb_conf::VerbConf,
};
@@ -60,10 +60,9 @@ fn find_conf_dir() -> PathBuf {
}
}
+static CONF_DIR: Lazy<PathBuf> = Lazy::new(find_conf_dir);
+
/// return the path to the config directory
pub fn dir() -> &'static Path {
- lazy_static! {
- static ref CONF_DIR: PathBuf = find_conf_dir();
- }
&*CONF_DIR
}
diff --git a/src/display/mod.rs b/src/display/mod.rs
index 9b9d4ec..4042da7 100644
--- a/src/display/mod.rs
+++ b/src/display/mod.rs
@@ -59,7 +59,7 @@ use {
},
QueueableCommand,
},
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
};
#[cfg(not(any(target_family="windows",target_os="android")))]
@@ -69,10 +69,8 @@ pub use {
pub static TAB_REPLACEMENT: &str = " ";
-lazy_static! {
- pub static ref SPACE_FILLING: Filling = Filling::from_char(' ');
- pub static ref BRANCH_FILLING: Filling = Filling::from_char('─');
-}
+pub static SPACE_FILLING: Lazy<Filling> = Lazy::new(|| { Filling::from_char(' ') });
+pub static BRANCH_FILLING: Lazy<Filling> = Lazy::new(|| { Filling::from_char('─') });
/// if true then the status of a panel covers the whole width
/// of the terminal (over the other panels)
diff --git a/src/errors.rs b/src/errors.rs
index e769030..388b30d 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -51,6 +51,7 @@ custom_error! {pub ConfError
UnexpectedInternalArg {invocation: String} = "unexpected argument for internal: {}",
InvalidCols {details: String} = "invalid cols definition: {}",
InvalidSkin {source: InvalidSkinError} = "invalid skin: {}",
+ InvalidThreadsCount { count: usize } = "invalid threads count: {}",
}
// error which can be raised when parsing a pattern the user typed
diff --git a/src/file_sum/mod.rs b/src/file_sum/mod.rs
index 81832db..3b3ba35 100644
--- a/src/file_sum/mod.rs
+++ b/src/file_sum/mod.rs
@@ -10,7 +10,7 @@ use {
task_sync::Dam,
},
ahash::AHashMap,
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
std::{
ops::AddAssign,
path::{Path, PathBuf},
@@ -18,14 +18,14 @@ use {
},
};
-lazy_static! {
- static ref SUM_CACHE_MUTEX: Mutex<AHashMap<PathBuf, FileSum>> =
- Mutex::new(AHashMap::default());
-}
+pub const DEFAULT_THREAD_COUNT: usize = 4;
+
+static SUM_CACHE: Lazy<Mutex<AHashMap<PathBuf, FileSum>>> = Lazy::new(|| {
+ Mutex::new(AHashMap::default())
+});
pub fn clear_cache() {
- let mut sum_cache = SUM_CACHE_MUTEX.lock().unwrap();
- sum_cache.clear();
+ SUM_CACHE.lock().unwrap().clear();
}
/// Reduction of counts, dates and sizes on a file or directory
@@ -65,7 +65,7 @@ impl FileSum {
/// fetching it from cache.
/// If the lifetime expires before complete computation, None is returned.
pub fn from_dir(path: &Path, dam: &Dam, con: &AppContext) -> Option<Self> {
- let mut sum_cache = SUM_CACHE_MUTEX.lock().unwrap();
+ let mut sum_cache = SUM_CACHE.lock().unwrap();
match sum_cache.get(path) {
Some(sum) => Some(*sum),
None => {
diff --git a/src/file_sum/sum_computation.rs b/src/file_sum/sum_computation.rs
index 84e5072..28ce930 100644
--- a/src/file_sum/sum_computation.rs
+++ b/src/file_sum/sum_computation.rs
@@ -7,7 +7,6 @@ use {
},
ahash::AHashMap,
crossbeam::channel,
- lazy_static::lazy_static,
rayon::{ThreadPool, ThreadPoolBuilder},
std::{
convert::TryInto,
@@ -29,6 +28,12 @@ use {
},
};
+
+struct DirSummer {
+ thread_count: usize,
+ thread_pool: ThreadPool,
+}
+
/// a node id, taking the device into account to be sure to discriminate
/// nodes with the same inode but on different devices
#[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)]
@@ -39,10 +44,6 @@ struct NodeId {
dev: u64,
}
-// threads used by one computation
-const THREADS_COUNT: usize = 6;
-
-
#[inline(always)]
fn is_ignored(path: &Path, special_paths: &[SpecialPath]) -> bool {
match special_paths.find(path) {
@@ -51,189 +52,216 @@ fn is_ignored(path: &Path, special_paths: &[SpecialPath]) -> bool {
}
}
-/// compute the consolidated numbers for a directory, with implementation
-/// varying depending on the OS:
-/// On unix, the computation is done on blocks of 512 bytes
-/// see https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html#tymethod.blocks
-pub fn compute_dir_sum(
- path: &Path,
- cache: &mut AHashMap<PathBuf, FileSum>,
- dam: &Dam,
- con: &AppContext,
-) -> Option<FileSum> {
- //debug!("compute size of dir {:?} --------------- ", path);
-
- if is_ignored(path, &con.special_paths) {
- return Some(FileSum::zero());
- }
-
- lazy_static! {
- static ref THREAD_POOL: ThreadPool = ThreadPoolBuilder::new()
- .num_threads(THREADS_COUNT * 2)
+impl DirSummer {
+ pub fn new(thread_count: usize) -> Self {
+ let thread_pool = ThreadPoolBuilder::new()
+ .num_threads(thread_count)
.build()
.unwrap();
+ Self {
+ thread_count,
+ thread_pool,
+ }
}
+ /// compute the consolidated numbers for a directory, with implementation
+ /// varying depending on the OS:
+ /// On unix, the computation is done on blocks of 512 bytes
+ /// see https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html#tymethod.blocks
+ pub fn compute_dir_sum(
+ &mut self,
+ path: &Path,
+ cache: &mut AHashMap<PathBuf, FileSum>,
+ dam: &Dam,
+ con: &AppContext,
+ ) -> Option<FileSum> {
+ let threads_count = self.thread_count;
+
+ if is_ignored(path, &con.special_paths) {
+ return Some(FileSum::zero());
+ }
- // to avoid counting twice a node, we store their id in a set
- #[cfg(unix)]
- let nodes = Arc::new(Mutex::new(FnvHashSet::<NodeId>::default()));
-
- // busy is the number of directories which are either being processed or queued
- // We use this count to determine when threads can stop waiting for tasks
- let mut busy = 0;
- let mut sum = compute_file_sum(path);
-
- // this MPMC channel contains the directory paths which must be handled.
- // A None means there's nothing left and the thread may send its result and stop
- let (dirs_sender, dirs_receiver) = channel::unbounded();
-
- let special_paths: Vec<SpecialPath> = con.special_paths.iter()
- .filter(|sp| sp.can_have_matches_in(path))
- .cloned()
- .collect();
-
- // the first level is managed a little differently: we look at the cache
- // before adding. This enables faster computations in two cases:
- // - for the root line (assuming it's computed after the content)
- // - when we navigate up the tree
- if let Ok(entries) = fs::read_dir(path) {
- for e in entries.flatten() {
- if let Ok(md) = e.metadata() {
- if md.is_dir() {
- let entry_path = e.path();
-
- if is_ignored(&entry_path, &special_paths) {
- debug!("not summing special path {:?}", entry_path);
- continue;
- }
+ // to avoid counting twice a node, we store their id in a set
+ #[cfg(unix)]
+ let nodes = Arc::new(Mutex::new(FnvHashSet::<NodeId>::default()));
+
+ // busy is the number of directories which are either being processed or queued
+ // We use this count to determine when threads can stop waiting for tasks
+ let mut busy = 0;
+ let mut sum = compute_file_sum(path);
+
+ // this MPMC channel contains the directory paths which must be handled.
+ // A None means there's nothing left and the thread may send its result and stop
+ let (dirs_sender, dirs_receiver) = channel::unbounded();
+
+ let special_paths: Vec<SpecialPath> = con.special_paths.iter()
+ .filter(|sp| sp.can_have_matches_in(path))
+ .cloned()
+ .collect();
+
+ // the first level is managed a little differently: we look at the cache
+ // before adding. This enables faster computations in two cases:
+ // - for the root line (assuming it's computed after the content)
+ // - when we navigate up the tree
+ if let Ok(entries) = fs::read_dir(path) {
+ for e in entries.flatten() {
+ if let Ok(md) = e.metadata() {
+ if md.is_dir() {
+ let entry_path = e.path();
+
+ if is_ignored(&entry_path, &special_paths) {
+ debug!("not summing special path {:?}", entry_path);
+ continue;
+ }
- // we check the cache
- if let Some(entry_sum) = cache.get(&entry_path) {
- sum += *entry_sum;
- continue;
- }
- // we add the directory to the channel of dirs needing
- // processing
- busy += 1;
- dirs_sender.send(Some(entry_path)).unwrap();
- } else {
-
- #[cfg(unix)]
- if md.nlink() > 1 {
- let mut nodes = nodes.lock().unwrap();
- let node_id = NodeId {
- inode: md.ino(),
- dev: md.dev(),
- };
- if !nodes.insert(node_id) {
- // it was already in the set
+ // we check the cache
+ if let Some(entry_sum) = cache.get(&entry_path) {
+ sum += *entry_sum;
continue;
}
- }
+ // we add the directory to the channel of dirs needing
+ // processing
+ busy += 1;
+ dirs_sender.send(Some(entry_path)).unwrap();
+ } else {
+
+ #[cfg(unix)]
+ if md.nlink() > 1 {
+ let mut nodes = nodes.lock().unwrap();
+ let node_id = NodeId {
+ inode: md.ino(),
+ dev: md.dev(),
+ };
+ if !nodes.insert(node_id) {
+ // it was already in the set
+ continue;
+ }
+ }
+ }
+ sum += md_sum(&md);
}
- sum += md_sum(&md);
}
}
- }
-
- if busy == 0 {
- return Some(sum);
- }
- let busy = Arc::new(AtomicIsize::new(busy));
-
- // this MPMC channel is here for the threads to send their results
- // at end of computation
- let (thread_sum_sender, thread_sum_receiver) = channel::bounded(THREADS_COUNT);
+ if busy == 0 {
+ return Some(sum);
+ }
+ let busy = Arc::new(AtomicIsize::new(busy));
- // Each thread does a summation without merge and the data are merged
- // at the end (this avoids waiting for a mutex during computation)
- for _ in 0..THREADS_COUNT {
- let busy = Arc::clone(&busy);
- let (dirs_sender, dirs_receiver) = (dirs_sender.clone(), dirs_receiver.clone());
+ // this MPMC channel is here for the threads to send their results
+ // at end of computation
+ let (thread_sum_sender, thread_sum_receiver) = channel::bounded(threads_count);
- #[cfg(unix)]
- let nodes = nodes.clone();
-
- let special_paths = special_paths.clone();
-
- let observer = dam.observer();
- let thread_sum_sender = thread_sum_sender.clone();
- THREAD_POOL.spawn(move || {
- let mut thread_sum = FileSum::zero();
- loop {
- let o = dirs_receiver.recv();
- if let Ok(Some(open_dir)) = o {
- if let Ok(entries) = fs::read_dir(&open_dir) {
- for e in entries.flatten() {
- if let Ok(md) = e.metadata() {
- if md.is_dir() {
-
- let path = e.path();
-
- if is_ignored(&path, &special_paths) {
- debug!("not summing (deep) special path {:?}", path);
- continue;
- }
- // we add the directory to the channel of dirs needing
- // processing
- busy.fetch_add(1, Ordering::Relaxed);
- dirs_sender.send(Some(path)).unwrap();
- } else {
+ // Each thread does a summation without merge and the data are merged
+ // at the end (this avoids waiting for a mutex during computation)
+ for _ in 0..threads_count {
+ let busy = Arc::clone(&busy);
+ let (dirs_sender, dirs_receiver) = (dirs_sender.clone(), dirs_receiver.clone());
- #[cfg(unix)]
- if md.nlink() > 1 {
- let mut nodes = nodes.lock().unwrap();
- let node_id = NodeId {
- inode: md.ino(),
- dev: md.dev(),
- };
- if !nodes.insert(node_id) {
- // it was already in the set
+ #[cfg(unix)]
+ let nodes = nodes.clone();
+
+ let special_paths = special_paths.clone();
+
+ let observer = dam.observer();
+ let thread_sum_sender = thread_sum_sender.clone();
+ self.thread_pool.spawn(move || {
+ let mut thread_sum = FileSum::zero();
+ loop {
+ let o = dirs_receiver.recv();
+ if let Ok(Some(open_dir)) = o {
+ if let Ok(entries) = fs::read_dir(&open_dir) {
+ for e in entries.flatten() {
+ if let Ok(md) = e.metadata() {
+ if md.is_dir() {
+
+ let path = e.path();
+
+ if is_ignored(&path, &special_paths) {
+ debug!("not summing (deep) special path {:?}", path);
continue;
}
- }
+ // we add the directory to the channel of dirs needing
+ // processing
+ busy.fetch_add(1, Ordering::Relaxed);
+ dirs_sender.send(Some(path)).unwrap();
+ } else {
+
+ #[cfg(unix)]
+ if md.nlink() > 1 {
+ let mut nodes = nodes.lock().unwrap();
+ let node_id = NodeId {
+ inode: md.ino(),
+ dev: md.dev(),
+ };
+ if !nodes.insert(node_id) {
+ // it was already in the set
+ continue;
+ }
+ }
+
+ }
+ thread_sum += md_sum(&md);
+ } else {
+ // we can't measure much but we can count the file
+ thread_sum.incr();
}
- thread_sum += md_sum(&md);
- } else {
- // we can't measure much but we can count the file
- thread_sum.incr();
}
}
+ busy.fetch_sub(1, Ordering::Relaxed);
+ }
+ if observer.has_event() {
+ dirs_sender.send(None).unwrap(); // to unlock the next waiting thread
+ break;
+ }
+ if busy.load(Ordering::Relaxed) < 1 {
+ dirs_sender.send(None).unwrap(); // to unlock the next waiting thread
+ break;
}
- busy.fetch_sub(1, Ordering::Relaxed);
}
- if observer.has_event() {
- dirs_sender.send(None).unwrap(); // to unlock the next waiting thread
- break;
+ thread_sum_sender.send(thread_sum).unwrap();
+ });
+ }
+ // Wait for the threads to finish and consolidate their results
+ for _ in 0..threads_count {
+ match thread_sum_receiver.recv() {
+ Ok(thread_sum) => {
+ sum += thread_sum;
}
- if busy.load(Ordering::Relaxed) < 1 {
- dirs_sender.send(None).unwrap(); // to unlock the next waiting thread
- break;
+ Err(e) => {
+ warn!("Error while recv summing thread result : {:?}", e);
}
}
- thread_sum_sender.send(thread_sum).unwrap();
- });
- }
- // Wait for the threads to finish and consolidate their results
- for _ in 0..THREADS_COUNT {
- match thread_sum_receiver.recv() {
- Ok(thread_sum) => {
- sum += thread_sum;
- }
- Err(e) => {
- warn!("Error while recv summing thread result : {:?}", e);
- }
}
+ if dam.has_event() {
+ return None;
+ }
+ Some(sum)
}
- if dam.has_event() {
- return None;
- }
- Some(sum)
+}
+
+
+/// compute the consolidated numbers for a directory, with implementation
+/// varying depending on the OS:
+/// On unix, the computation is done on blocks of 512 bytes
+/// see https://doc.rust-lang.org/std/os/unix/fs/trait.MetadataExt.html#tymethod.blocks
+pub fn compute_dir_sum(
+ path: &Path,
+ cache: &mut AHashMap<PathBuf, FileSum>,
+ dam: &Dam,
+ con: &AppContext,
+) -> Option<FileSum> {
+ use once_cell::sync::OnceCell;
+ static DIR_SUMMER: OnceCell<Mutex<DirSummer>> = OnceCell::new();
+ DIR_SUMMER
+ .get_or_init(|| {
+ Mutex::new(DirSummer::new(con.file_sum_threads_count))
+ })
+ .lock().unwrap()
+ .compute_dir_sum(path, cache, dam, con)
}
/// compute the sum for a regular file (not a folder)
diff --git a/src/filesystems/mod.rs b/src/filesystems/mod.rs
index d04b991..62f26e1 100644
--- a/src/filesystems/mod.rs
+++ b/src/filesystems/mod.rs
@@ -12,13 +12,11 @@ pub use {
use {
crossterm::style::Color,
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
std::sync::Mutex,
};
-lazy_static! {
- pub static ref MOUNTS: Mutex<MountList> = Mutex::new(MountList::new());
-}
+pub static MOUNTS: Lazy<Mutex<MountList>> = Lazy::new(|| Mutex::new(MountList::new()));
pub fn clear_cache() {
let mut mount_list = MOUNTS.lock().unwrap();
diff --git a/src/git/ignore.rs b/src/git/ignore.rs
index f3f267e..4c6558e 100644
--- a/src/git/ignore.rs
+++ b/src/git/ignore.rs
@@ -4,8 +4,8 @@ use {
git2,
glob,
id_arena::{Arena, Id},
- lazy_static::lazy_static,
lazy_regex::regex,
+ once_cell::sync::Lazy,
std::{
fs::File,
io::{BufRead, BufReader, Result},
@@ -97,9 +97,7 @@ impl GitIgnoreFile {
/// return the global gitignore file interpreted for
/// the given repo dir
pub fn global(repo_dir: &Path) -> Option<GitIgnoreFile> {
- lazy_static! {
- static ref GLOBAL_GI_PATH: Option<PathBuf> = find_global_ignore();
- }
+ static GLOBAL_GI_PATH: Lazy<Option<PathBuf>> = Lazy::new(find_global_ignore);
if let Some(path) = &*GLOBAL_GI_PATH {
GitIgnoreFile::new(path, repo_dir).ok()
} else {
diff --git a/src/git/status_computer.rs b/src/git/status_computer.rs
index 8cb1528..bb6bdc7 100644
--- a/src/git/status_computer.rs
+++ b/src/git/status_computer.rs
@@ -7,7 +7,7 @@ use {
crossbeam::channel::bounded,
ahash::AHashMap,
git2::Repository,
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
std::{
path::{Path, PathBuf},
sync::Mutex,
@@ -30,11 +30,10 @@ fn compute_tree_status(root_path: &Path) -> ComputationResult<TreeGitStatus> {
}
}
-lazy_static! {
// the key is the path of the repository
- static ref TS_CACHE_MX: Mutex<AHashMap<PathBuf, Computation<TreeGitStatus>>> =
- Mutex::new(AHashMap::default());
-}
+static TS_CACHE_MX: Lazy<Mutex<AHashMap<PathBuf, Computation<TreeGitStatus>>>> = Lazy::new(|| {
+ Mutex::new(AHashMap::default())
+});
/// try to get the result of the computation of the tree git status.
/// This may be immediate if a previous computation was finished.
diff --git a/src/help/help_content.rs b/src/help/help_content.rs
index 33edf64..25419de 100644
--- a/src/help/help_content.rs
+++ b/src/help/help_content.rs
@@ -1,5 +1,4 @@
use {
- lazy_static::lazy_static,
minimad::{TextTemplate, TextTemplateExpander},
};
@@ -75,9 +74,7 @@ ${features
/// completed with data and which then would be used to
/// produce the markdown of the help page
pub fn expander() -> TextTemplateExpander<'static, 'static> {
- lazy_static! {
- // this doesn't really matter, only half a ms is spared
- static ref TEMPLATE: TextTemplate<'static> = TextTemplate::from(MD);
- }
+ use once_cell::sync::Lazy;
+ static TEMPLATE: Lazy<TextTemplate<'static>> = Lazy::new(|| TextTemplate::from(MD));
TEMPLATE.expander()
}
diff --git a/src/kitty/mod.rs b/src/kitty/mod.rs
index 07cb901..04f4ba7 100644
--- a/src/kitty/mod.rs
+++ b/src/kitty/mod.rs
@@ -3,13 +3,13 @@ mod image_renderer;
pub use image_renderer::*;
use {
- lazy_static::lazy_static,
+ once_cell::sync::Lazy,
std::sync::Mutex,
};
-lazy_static! {
- static ref RENDERER: Option<Mutex<KittyImageRenderer>> = KittyImageRenderer::new().map(Mutex::new);
-}
+s