mirror of
https://github.com/ClementTsang/bottom.git
synced 2026-09-24 11:35:38 +00:00
feature: support binary prefix option for disk table I/O (#2251)
This is a follow-up to https://github.com/ClementTsang/bottom/pull/2236#issuecomment-5689665534 so the binary prefix configuration also affects the disk I/O display. Note this does not touch the graph at the moment, just the table.
This commit is contained in:
+2
-1
@@ -30,7 +30,8 @@ That said, these are more guidelines rather than hard rules, though the project
|
||||
|
||||
- [#2239](https://github.com/ClementTsang/bottom/pull/2239): Initial Intel GPU support for Linux to get process GPU usage.
|
||||
- [#2245](https://github.com/ClementTsang/bottom/pull/2245): Support solid bars using block and square characters via `styles.widgets.bar_type`.
|
||||
- [#2236](https://github.com/ClementTsang/bottom/pull/2236): Add configurable binary disk capacity units for usage.
|
||||
- [#2236](https://github.com/ClementTsang/bottom/pull/2236): Add configurable binary disk capacity units for disk widget usage.
|
||||
- [#2251](https://github.com/ClementTsang/bottom/pull/2251): Add configurable binary disk capacity units for disk widget I/O.
|
||||
|
||||
### Other
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ see information on these options by running `btm -h`, or run `btm --help` to dis
|
||||
|
||||
## Disk Options
|
||||
|
||||
| Option | Behaviour |
|
||||
| -------------------------- | --------------------------------------------------------------- |
|
||||
| `--disk_use_binary_prefix` | Displays used, free, and total disk space with binary prefixes. |
|
||||
| Option | Behaviour |
|
||||
| -------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `--disk_use_binary_prefix` | Displays the disk widget with binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB). |
|
||||
|
||||
## Process Options
|
||||
|
||||
@@ -77,15 +77,15 @@ see information on these options by running `btm -h`, or run `btm --help` to dis
|
||||
|
||||
## Network Options
|
||||
|
||||
| Option | Behaviour |
|
||||
| ----------------------------- | -------------------------------------------------------------- |
|
||||
| `--network_legend <POSITION>` | Where to place the legend for the network chart widget. |
|
||||
| `--network_use_bytes` | Displays the network widget using bytes. |
|
||||
| `--network_use_binary_prefix` | Displays the network widget with binary prefixes. |
|
||||
| `--network_use_log` | Displays the network widget with a log scale. |
|
||||
| `--show_packets` | Displays packet rate and average packet size info. |
|
||||
| `--use_old_network_legend` | Uses a separate network legend. |
|
||||
| `--network_start_zeroed` | Show total network usage from app startup rather than on boot. |
|
||||
| Option | Behaviour |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `--network_legend <POSITION>` | Where to place the legend for the network chart widget. |
|
||||
| `--network_use_bytes` | Displays the network widget using bytes. |
|
||||
| `--network_use_binary_prefix` | Displays the network widget binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB). |
|
||||
| `--network_use_log` | Displays the network widget with a log scale. |
|
||||
| `--show_packets` | Displays packet rate and average packet size info. |
|
||||
| `--use_old_network_legend` | Uses a separate network legend. |
|
||||
| `--network_start_zeroed` | Show total network usage from app startup rather than on boot. |
|
||||
|
||||
## Battery Options
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ You can also set the sort order by changing `disk.sort_order` with `"Ascending"`
|
||||
sort_order = "Ascending"
|
||||
```
|
||||
|
||||
## Disk Space Units
|
||||
## Using Binary Prefixes
|
||||
|
||||
Disk space uses decimal prefixes (KB, MB, GB, TB) by default. To display the Used, Free, and Total columns
|
||||
with binary prefixes (KiB, MiB, GiB, TiB), enable `use_binary_prefix`:
|
||||
Disk space uses decimal prefixes (e.g. KB, MB, GB, TB) by default. To display using binary prefixes instead
|
||||
(e.g. KiB, MiB, GiB, TiB), enable `use_binary_prefix`:
|
||||
|
||||
```toml
|
||||
[disk]
|
||||
|
||||
@@ -155,7 +155,6 @@
|
||||
# Where to place the legend for the network widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
|
||||
#network_legend = "top-right"
|
||||
|
||||
|
||||
# Processes widget configuration
|
||||
#[processes]
|
||||
# The columns shown by the process widget. The following columns are supported (the GPU columns are only available if the GPU feature is enabled when built):
|
||||
@@ -209,7 +208,6 @@
|
||||
# Show process CPU% usage without averaging over the number of CPU cores.
|
||||
#unnormalized_cpu = false
|
||||
|
||||
|
||||
# CPU widget configuration
|
||||
#[cpu]
|
||||
# One of "all" (default), "average"/"avg"
|
||||
@@ -218,11 +216,10 @@
|
||||
# Whether to show a decimal place for CPU usage values.
|
||||
#show_decimal = false
|
||||
|
||||
|
||||
# Disk widget configuration
|
||||
#[disk]
|
||||
|
||||
# Whether to display used, free, and total disk space with binary prefixes (e.g. GiB instead of GB).
|
||||
# Whether to display disk widget data with binary prefixes (e.g. GiB instead of GB).
|
||||
#use_binary_prefix = false
|
||||
|
||||
# The columns shown by the process widget. The following columns are supported:
|
||||
@@ -277,7 +274,6 @@
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Disk I/O graph widget configuration
|
||||
#[disk_io_graph]
|
||||
|
||||
@@ -316,7 +312,6 @@
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Temperature widget configuration
|
||||
#[temperature]
|
||||
|
||||
@@ -347,7 +342,6 @@
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Temperature graph widget configuration
|
||||
#[temperature_graph]
|
||||
|
||||
@@ -375,7 +369,6 @@
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Memory widget configuration
|
||||
#[memory_graph]
|
||||
|
||||
@@ -391,7 +384,6 @@
|
||||
# Use short GPU names (e.g. "GPU" or "GPU0", "GPU1") instead of full GPU names. Only available if the GPU feature is enabled when built.
|
||||
#short_gpu_names = false
|
||||
|
||||
|
||||
# Network widget configuration
|
||||
#[network_graph]
|
||||
|
||||
@@ -418,7 +410,6 @@
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# These are all the components that support custom theming. Note that colour support
|
||||
# will depend on terminal support.
|
||||
#[styles] # Uncomment if you want to use custom styling
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"$ref": "#/$defs/SortOrder"
|
||||
},
|
||||
"use_binary_prefix": {
|
||||
"description": "Displays used, free, and total disk space with binary prefixes (e.g. GiB).\nDefaults to decimal prefixes (e.g. GB).",
|
||||
"description": "Use binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB).\n\nDefaults to decimal prefixes.",
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
|
||||
+1
-10
@@ -404,7 +404,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Where to place the legend for the network widget. One of "none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right".
|
||||
#network_legend = "top-right"
|
||||
|
||||
|
||||
# Processes widget configuration
|
||||
#[processes]
|
||||
# The columns shown by the process widget. The following columns are supported (the GPU columns are only available if the GPU feature is enabled when built):
|
||||
@@ -458,7 +457,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Show process CPU% usage without averaging over the number of CPU cores.
|
||||
#unnormalized_cpu = false
|
||||
|
||||
|
||||
# CPU widget configuration
|
||||
#[cpu]
|
||||
# One of "all" (default), "average"/"avg"
|
||||
@@ -467,11 +465,10 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to show a decimal place for CPU usage values.
|
||||
#show_decimal = false
|
||||
|
||||
|
||||
# Disk widget configuration
|
||||
#[disk]
|
||||
|
||||
# Whether to display used, free, and total disk space with binary prefixes (e.g. GiB instead of GB).
|
||||
# Whether to display disk widget data with binary prefixes (e.g. GiB instead of GB).
|
||||
#use_binary_prefix = false
|
||||
|
||||
# The columns shown by the process widget. The following columns are supported:
|
||||
@@ -526,7 +523,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Disk I/O graph widget configuration
|
||||
#[disk_io_graph]
|
||||
|
||||
@@ -565,7 +561,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Temperature widget configuration
|
||||
#[temperature]
|
||||
|
||||
@@ -596,7 +591,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Temperature graph widget configuration
|
||||
#[temperature_graph]
|
||||
|
||||
@@ -624,7 +618,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# Memory widget configuration
|
||||
#[memory_graph]
|
||||
|
||||
@@ -640,7 +633,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Use short GPU names (e.g. "GPU" or "GPU0", "GPU1") instead of full GPU names. Only available if the GPU feature is enabled when built.
|
||||
#short_gpu_names = false
|
||||
|
||||
|
||||
# Network widget configuration
|
||||
#[network_graph]
|
||||
|
||||
@@ -667,7 +659,6 @@ pub(crate) const CONFIG_TEXT: &str = r#"# This is a default config file for bott
|
||||
# Whether to require matching the whole word. Defaults to false.
|
||||
#whole_word = false
|
||||
|
||||
|
||||
# These are all the components that support custom theming. Note that colour support
|
||||
# will depend on terminal support.
|
||||
#[styles] # Uncomment if you want to use custom styling
|
||||
|
||||
+3
-5
@@ -562,9 +562,8 @@ pub struct DiskArgs {
|
||||
#[arg(
|
||||
long,
|
||||
action = ArgAction::SetTrue,
|
||||
help = "Displays disk space with binary prefixes.",
|
||||
long_help = "Displays used, free, and total disk space with binary prefixes (e.g. KiB, MiB, GiB) \
|
||||
rather than decimal prefixes (e.g. KB, MB, GB). Defaults to decimal prefixes.",
|
||||
help = "Displays the disk widget with binary prefixes.",
|
||||
long_help = "Displays the disk widget with binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB).",
|
||||
alias = "disk-use-binary-prefix"
|
||||
)]
|
||||
pub disk_use_binary_prefix: bool,
|
||||
@@ -598,8 +597,7 @@ pub struct NetworkArgs {
|
||||
long,
|
||||
action = ArgAction::SetTrue,
|
||||
help = "Displays the network widget with binary prefixes.",
|
||||
long_help = "Displays the network widget with binary prefixes (e.g. kibibits, mebibits) rather than a decimal \
|
||||
prefixes (e.g. kilobits, megabits). Defaults to decimal prefixes.",
|
||||
long_help = "Displays the network widget binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB).",
|
||||
alias = "network-use-binary-prefix"
|
||||
)]
|
||||
pub network_use_binary_prefix: bool,
|
||||
|
||||
@@ -8,8 +8,9 @@ use crate::{canvas::components::data_table::SortOrder, options::DiskWidgetColumn
|
||||
#[cfg_attr(feature = "generate_schema", derive(schemars::JsonSchema))]
|
||||
#[cfg_attr(test, serde(deny_unknown_fields), derive(PartialEq, Eq))]
|
||||
pub(crate) struct DiskConfig {
|
||||
/// Displays used, free, and total disk space with binary prefixes (e.g. GiB).
|
||||
/// Defaults to decimal prefixes (e.g. GB).
|
||||
/// Use binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB).
|
||||
///
|
||||
/// Defaults to decimal prefixes.
|
||||
pub(crate) use_binary_prefix: Option<bool>,
|
||||
|
||||
/// A filter over the disk names.
|
||||
|
||||
+71
-3
@@ -20,9 +20,9 @@ pub(crate) fn get_binary_unit_and_denominator(bytes: u64) -> (&'static str, f64)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a string given a value that is converted to the closest SI-variant,
|
||||
/// per second. If the value is greater than a giga-X, then it will return a
|
||||
/// decimal place.
|
||||
/// Returns a decimal-prefixed string given a value that is converted to the
|
||||
/// closest SI-variant, per second. If the value is greater than a giga-X,
|
||||
/// then it will return a decimal place.
|
||||
#[inline]
|
||||
pub(crate) fn dec_bytes_per_second_string(value: u64) -> String {
|
||||
let converted_values = get_decimal_bytes(value);
|
||||
@@ -33,6 +33,19 @@ pub(crate) fn dec_bytes_per_second_string(value: u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a binary-prefixed string given a value that is converted to the
|
||||
/// closest IEC-variant, per second. If the value is greater than a gibi-X,
|
||||
/// then it will return a decimal place.
|
||||
#[inline]
|
||||
pub(crate) fn bin_bytes_per_second_string(value: u64) -> String {
|
||||
let converted_values = get_binary_bytes(value);
|
||||
if value >= GIBI_LIMIT {
|
||||
format!("{:.1}{}/s", converted_values.0, converted_values.1)
|
||||
} else {
|
||||
format!("{:.0}{}/s", converted_values.0, converted_values.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@@ -71,4 +84,59 @@ mod test {
|
||||
"10.4TB/s".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bin_bytes_per_second_string() {
|
||||
assert_eq!(bin_bytes_per_second_string(0), "0B/s".to_string());
|
||||
assert_eq!(bin_bytes_per_second_string(1), "1B/s".to_string());
|
||||
assert_eq!(bin_bytes_per_second_string(900), "900B/s".to_string());
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(KILO_LIMIT),
|
||||
"1000B/s".to_string()
|
||||
);
|
||||
assert_eq!(bin_bytes_per_second_string(1023), "1023B/s".to_string());
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(KIBI_LIMIT),
|
||||
"1KiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(KIBI_LIMIT + 1),
|
||||
"1KiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(MEBI_LIMIT),
|
||||
"1MiB/s".to_string()
|
||||
);
|
||||
|
||||
// The decimal place is added past a gibibyte, not a gigabyte.
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(GIGA_LIMIT),
|
||||
"954MiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(GIBI_LIMIT - 1),
|
||||
"1024MiB/s".to_string()
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(GIBI_LIMIT),
|
||||
"1.0GiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string(2 * GIBI_LIMIT),
|
||||
"2.0GiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string((2.5 * GIBI_LIMIT as f64) as u64),
|
||||
"2.5GiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string((10.34 * TEBI_LIMIT as f64) as u64),
|
||||
"10.3TiB/s".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
bin_bytes_per_second_string((10.36 * TEBI_LIMIT as f64) as u64),
|
||||
"10.4TiB/s".to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+27
-11
@@ -10,13 +10,16 @@ use crate::{
|
||||
},
|
||||
options::config::style::Styles,
|
||||
utils::{
|
||||
conversion::dec_bytes_per_second_string, data_units::convert_bytes,
|
||||
conversion::{bin_bytes_per_second_string, dec_bytes_per_second_string},
|
||||
data_units::convert_bytes,
|
||||
general::sort_partial_fn,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DiskWidgetData {
|
||||
// TODO: Remove this field, carry it through the widget configuration
|
||||
// rather than data (requires some refactoring)
|
||||
pub use_binary_prefix: bool,
|
||||
pub name: String,
|
||||
pub mount_point: String,
|
||||
@@ -86,13 +89,21 @@ impl DiskWidgetData {
|
||||
|
||||
fn io_read(&self) -> Cow<'static, str> {
|
||||
self.io_read_rate_bytes.map_or("N/A".into(), |r_rate| {
|
||||
dec_bytes_per_second_string(r_rate).into()
|
||||
if self.use_binary_prefix {
|
||||
bin_bytes_per_second_string(r_rate).into()
|
||||
} else {
|
||||
dec_bytes_per_second_string(r_rate).into()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn io_write(&self) -> Cow<'static, str> {
|
||||
self.io_write_rate_bytes.map_or("N/A".into(), |w_rate| {
|
||||
dec_bytes_per_second_string(w_rate).into()
|
||||
if self.use_binary_prefix {
|
||||
bin_bytes_per_second_string(w_rate).into()
|
||||
} else {
|
||||
dec_bytes_per_second_string(w_rate).into()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -431,7 +442,7 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
fn cell(data: &DiskWidgetData, column: DiskWidgetColumn) -> Cow<'static, str> {
|
||||
fn render_cell(data: &DiskWidgetData, column: DiskWidgetColumn) -> Cow<'static, str> {
|
||||
data.to_cell_text(&column, NonZeroU16::new(10).unwrap())
|
||||
.unwrap()
|
||||
}
|
||||
@@ -455,7 +466,7 @@ mod test {
|
||||
DiskWidgetColumn::Free,
|
||||
DiskWidgetColumn::Total,
|
||||
] {
|
||||
assert_eq!(cell(&data, column), expected);
|
||||
assert_eq!(render_cell(&data, column), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,15 +485,20 @@ mod test {
|
||||
DiskWidgetColumn::IoRead,
|
||||
DiskWidgetColumn::IoWrite,
|
||||
] {
|
||||
assert_eq!(cell(&missing, column), "N/A");
|
||||
assert_eq!(render_cell(&missing, column), "N/A");
|
||||
}
|
||||
let data = disk(Some(500 * GIBI_LIMIT), use_binary_prefix);
|
||||
assert_eq!(cell(&data, DiskWidgetColumn::UsedPercent), "50.0%");
|
||||
assert_eq!(cell(&data, DiskWidgetColumn::FreePercent), "50.0%");
|
||||
assert_eq!(cell(&data, DiskWidgetColumn::IoRead), "536.9GB/s");
|
||||
assert_eq!(cell(&data, DiskWidgetColumn::IoWrite), "536.9GB/s");
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::UsedPercent), "50.0%");
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::FreePercent), "50.0%");
|
||||
if use_binary_prefix {
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::IoRead), "500.0GiB/s");
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::IoWrite), "500.0GiB/s");
|
||||
} else {
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::IoRead), "536.9GB/s");
|
||||
assert_eq!(render_cell(&data, DiskWidgetColumn::IoWrite), "536.9GB/s");
|
||||
}
|
||||
assert_eq!(
|
||||
cell(
|
||||
render_cell(
|
||||
&disk(Some(0), use_binary_prefix),
|
||||
DiskWidgetColumn::UsedPercent
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user