Skip to content

Commit d7b0fb6

Browse files
authored
feat!: allow user to set rayon threads (#270)
BREAKING CHANGE: a new field named `threads` is added to `Args`.
1 parent 67d3079 commit d7b0fb6

File tree

8 files changed

+73
-11
lines changed

8 files changed

+73
-11
lines changed

exports/completion.bash

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ _pdu() {
1919

2020
case "${cmd}" in
2121
pdu)
22-
opts="-h -V --json-input --json-output --bytes-format --top-down --align-right --quantity --max-depth --total-width --column-width --min-ratio --no-sort --silent-errors --progress --help --version [FILES]..."
22+
opts="-h -V --json-input --json-output --bytes-format --top-down --align-right --quantity --max-depth --total-width --column-width --min-ratio --no-sort --silent-errors --progress --threads --help --version [FILES]..."
2323
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
2424
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
2525
return 0
@@ -49,6 +49,10 @@ _pdu() {
4949
COMPREPLY=($(compgen -f "${cur}"))
5050
return 0
5151
;;
52+
--threads)
53+
COMPREPLY=($(compgen -f "${cur}"))
54+
return 0
55+
;;
5256
*)
5357
COMPREPLY=()
5458
;;

exports/completion.elv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ set edit:completion:arg-completer[pdu] = {|@words|
2424
cand --total-width 'Width of the visualization'
2525
cand --column-width 'Maximum widths of the tree column and width of the bar column'
2626
cand --min-ratio 'Minimal size proportion required to appear'
27+
cand --threads 'Set the maximum number of threads to spawn. Could be either "auto", "max", or a number'
2728
cand --json-input 'Read JSON data from stdin'
2829
cand --json-output 'Print JSON data instead of an ASCII chart'
2930
cand --top-down 'Print the tree top-down instead of bottom-up'

exports/completion.fish

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ complete -c pdu -l max-depth -d 'Maximum depth to display the data (must be grea
44
complete -c pdu -l total-width -d 'Width of the visualization' -r
55
complete -c pdu -l column-width -d 'Maximum widths of the tree column and width of the bar column' -r
66
complete -c pdu -l min-ratio -d 'Minimal size proportion required to appear' -r
7+
complete -c pdu -l threads -d 'Set the maximum number of threads to spawn. Could be either "auto", "max", or a number' -r
78
complete -c pdu -l json-input -d 'Read JSON data from stdin'
89
complete -c pdu -l json-output -d 'Print JSON data instead of an ASCII chart'
910
complete -c pdu -l top-down -d 'Print the tree top-down instead of bottom-up'

exports/completion.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Register-ArgumentCompleter -Native -CommandName 'pdu' -ScriptBlock {
2727
[CompletionResult]::new('--total-width', '--total-width', [CompletionResultType]::ParameterName, 'Width of the visualization')
2828
[CompletionResult]::new('--column-width', '--column-width', [CompletionResultType]::ParameterName, 'Maximum widths of the tree column and width of the bar column')
2929
[CompletionResult]::new('--min-ratio', '--min-ratio', [CompletionResultType]::ParameterName, 'Minimal size proportion required to appear')
30+
[CompletionResult]::new('--threads', '--threads', [CompletionResultType]::ParameterName, 'Set the maximum number of threads to spawn. Could be either "auto", "max", or a number')
3031
[CompletionResult]::new('--json-input', '--json-input', [CompletionResultType]::ParameterName, 'Read JSON data from stdin')
3132
[CompletionResult]::new('--json-output', '--json-output', [CompletionResultType]::ParameterName, 'Print JSON data instead of an ASCII chart')
3233
[CompletionResult]::new('--top-down', '--top-down', [CompletionResultType]::ParameterName, 'Print the tree top-down instead of bottom-up')

exports/completion.zsh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ block-count\:"Count numbers of blocks"))' \
2525
'(--column-width)--total-width=[Width of the visualization]:TOTAL_WIDTH:_default' \
2626
'*--column-width=[Maximum widths of the tree column and width of the bar column]:TREE_WIDTH:_default:TREE_WIDTH:_default' \
2727
'--min-ratio=[Minimal size proportion required to appear]:MIN_RATIO:_default' \
28+
'--threads=[Set the maximum number of threads to spawn. Could be either "auto", "max", or a number]:THREADS:_default' \
2829
'(--quantity)--json-input[Read JSON data from stdin]' \
2930
'--json-output[Print JSON data instead of an ASCII chart]' \
3031
'--top-down[Print the tree top-down instead of bottom-up]' \

