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
This commit is contained in:
Clement Tsang 2023-04-12 00:03:27 -04:00 committed by GitHub
parent 857b5bade0
commit e61e5f2af6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 75 additions and 64 deletions

39
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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::*;

View file

@ -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<Pid, ProcessHarvest>,
/// A mapping between a process PID to any children process PIDs.
pub process_parent_mapping: FxHashMap<Pid, Vec<Pid>>,
pub process_parent_mapping: HashMap<Pid, Vec<Pid>>,
/// PIDs corresponding to processes that have no parents.
pub orphan_pids: Vec<Pid>,

View file

@ -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<crate::Pid, processes::PrevProcDetails>,
pid_mapping: HashMap<crate::Pid, processes::PrevProcDetails>,
#[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")]

View file

@ -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<Filter>, mount_filter: &Option<Filter>) -> Vec<usize> {
let targets = [

View file

@ -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;

View file

@ -1,5 +1,4 @@
use anyhow::bail;
use mach2::kern_return;
use super::{bindings::*, IoIterator};

View file

@ -1,4 +1,5 @@
use std::mem::{size_of, zeroed};
use windows::Win32::Foundation::TRUE;
use windows::Win32::System::ProcessStatus::{GetPerformanceInfo, PERFORMANCE_INFORMATION};

View file

@ -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(

View file

@ -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<std::collections::HashMap<i32, f64>> {
fn get_freebsd_process_cpu_usage(pids: &[i32]) -> io::Result<HashMap<i32, f64>> {
if pids.is_empty() {
return Ok(std::collections::HashMap::new());
return Ok(HashMap::new());
}
let output = std::process::Command::new("ps")

View file

@ -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<Pid, PrevProcDetails>,
sys: &System, prev_proc: PrevProc<'_>, pid_mapping: &mut HashMap<Pid, PrevProcDetails>,
proc_harvest_options: ProcHarvestOptions, time_difference_in_secs: u64, total_memory: u64,
user_table: &mut UserTable,
) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
@ -261,7 +261,7 @@ pub(crate) fn get_process_data(
cpu_usage /= num_processors;
}
let mut pids_to_clear: FxHashSet<Pid> = pid_mapping.keys().cloned().collect();
let mut pids_to_clear: HashSet<Pid> = pid_mapping.keys().cloned().collect();
let process_vector: Vec<ProcessHarvest> = std::fs::read_dir("/proc")?
.filter_map(|dir| {

View file

@ -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<Pid> {
.ok()
}
fn get_macos_process_cpu_usage(
pids: &[Pid],
) -> std::io::Result<std::collections::HashMap<i32, f64>> {
fn get_macos_process_cpu_usage(pids: &[Pid]) -> std::io::Result<HashMap<i32, f64>> {
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::<String>(),
)
.output()?;
let mut result = std::collections::HashMap::new();
let mut result = HashMap::new();
String::from_utf8_lossy(&output.stdout)
.split_whitespace()
.chunks(2)

View file

@ -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;

View file

@ -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<libc::uid_t, String>,
pub uid_user_mapping: HashMap<libc::uid_t, String>,
}
impl UserTable {

View file

@ -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);

View file

@ -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};

View file

@ -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();

View file

@ -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<Pid> },
Tree { collapsed_pids: HashSet<Pid> },
Grouped,
Normal,
}
type ProcessTable = SortDataTable<ProcWidgetData, ProcColumn>;
type SortTable = DataTable<Cow<'static, str>, SortTableColumn>;
type StringPidMap = FxHashMap<String, Vec<Pid>>;
type StringPidMap = HashMap<String, Vec<Pid>>;
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<Pid>, data_collection: &DataCollection,
&self, collapsed_pids: &HashSet<Pid>, data_collection: &DataCollection,
) -> Vec<ProcWidgetData> {
const BRANCH_END: char = '└';
const BRANCH_VERTICAL: char = '│';
@ -305,11 +305,11 @@ impl ProcWidgetState {
None
}
})
.collect::<FxHashSet<_>>();
.collect::<HashSet<_>>();
#[inline]
fn is_ancestor_shown(
current_process: &ProcessHarvest, kept_pids: &FxHashSet<Pid>,
current_process: &ProcessHarvest, kept_pids: &HashSet<Pid>,
process_harvest: &BTreeMap<Pid, ProcessHarvest>,
) -> 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<Pid, Vec<Pid>> = 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<Pid, bool> = 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<String, Vec<Pid>> = FxHashMap::default();
let mut id_pid_map: HashMap<String, Vec<Pid>> = HashMap::default();
let mut filtered_data: Vec<ProcWidgetData> = 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

View file

@ -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.

View file

@ -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 {