From e61e5f2af6b5f533461e15bb04250e9ad94a6627 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Wed, 12 Apr 2023 00:03:27 -0400 Subject: [PATCH] deps: Switch to using hashbrown for general hashmap usage (#1092) * deps: replace fxhash with hashbrown + ahash * replace std hashmap with hashbrown + ahash * fmt * some more fmt --- Cargo.lock | 39 +++++++++++++------ Cargo.toml | 2 +- src/app.rs | 2 +- src/app/data_farmer.rs | 4 +- src/app/data_harvester.rs | 9 ++--- src/app/data_harvester/disks.rs | 7 ++-- .../disks/unix/macos/io_kit/bindings.rs | 1 - .../disks/unix/macos/io_kit/io_disks.rs | 1 - src/app/data_harvester/memory/windows.rs | 1 + src/app/data_harvester/network/sysinfo.rs | 3 +- src/app/data_harvester/processes/freebsd.rs | 5 ++- src/app/data_harvester/processes/linux.rs | 6 +-- src/app/data_harvester/processes/macos.rs | 7 ++-- .../data_harvester/processes/macos_freebsd.rs | 2 +- src/app/data_harvester/processes/unix.rs | 4 +- src/app/process_killer.rs | 8 ++-- src/app/states.rs | 3 +- src/options.rs | 8 ++-- src/widgets/process_table.rs | 22 +++++------ tests/layout_management_tests.rs | 1 - tests/util.rs | 4 +- 21 files changed, 75 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 446504d2..bd4ff2d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -111,7 +122,7 @@ dependencies = [ "dirs", "fern", "filedescriptor", - "fxhash", + "hashbrown 0.13.2", "humantime", "humantime-serde", "indexmap", @@ -522,15 +533,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "getrandom" version = "0.2.6" @@ -554,6 +556,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "heck" version = "0.4.1" @@ -604,7 +615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1379,6 +1390,12 @@ dependencies = [ "typenum", ] +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wait-timeout" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index e0c0529c..44ccc2f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ ctrlc = { version = "3.2.5", features = ["termination"] } # dhat = "0.3.2" dirs = "5.0.0" fern = { version = "0.6.2", optional = true } -fxhash = "0.2.1" +hashbrown = "0.13.2" humantime = "2.1.0" humantime-serde = "1.1.1" indexmap = "1.9.3" diff --git a/src/app.rs b/src/app.rs index 9c3a37fd..7136deb8 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,5 @@ use std::{ cmp::{max, min}, - collections::HashMap, time::Instant, }; @@ -8,6 +7,7 @@ use concat_string::concat_string; use data_farmer::*; use data_harvester::temperature; use filter::*; +use hashbrown::HashMap; use layout_manager::*; pub use states::*; use typed_builder::*; diff --git a/src/app/data_farmer.rs b/src/app/data_farmer.rs index b36946dc..af130c3c 100644 --- a/src/app/data_farmer.rs +++ b/src/app/data_farmer.rs @@ -15,7 +15,7 @@ use std::{collections::BTreeMap, time::Instant, vec::Vec}; -use fxhash::FxHashMap; +use hashbrown::HashMap; #[cfg(feature = "battery")] use crate::data_harvester::batteries; @@ -48,7 +48,7 @@ pub struct ProcessData { pub process_harvest: BTreeMap, /// A mapping between a process PID to any children process PIDs. - pub process_parent_mapping: FxHashMap>, + pub process_parent_mapping: HashMap>, /// PIDs corresponding to processes that have no parents. pub orphan_pids: Vec, diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs index 77e301f6..7904f495 100644 --- a/src/app/data_harvester.rs +++ b/src/app/data_harvester.rs @@ -3,15 +3,12 @@ use std::time::{Duration, Instant}; #[cfg(target_os = "linux")] -use fxhash::FxHashMap; - +use hashbrown::HashMap; #[cfg(feature = "battery")] use starship_battery::{Battery, Manager}; - use sysinfo::{System, SystemExt}; use self::temperature::TemperatureType; - use super::DataFilters; use crate::app::layout_manager::UsedWidgets; @@ -111,7 +108,7 @@ pub struct DataCollector { filters: DataFilters, #[cfg(target_os = "linux")] - pid_mapping: FxHashMap, + pid_mapping: HashMap, #[cfg(target_os = "linux")] prev_idle: f64, #[cfg(target_os = "linux")] @@ -132,7 +129,7 @@ impl DataCollector { data: Data::default(), sys: System::new_with_specifics(sysinfo::RefreshKind::new()), #[cfg(target_os = "linux")] - pid_mapping: FxHashMap::default(), + pid_mapping: HashMap::default(), #[cfg(target_os = "linux")] prev_idle: 0_f64, #[cfg(target_os = "linux")] diff --git a/src/app/data_harvester/disks.rs b/src/app/data_harvester/disks.rs index fbd06a94..146965be 100644 --- a/src/app/data_harvester/disks.rs +++ b/src/app/data_harvester/disks.rs @@ -1,9 +1,9 @@ //! Data collection about disks (e.g. I/O, usage, space). -use std::collections::HashMap; +use cfg_if::cfg_if; +use hashbrown::HashMap; use crate::app::filter::Filter; -use cfg_if::cfg_if; cfg_if! { if #[cfg(target_os = "freebsd")] { @@ -114,9 +114,8 @@ pub(self) fn keep_disk_entry( mod test { use regex::Regex; - use crate::app::filter::Filter; - use super::keep_disk_entry; + use crate::app::filter::Filter; fn run_filter(disk_filter: &Option, mount_filter: &Option) -> Vec { let targets = [ diff --git a/src/app/data_harvester/disks/unix/macos/io_kit/bindings.rs b/src/app/data_harvester/disks/unix/macos/io_kit/bindings.rs index bb586b31..decc8a77 100644 --- a/src/app/data_harvester/disks/unix/macos/io_kit/bindings.rs +++ b/src/app/data_harvester/disks/unix/macos/io_kit/bindings.rs @@ -7,7 +7,6 @@ use core_foundation::base::{mach_port_t, CFAllocatorRef}; use core_foundation::dictionary::CFMutableDictionaryRef; - use libc::c_char; use mach2::kern_return::kern_return_t; use mach2::port::MACH_PORT_NULL; diff --git a/src/app/data_harvester/disks/unix/macos/io_kit/io_disks.rs b/src/app/data_harvester/disks/unix/macos/io_kit/io_disks.rs index 3d206973..9552b0b7 100644 --- a/src/app/data_harvester/disks/unix/macos/io_kit/io_disks.rs +++ b/src/app/data_harvester/disks/unix/macos/io_kit/io_disks.rs @@ -1,5 +1,4 @@ use anyhow::bail; - use mach2::kern_return; use super::{bindings::*, IoIterator}; diff --git a/src/app/data_harvester/memory/windows.rs b/src/app/data_harvester/memory/windows.rs index dc244450..c54657e9 100644 --- a/src/app/data_harvester/memory/windows.rs +++ b/src/app/data_harvester/memory/windows.rs @@ -1,4 +1,5 @@ use std::mem::{size_of, zeroed}; + use windows::Win32::Foundation::TRUE; use windows::Win32::System::ProcessStatus::{GetPerformanceInfo, PERFORMANCE_INFORMATION}; diff --git a/src/app/data_harvester/network/sysinfo.rs b/src/app/data_harvester/network/sysinfo.rs index ec21bd42..9c2aaade 100644 --- a/src/app/data_harvester/network/sysinfo.rs +++ b/src/app/data_harvester/network/sysinfo.rs @@ -2,9 +2,8 @@ use std::time::Instant; -use crate::app::Filter; - use super::NetworkHarvest; +use crate::app::Filter; // TODO: Eventually make it so that this thing also takes individual usage into account, so we can show per-interface! pub fn get_network_data( diff --git a/src/app/data_harvester/processes/freebsd.rs b/src/app/data_harvester/processes/freebsd.rs index 715d2271..43c373e0 100644 --- a/src/app/data_harvester/processes/freebsd.rs +++ b/src/app/data_harvester/processes/freebsd.rs @@ -2,6 +2,7 @@ use std::io; +use hashbrown::HashMap; use serde::{Deserialize, Deserializer}; use sysinfo::System; @@ -38,9 +39,9 @@ pub fn get_process_data( ) } -fn get_freebsd_process_cpu_usage(pids: &[i32]) -> io::Result> { +fn get_freebsd_process_cpu_usage(pids: &[i32]) -> io::Result> { if pids.is_empty() { - return Ok(std::collections::HashMap::new()); + return Ok(HashMap::new()); } let output = std::process::Command::new("ps") diff --git a/src/app/data_harvester/processes/linux.rs b/src/app/data_harvester/processes/linux.rs index 4ada595f..4918230f 100644 --- a/src/app/data_harvester/processes/linux.rs +++ b/src/app/data_harvester/processes/linux.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::{BufRead, BufReader}; -use fxhash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; use procfs::process::{Process, Stat}; use sysinfo::{ProcessStatus, System}; @@ -231,7 +231,7 @@ pub(crate) struct ProcHarvestOptions { } pub(crate) fn get_process_data( - sys: &System, prev_proc: PrevProc<'_>, pid_mapping: &mut FxHashMap, + sys: &System, prev_proc: PrevProc<'_>, pid_mapping: &mut HashMap, proc_harvest_options: ProcHarvestOptions, time_difference_in_secs: u64, total_memory: u64, user_table: &mut UserTable, ) -> crate::utils::error::Result> { @@ -261,7 +261,7 @@ pub(crate) fn get_process_data( cpu_usage /= num_processors; } - let mut pids_to_clear: FxHashSet = pid_mapping.keys().cloned().collect(); + let mut pids_to_clear: HashSet = pid_mapping.keys().cloned().collect(); let process_vector: Vec = std::fs::read_dir("/proc")? .filter_map(|dir| { diff --git a/src/app/data_harvester/processes/macos.rs b/src/app/data_harvester/processes/macos.rs index 7679e3ba..95e6fd9a 100644 --- a/src/app/data_harvester/processes/macos.rs +++ b/src/app/data_harvester/processes/macos.rs @@ -1,5 +1,6 @@ //! Process data collection for macOS. Uses sysinfo and custom bindings. +use hashbrown::HashMap; use sysinfo::System; use super::ProcessHarvest; @@ -26,9 +27,7 @@ pub(crate) fn fallback_macos_ppid(pid: Pid) -> Option { .ok() } -fn get_macos_process_cpu_usage( - pids: &[Pid], -) -> std::io::Result> { +fn get_macos_process_cpu_usage(pids: &[Pid]) -> std::io::Result> { use itertools::Itertools; let output = std::process::Command::new("ps") .args(["-o", "pid=,pcpu=", "-p"]) @@ -38,7 +37,7 @@ fn get_macos_process_cpu_usage( .collect::(), ) .output()?; - let mut result = std::collections::HashMap::new(); + let mut result = HashMap::new(); String::from_utf8_lossy(&output.stdout) .split_whitespace() .chunks(2) diff --git a/src/app/data_harvester/processes/macos_freebsd.rs b/src/app/data_harvester/processes/macos_freebsd.rs index 88076592..183722fc 100644 --- a/src/app/data_harvester/processes/macos_freebsd.rs +++ b/src/app/data_harvester/processes/macos_freebsd.rs @@ -1,8 +1,8 @@ //! Shared process data harvesting code from macOS and FreeBSD via sysinfo. -use std::collections::HashMap; use std::io; +use hashbrown::HashMap; use sysinfo::{CpuExt, PidExt, ProcessExt, ProcessStatus, System, SystemExt}; use super::ProcessHarvest; diff --git a/src/app/data_harvester/processes/unix.rs b/src/app/data_harvester/processes/unix.rs index 3e459e06..b0d68e23 100644 --- a/src/app/data_harvester/processes/unix.rs +++ b/src/app/data_harvester/processes/unix.rs @@ -1,12 +1,12 @@ //! Unix-specific parts of process collection. -use fxhash::FxHashMap; +use hashbrown::HashMap; use crate::utils::error; #[derive(Debug, Default)] pub struct UserTable { - pub uid_user_mapping: FxHashMap, + pub uid_user_mapping: HashMap, } impl UserTable { diff --git a/src/app/process_killer.rs b/src/app/process_killer.rs index cf23b076..862b17c2 100644 --- a/src/app/process_killer.rs +++ b/src/app/process_killer.rs @@ -1,9 +1,5 @@ //! This file is meant to house (OS specific) implementations on how to kill processes. -#[cfg(target_family = "unix")] -use crate::utils::error::BottomError; -use crate::Pid; - #[cfg(target_os = "windows")] use windows::Win32::{ Foundation::HANDLE, @@ -12,6 +8,10 @@ use windows::Win32::{ }, }; +#[cfg(target_family = "unix")] +use crate::utils::error::BottomError; +use crate::Pid; + /// Based from [this SO answer](https://stackoverflow.com/a/55231715). #[cfg(target_os = "windows")] struct Process(HANDLE); diff --git a/src/app/states.rs b/src/app/states.rs index 30e20291..d38b6d02 100644 --- a/src/app/states.rs +++ b/src/app/states.rs @@ -1,5 +1,6 @@ -use std::{collections::HashMap, ops::Range, time::Instant}; +use std::{ops::Range, time::Instant}; +use hashbrown::HashMap; use indexmap::IndexMap; use unicode_segmentation::{GraphemeCursor, GraphemeIncomplete, UnicodeSegmentation}; diff --git a/src/options.rs b/src/options.rs index 0a620129..0e24160b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,21 +1,20 @@ use std::{ borrow::Cow, - collections::{HashMap, HashSet}, convert::TryInto, str::FromStr, time::{Duration, Instant}, }; use clap::ArgMatches; +use hashbrown::{HashMap, HashSet}; use layout_options::*; use regex::Regex; use serde::{Deserialize, Serialize}; +use typed_builder::*; #[cfg(feature = "battery")] use starship_battery::Manager; -use typed_builder::*; - use crate::{ app::{filter::Filter, layout_manager::*, *}, canvas::{canvas_styling::CanvasColours, ColourScheme}, @@ -826,9 +825,8 @@ mod test { use clap::ArgMatches; - use crate::{app::App, canvas::canvas_styling::CanvasColours}; - use super::{get_color_scheme, get_widget_layout, Config}; + use crate::{app::App, canvas::canvas_styling::CanvasColours}; fn create_app(mut config: Config, matches: ArgMatches) -> App { let (layout, id, ty) = get_widget_layout(&matches, &config).unwrap(); diff --git a/src/widgets/process_table.rs b/src/widgets/process_table.rs index 12af6bc3..78b5823d 100644 --- a/src/widgets/process_table.rs +++ b/src/widgets/process_table.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, collections::BTreeMap}; use const_format::formatcp; -use fxhash::{FxHashMap, FxHashSet}; +use hashbrown::{HashMap, HashSet}; use itertools::Itertools; use crate::{ @@ -63,14 +63,14 @@ impl ProcessSearchState { #[derive(Clone, Debug, Eq, PartialEq)] pub enum ProcWidgetMode { - Tree { collapsed_pids: FxHashSet }, + Tree { collapsed_pids: HashSet }, Grouped, Normal, } type ProcessTable = SortDataTable; type SortTable = DataTable, SortTableColumn>; -type StringPidMap = FxHashMap>; +type StringPidMap = HashMap>; pub struct ProcWidgetState { pub mode: ProcWidgetMode, @@ -215,7 +215,7 @@ impl ProcWidgetState { show_memory_as_values, ); - let id_pid_map = FxHashMap::default(); + let id_pid_map = HashMap::default(); let mut table = ProcWidgetState { proc_search: process_search_state, @@ -271,7 +271,7 @@ impl ProcWidgetState { } fn get_tree_data( - &self, collapsed_pids: &FxHashSet, data_collection: &DataCollection, + &self, collapsed_pids: &HashSet, data_collection: &DataCollection, ) -> Vec { const BRANCH_END: char = '└'; const BRANCH_VERTICAL: char = '│'; @@ -305,11 +305,11 @@ impl ProcWidgetState { None } }) - .collect::>(); + .collect::>(); #[inline] fn is_ancestor_shown( - current_process: &ProcessHarvest, kept_pids: &FxHashSet, + current_process: &ProcessHarvest, kept_pids: &HashSet, process_harvest: &BTreeMap, ) -> bool { if let Some(ppid) = current_process.parent_pid { @@ -330,10 +330,10 @@ impl ProcWidgetState { // - The process contains some descendant that matches. // - The process's parent (and only parent, not any ancestor) matches. let filtered_tree = { - let mut filtered_tree = FxHashMap::default(); + let mut filtered_tree: HashMap> = HashMap::default(); // We do a simple DFS traversal to build our filtered parent-to-tree mappings. - let mut visited_pids = FxHashMap::default(); + let mut visited_pids: HashMap = HashMap::default(); let mut stack = orphan_pids .iter() .filter_map(|process| process_harvest.get(process)) @@ -534,9 +534,9 @@ impl ProcWidgetState { .unwrap_or(true) }); - let mut id_pid_map: FxHashMap> = FxHashMap::default(); + let mut id_pid_map: HashMap> = HashMap::default(); let mut filtered_data: Vec = if let ProcWidgetMode::Grouped = self.mode { - let mut id_process_mapping: FxHashMap<&String, ProcessHarvest> = FxHashMap::default(); + let mut id_process_mapping: HashMap<&String, ProcessHarvest> = HashMap::default(); for process in filtered_iter { let id = if is_using_command { &process.command diff --git a/tests/layout_management_tests.rs b/tests/layout_management_tests.rs index fb14eef2..7dd6114c 100644 --- a/tests/layout_management_tests.rs +++ b/tests/layout_management_tests.rs @@ -6,7 +6,6 @@ use bottom::constants::DEFAULT_BATTERY_LAYOUT; use bottom::constants::{DEFAULT_LAYOUT, DEFAULT_WIDGET_ID}; use bottom::options::{layout_options::Row, Config}; use bottom::utils::error; - use toml_edit::de::from_str; // TODO: Could move these into the library files rather than external tbh. diff --git a/tests/util.rs b/tests/util.rs index f7dbebee..40e50305 100644 --- a/tests/util.rs +++ b/tests/util.rs @@ -1,4 +1,6 @@ -use std::{collections::HashMap, env, process::Command}; +use std::{env, process::Command}; + +use hashbrown::HashMap; /// Returns a QEMU runner target given an architecture. fn get_qemu_target(arch: &str) -> &str {