src/app.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub mod sub;
33
pub use sub::Sub;
44

55
use crate::{
6-
args::{Args, Quantity},
6+
args::{Args, Quantity, Threads},
77
get_size::GetApparentSize,
88
json_data::{JsonData, UnitAndTree},
99
reporter::{ErrorOnlyReporter, ErrorReport, ProgressAndErrorReporter, ProgressReport},
@@ -46,16 +46,25 @@ impl App {
4646
//
4747
// The other operations which are invoked frequently should not utilize dynamic dispatch.
4848

49-
{
50-
// If one of the files is on HDD, set thread number to 1
51-
let disks = Disks::new_with_refreshed_list();
52-
if any_path_is_in_hdd::<hdd::RealApi>(&self.args.files, &disks) {
53-
eprintln!("warning: HDD detected, the thread limit will be set to 1");
54-
rayon::ThreadPoolBuilder::new()
55-
.num_threads(1)
56-
.build_global()
57-
.unwrap_or_else(|_| eprintln!("warning: Failed to set thread limit to 1"));
49+
let threads = match self.args.threads {
50+
Threads::Auto => {
51+
let disks = Disks::new_with_refreshed_list();
52+
if any_path_is_in_hdd::<hdd::RealApi>(&self.args.files, &disks) {
53+
eprintln!("warning: HDD detected, the thread limit will be set to 1");
54+
Some(1)
55+
} else {
56+
None
57+
}
5858
}
59+
Threads::Max => None,
60+
Threads::Fixed(threads) => Some(threads),
61+
};
62+
63+
if let Some(threads) = threads {
64+
rayon::ThreadPoolBuilder::new()
65+
.num_threads(threads)
66+
.build_global()
67+
.unwrap_or_else(|_| eprintln!("warning: Failed to set thread limit to {threads}"));
5968
}
6069

6170
let column_width_distribution = self.args.column_width_distribution();

src/args.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
pub mod fraction;
22
pub mod quantity;
3+
pub mod threads;
34

45
pub use fraction::Fraction;
56
pub use quantity::Quantity;
7+
pub use threads::Threads;
68

79
use crate::{bytes_format::BytesFormat, visualizer::ColumnWidthDistribution};
810
use clap::{ColorChoice, Parser};
@@ -128,6 +130,10 @@ pub struct Args {
128130
/// Report progress being made at the expense of performance.
129131
#[clap(long)]
130132
pub progress: bool,
133+
134+
/// Set the maximum number of threads to spawn. Could be either "auto", "max", or a number.
135+
#[clap(long, default_value_t = Threads::Auto)]
136+
pub threads: Threads,
131137
}
132138

133139
impl Args {

src/args/threads.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use derive_more::{Display, Error};
2+
use std::{num::ParseIntError, str::FromStr};
3+
4+
const AUTO: &str = "auto";
5+
const MAX: &str = "max";
6+
7+
/// Number of rayon threads.
8+
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Display)]
9+
pub enum Threads {
10+
#[default]
11+
#[display("{AUTO}")]
12+
Auto,
13+
#[display("{MAX}")]
14+
Max,
15+
Fixed(usize),
16+
}
17+
18+
/// Error that occurs when converting a string to an instance of [`Threads`].
19+
#[derive(Debug, Display, Clone, PartialEq, Eq, Error)]
20+
pub enum FromStrError {
21+
#[display("Value is neither {AUTO:?}, {MAX:?}, nor a number: {_0}")]
22+
InvalidSyntax(ParseIntError),
23+
}
24+
25+
impl FromStr for Threads {
26+
type Err = FromStrError;
27+
fn from_str(value: &str) -> Result<Self, Self::Err> {
28+
let value = value.trim();
29+
match value {
30+
AUTO => return Ok(Threads::Auto),
31+
MAX => return Ok(Threads::Max),
32+
_ => {}
33+
};
34+
value
35+
.parse()
36+
.map_err(FromStrError::InvalidSyntax)
37+
.map(Threads::Fixed)
38+
}
39+
}

0 commit comments

Comments
 (0)