perf: use FxHash instead of SipHash where it makes sense

This commit is contained in:
alexpasmantier 2025-01-07 02:07:47 +01:00
parent 263e88beb6
commit f416d39009
39 changed files with 193 additions and 157 deletions

4
Cargo.lock generated
View File

@ -3038,6 +3038,7 @@ dependencies = [
"ignore",
"lazy_static",
"regex",
"rustc-hash",
"serde",
"strum",
"television-derive",
@ -3076,6 +3077,7 @@ dependencies = [
"parking_lot",
"ratatui",
"regex",
"rustc-hash",
"simdutf8",
"smallvec",
"syntect",
@ -3092,6 +3094,7 @@ version = "0.0.18"
dependencies = [
"color-eyre",
"ratatui",
"rustc-hash",
"serde",
"syntect",
"television-channels",
@ -3109,6 +3112,7 @@ dependencies = [
"gag",
"ignore",
"lazy_static",
"rustc-hash",
"syntect",
"tracing",
"unicode-width 0.2.0",

View File

@ -4,13 +4,14 @@ use ratatui::layout::Alignment;
use ratatui::prelude::{Line, Style};
use ratatui::style::Color;
use ratatui::widgets::{Block, BorderType, Borders, ListDirection, Padding};
use rustc_hash::FxHashMap;
use television_channels::entry::merge_ranges;
use television_channels::entry::{Entry, PreviewType};
use television_screen::colors::ResultsColorscheme;
use television_screen::results::build_results_list;
pub fn results_list_benchmark(c: &mut Criterion) {
let mut icon_color_cache = std::collections::HashMap::default();
let mut icon_color_cache = FxHashMap::default();
// FIXME: there's probably a way to have this as a benchmark asset
// possible as a JSON file and to load it for the benchmark using Serde
// I don't know how exactly right now just having it here instead
@ -634,6 +635,7 @@ pub fn results_list_benchmark(c: &mut Criterion) {
result_name_fg: Color::Indexed(222),
result_preview_fg: Color::Indexed(222),
result_line_number_fg: Color::Indexed(222),
result_selected_fg: Color::Indexed(222),
result_selected_bg: Color::Indexed(222),
match_foreground_color: Color::Indexed(222),
};
@ -651,6 +653,7 @@ pub fn results_list_benchmark(c: &mut Criterion) {
.style(Style::default())
.padding(Padding::right(1)),
&entries,
None,
ListDirection::BottomToTop,
false,
&mut icon_color_cache,

View File

@ -25,6 +25,7 @@ color-eyre = { workspace = true }
serde = { workspace = true }
lazy_static = { workspace = true }
toml = { workspace = true }
rustc-hash = { workspace = true }
devicons = "0.6.11"
ignore = "0.4.23"

View File

@ -1,5 +1,5 @@
use rustc_hash::FxHashMap;
use std::{
collections::HashMap,
fmt::{self, Display, Formatter},
ops::Deref,
};
@ -27,10 +27,10 @@ impl Display for CableChannelPrototype {
}
#[derive(Debug, serde::Deserialize, Default)]
pub struct CableChannels(pub HashMap<String, CableChannelPrototype>);
pub struct CableChannels(pub FxHashMap<String, CableChannelPrototype>);
impl Deref for CableChannels {
type Target = HashMap<String, CableChannelPrototype>;
type Target = FxHashMap<String, CableChannelPrototype>;
fn deref(&self) -> &Self::Target {
&self.0

View File

@ -1,7 +1,6 @@
use std::collections::HashSet;
use crate::entry::Entry;
use color_eyre::Result;
use rustc_hash::FxHashSet;
use television_derive::{Broadcast, ToCliChannel, ToUnitChannel};
mod alias;
@ -68,7 +67,7 @@ pub trait OnAir: Send {
fn get_result(&self, index: u32) -> Option<Entry>;
/// Get the currently selected entries.
fn selected_entries(&self) -> &HashSet<Entry>;
fn selected_entries(&self) -> &FxHashSet<Entry>;
/// Toggles selection for the entry under the cursor.
fn toggle_selection(&mut self, entry: &Entry);

View File

@ -4,6 +4,8 @@ use crate::channels::OnAir;
use crate::entry::Entry;
use crate::entry::PreviewType;
use devicons::FileIcon;
use rustc_hash::FxBuildHasher;
use rustc_hash::FxHashSet;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
use television_utils::indices::sep_name_and_value_indices;
use tracing::debug;
@ -23,7 +25,7 @@ impl Alias {
pub struct Channel {
matcher: Matcher<Alias>,
file_icon: FileIcon,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
const NUM_THREADS: usize = 1;
@ -55,7 +57,7 @@ impl Channel {
Self {
matcher,
file_icon: FileIcon::from(FILE_ICON_STR),
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -119,7 +121,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -1,7 +1,9 @@
use std::collections::HashSet;
use color_eyre::Result;
use lazy_static::lazy_static;
use regex::Regex;
use std::collections::HashSet;
use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug;
use crate::cable::{CableChannelPrototype, DEFAULT_DELIMITER};
@ -26,7 +28,7 @@ pub struct Channel {
matcher: Matcher<String>,
entries_command: String,
preview_kind: PreviewKind,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Default for Channel {
@ -94,7 +96,7 @@ impl Channel {
entries_command: entries_command.to_string(),
preview_kind,
name: name.to_string(),
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -164,7 +166,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -1,6 +1,7 @@
use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewCommand, PreviewType};
use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet;
use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
@ -11,7 +12,7 @@ pub struct Channel {
crawl_handle: tokio::task::JoinHandle<()>,
// PERF: cache results (to make deleting characters smoother) with
// a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc")
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Channel {
@ -22,7 +23,7 @@ impl Channel {
Channel {
matcher,
crawl_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -114,7 +115,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -1,6 +1,7 @@
use std::collections::HashSet;
use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use super::OnAir;
use crate::entry::{Entry, PreviewType};
@ -17,7 +18,7 @@ struct EnvVar {
pub struct Channel {
matcher: Matcher<EnvVar>,
file_icon: FileIcon,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
const NUM_THREADS: usize = 1;
@ -35,7 +36,7 @@ impl Channel {
Channel {
matcher,
file_icon: FileIcon::from(FILE_ICON_STR),
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -99,7 +100,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -1,6 +1,7 @@
use crate::channels::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType};
use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet;
use std::path::PathBuf;
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
@ -11,7 +12,7 @@ pub struct Channel {
crawl_handle: tokio::task::JoinHandle<()>,
// PERF: cache results (to make deleting characters smoother) with
// a shallow stack of sub-patterns as keys (e.g. "a", "ab", "abc")
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Channel {
@ -22,7 +23,7 @@ impl Channel {
Channel {
matcher,
crawl_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -72,7 +73,7 @@ impl From<&mut TelevisionChannel> for Channel {
entries
.iter()
.map(|entry| PathBuf::from(&entry.name))
.collect::<HashSet<_>>()
.collect::<FxHashSet<_>>()
.into_iter()
.collect(),
)
@ -83,7 +84,7 @@ impl From<&mut TelevisionChannel> for Channel {
entries
.iter()
.map(|entry| PathBuf::from(&entry.name))
.collect::<HashSet<_>>()
.collect::<FxHashSet<_>>()
.into_iter()
.collect(),
)
@ -120,7 +121,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -2,6 +2,7 @@ use devicons::FileIcon;
use directories::BaseDirs;
use ignore::overrides::OverrideBuilder;
use lazy_static::lazy_static;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet;
use std::path::PathBuf;
use tokio::task::JoinHandle;
@ -16,7 +17,7 @@ pub struct Channel {
matcher: Matcher<String>,
icon: FileIcon,
crawl_handle: JoinHandle<()>,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Channel {
@ -31,7 +32,7 @@ impl Channel {
matcher,
icon: FileIcon::from("git"),
crawl_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -84,7 +85,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -7,6 +7,7 @@ use crate::entry::{Entry, PreviewType};
use clap::ValueEnum;
use color_eyre::Result;
use devicons::FileIcon;
use rustc_hash::{FxBuildHasher, FxHashSet};
use television_fuzzy::matcher::{config::Config, Matcher};
use super::cable;
@ -14,7 +15,7 @@ use super::cable;
pub struct RemoteControl {
matcher: Matcher<RCButton>,
cable_channels: Option<CableChannels>,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
#[derive(Clone)]
@ -61,7 +62,7 @@ impl RemoteControl {
RemoteControl {
matcher,
cable_channels,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
@ -143,7 +144,7 @@ impl OnAir for RemoteControl {
.collect()
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -4,6 +4,7 @@ use std::{
thread::spawn,
};
use rustc_hash::{FxBuildHasher, FxHashSet};
use tracing::debug;
use super::OnAir;
@ -13,7 +14,7 @@ use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
pub struct Channel {
matcher: Matcher<String>,
preview_type: PreviewType,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Channel {
@ -26,7 +27,7 @@ impl Channel {
Self {
matcher,
preview_type: preview_type.unwrap_or_default(),
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -93,7 +94,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -2,6 +2,7 @@ use super::{OnAir, TelevisionChannel};
use crate::entry::{Entry, PreviewType};
use devicons::FileIcon;
use ignore::WalkState;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::{
collections::HashSet,
fs::File,
@ -37,7 +38,7 @@ impl CandidateLine {
pub struct Channel {
matcher: Matcher<CandidateLine>,
crawl_handle: tokio::task::JoinHandle<()>,
selected_entries: HashSet<Entry>,
selected_entries: FxHashSet<Entry>,
}
impl Channel {
@ -51,7 +52,7 @@ impl Channel {
Channel {
matcher,
crawl_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
@ -76,7 +77,7 @@ impl Channel {
Channel {
matcher,
crawl_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
@ -101,7 +102,7 @@ impl Channel {
Channel {
matcher,
crawl_handle: load_handle,
selected_entries: HashSet::new(),
selected_entries: HashSet::with_hasher(FxBuildHasher),
}
}
}
@ -216,7 +217,7 @@ impl OnAir for Channel {
})
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
&self.selected_entries
}

View File

@ -213,7 +213,7 @@ fn impl_tv_channel(ast: &syn::DeriveInput) -> TokenStream {
}
}
fn selected_entries(&self) -> &HashSet<Entry> {
fn selected_entries(&self) -> &FxHashSet<Entry> {
match self {
#(
#enum_name::#variant_names(ref channel) => {

View File

@ -21,6 +21,7 @@ tracing = { workspace = true }
tokio = { workspace = true }
color-eyre = { workspace = true }
lazy_static = { workspace = true }
rustc-hash = { workspace = true }
parking_lot = "0.12.3"
devicons = "0.6.11"

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, sync::Arc};
use rustc_hash::FxHashMap;
use std::sync::Arc;
use crate::previewers::Preview;
use television_utils::cache::RingSet;
@ -15,7 +16,7 @@ const DEFAULT_PREVIEW_CACHE_SIZE: usize = 100;
/// The cache is implemented as an LRU cache with a fixed size.
#[derive(Debug)]
pub struct PreviewCache {
entries: HashMap<String, Arc<Preview>>,
entries: FxHashMap<String, Arc<Preview>>,
ring_set: RingSet<String>,
}
@ -23,7 +24,7 @@ impl PreviewCache {
/// Create a new preview cache with the given capacity.
pub fn new(capacity: usize) -> Self {
PreviewCache {
entries: HashMap::new(),
entries: FxHashMap::default(),
ring_set: RingSet::with_capacity(capacity),
}
}

View File

@ -4,7 +4,7 @@ use crate::previewers::{Preview, PreviewContent};
use lazy_static::lazy_static;
use parking_lot::Mutex;
use regex::Regex;
use std::collections::HashSet;
use rustc_hash::FxHashSet;
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use television_channels::entry::{Entry, PreviewCommand};
@ -18,7 +18,7 @@ pub struct CommandPreviewer {
config: CommandPreviewerConfig,
concurrent_preview_tasks: Arc<AtomicU8>,
last_previewed: Arc<Mutex<Arc<Preview>>>,
in_flight_previews: Arc<Mutex<HashSet<String>>>,
in_flight_previews: Arc<Mutex<FxHashSet<String>>>,
}
#[allow(dead_code)]
@ -57,7 +57,7 @@ impl CommandPreviewer {
last_previewed: Arc::new(Mutex::new(Arc::new(
Preview::default().stale(),
))),
in_flight_previews: Arc::new(Mutex::new(HashSet::new())),
in_flight_previews: Arc::new(Mutex::new(FxHashSet::default())),
}
}

View File

@ -1,4 +1,4 @@
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::sync::Arc;
use crate::previewers::{Preview, PreviewContent};
@ -6,7 +6,7 @@ use television_channels::entry;
#[derive(Debug, Default)]
pub struct EnvVarPreviewer {
cache: HashMap<entry::Entry, Arc<Preview>>,
cache: FxHashMap<entry::Entry, Arc<Preview>>,
_config: EnvVarPreviewerConfig,
}
@ -16,7 +16,7 @@ pub struct EnvVarPreviewerConfig {}
impl EnvVarPreviewer {
pub fn new(config: Option<EnvVarPreviewerConfig>) -> Self {
EnvVarPreviewer {
cache: HashMap::new(),
cache: FxHashMap::default(),
_config: config.unwrap_or_default(),
}
}

View File

@ -1,5 +1,6 @@
use color_eyre::Result;
use parking_lot::Mutex;
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufRead, BufReader, Seek};
@ -28,7 +29,7 @@ pub struct FilePreviewer {
pub syntax_theme: Arc<Theme>,
concurrent_preview_tasks: Arc<AtomicU8>,
last_previewed: Arc<Mutex<Arc<Preview>>>,
in_flight_previews: Arc<Mutex<HashSet<String>>>,
in_flight_previews: Arc<Mutex<FxHashSet<String>>>,
}
#[derive(Debug, Clone, Default)]
@ -74,7 +75,9 @@ impl FilePreviewer {
last_previewed: Arc::new(Mutex::new(Arc::new(
Preview::default().stale(),
))),
in_flight_previews: Arc::new(Mutex::new(HashSet::new())),
in_flight_previews: Arc::new(Mutex::new(HashSet::with_hasher(
FxBuildHasher,
))),
}
}
@ -137,7 +140,7 @@ pub fn try_preview(
syntax_theme: &Arc<Theme>,
concurrent_tasks: &Arc<AtomicU8>,
last_previewed: &Arc<Mutex<Arc<Preview>>>,
in_flight_previews: &Arc<Mutex<HashSet<String>>>,
in_flight_previews: &Arc<Mutex<FxHashSet<String>>>,
) {
debug!("Computing preview for {:?}", entry.name);
let path = PathBuf::from(&entry.name);

View File

@ -21,6 +21,7 @@ ratatui = { workspace = true }
serde = { workspace = true }
color-eyre = { workspace = true }
syntect = { workspace = true }
rustc-hash = { workspace = true }
[lints]
workspace = true

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, sync::Arc};
use rustc_hash::FxHashMap;
use std::sync::Arc;
use ratatui::widgets::Paragraph;
use television_utils::cache::RingSet;
@ -7,14 +8,14 @@ const DEFAULT_RENDERED_PREVIEW_CACHE_SIZE: usize = 25;
#[derive(Debug)]
pub struct RenderedPreviewCache<'a> {
previews: HashMap<String, Arc<Paragraph<'a>>>,
previews: FxHashMap<String, Arc<Paragraph<'a>>>,
ring_set: RingSet<String>,
}
impl<'a> RenderedPreviewCache<'a> {
pub fn new(capacity: usize) -> Self {
RenderedPreviewCache {
previews: HashMap::new(),
previews: FxHashMap::default(),
ring_set: RingSet::with_capacity(capacity),
}
}

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, fmt::Display};
use rustc_hash::FxHashMap;
use std::fmt::Display;
use crate::{colors::Colorscheme, mode::Mode};
use ratatui::{
@ -10,11 +11,11 @@ use ratatui::{
#[derive(Debug, Clone)]
pub struct DisplayableKeybindings {
bindings: HashMap<DisplayableAction, Vec<String>>,
bindings: FxHashMap<DisplayableAction, Vec<String>>,
}
impl DisplayableKeybindings {
pub fn new(bindings: HashMap<DisplayableAction, Vec<String>>) -> Self {
pub fn new(bindings: FxHashMap<DisplayableAction, Vec<String>>) -> Self {
Self { bindings }
}
}
@ -52,7 +53,7 @@ impl Display for DisplayableAction {
}
pub fn build_keybindings_table<'a>(
keybindings: &'a HashMap<Mode, DisplayableKeybindings>,
keybindings: &'a FxHashMap<Mode, DisplayableKeybindings>,
mode: Mode,
colorscheme: &'a Colorscheme,
) -> Table<'a> {

View File

@ -1,4 +1,4 @@
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use crate::colors::{Colorscheme, GeneralColorscheme};
use crate::logo::build_remote_logo_paragraph;
@ -25,7 +25,7 @@ pub fn draw_remote_control(
use_nerd_font_icons: bool,
picker_state: &mut ListState,
input_state: &mut Input,
icon_color_cache: &mut HashMap<String, Color>,
icon_color_cache: &mut FxHashMap<String, Color>,
mode: &Mode,
colorscheme: &Colorscheme,
) -> Result<()> {
@ -65,7 +65,7 @@ fn draw_rc_channels(
entries: &[Entry],
use_nerd_font_icons: bool,
picker_state: &mut ListState,
icon_color_cache: &mut HashMap<String, Color>,
icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &Colorscheme,
) {
let rc_block = Block::default()

View File

@ -8,7 +8,7 @@ use ratatui::widgets::{
Block, BorderType, Borders, List, ListDirection, ListState, Padding,
};
use ratatui::Frame;
use std::collections::{HashMap, HashSet};
use rustc_hash::{FxHashMap, FxHashSet};
use std::str::FromStr;
use television_channels::entry::Entry;
use television_utils::strings::{
@ -23,10 +23,10 @@ const DESLECTED_SYMBOL: &str = " ";
pub fn build_results_list<'a, 'b>(
results_block: Block<'b>,
entries: &'a [Entry],
selected_entries: Option<&HashSet<Entry>>,
selected_entries: Option<&FxHashSet<Entry>>,
list_direction: ListDirection,
use_icons: bool,
icon_color_cache: &mut HashMap<String, Color>,
icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &ResultsColorscheme,
) -> List<'a>
where
@ -156,11 +156,11 @@ pub fn draw_results_list(
f: &mut Frame,
rect: Rect,
entries: &[Entry],
selected_entries: &HashSet<Entry>,
selected_entries: &FxHashSet<Entry>,
relative_picker_state: &mut ListState,
input_bar_position: InputPosition,
use_nerd_font_icons: bool,
icon_color_cache: &mut HashMap<String, Color>,
icon_color_cache: &mut FxHashMap<String, Color>,
colorscheme: &Colorscheme,
help_keybinding: &str,
preview_keybinding: &str,

View File

@ -19,6 +19,7 @@ color-eyre = { workspace = true }
directories = { workspace = true }
syntect = { workspace = true }
unicode-width = { workspace = true }
rustc-hash = { workspace = true }
ignore = "0.4.23"
bat = { version = "0.24.0", default-features = false, features = [

View File

@ -1,3 +1,4 @@
use rustc_hash::{FxBuildHasher, FxHashSet};
use std::collections::{HashSet, VecDeque};
use tracing::debug;
@ -43,7 +44,7 @@ use tracing::debug;
#[derive(Debug)]
pub struct RingSet<T> {
ring_buffer: VecDeque<T>,
known_keys: HashSet<T>,
known_keys: FxHashSet<T>,
capacity: usize,
}
@ -55,7 +56,10 @@ where
pub fn with_capacity(capacity: usize) -> Self {
RingSet {
ring_buffer: VecDeque::with_capacity(capacity),
known_keys: HashSet::with_capacity(capacity),
known_keys: HashSet::with_capacity_and_hasher(
capacity,
FxBuildHasher,
),
capacity,
}
}

View File

@ -1,8 +1,9 @@
use rustc_hash::FxHashSet;
use std::fmt::Debug;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::{collections::HashSet, path::PathBuf};
use std::path::PathBuf;
use ignore::{overrides::Override, types::TypesBuilder, WalkBuilder};
use lazy_static::lazy_static;
@ -99,7 +100,7 @@ where
}
lazy_static! {
static ref KNOWN_TEXT_FILE_EXTENSIONS: HashSet<&'static str> = [
static ref KNOWN_TEXT_FILE_EXTENSIONS: FxHashSet<&'static str> = [
"ada",
"adb",
"ads",
@ -428,5 +429,7 @@ lazy_static! {
"zsh",
"zshrc",
]
.into();
.iter()
.copied()
.collect();
}

View File

@ -1,4 +1,4 @@
use std::collections::HashSet;
use rustc_hash::FxHashSet;
use std::sync::Arc;
use color_eyre::Result;
@ -45,16 +45,16 @@ pub struct App {
/// The outcome of an action.
#[derive(Debug)]
pub enum ActionOutcome {
Entries(HashSet<Entry>),
Entries(FxHashSet<Entry>),
Input(String),
Passthrough(HashSet<Entry>, String),
Passthrough(FxHashSet<Entry>, String),
None,
}
/// The result of the application.
#[derive(Debug)]
pub struct AppOutput {
pub selected_entries: Option<HashSet<Entry>>,
pub selected_entries: Option<FxHashSet<Entry>>,
pub passthrough: Option<String>,
}

View File

@ -1,4 +1,4 @@
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use color_eyre::Result;
use television_channels::cable::{CableChannelPrototype, CableChannels};
@ -71,7 +71,7 @@ pub fn load_cable_channels() -> Result<CableChannels> {
debug!("Loaded cable channels: {:?}", user_defined_prototypes);
let mut cable_channels = HashMap::new();
let mut cable_channels = FxHashMap::default();
for prototype in user_defined_prototypes {
cable_channels.insert(prototype.name.clone(), prototype);
}

View File

@ -1,4 +1,5 @@
use std::{collections::HashMap, path::Path};
use rustc_hash::FxHashMap;
use std::path::Path;
use clap::{Parser, Subcommand, ValueEnum};
use color_eyre::{eyre::eyre, Result};
@ -231,7 +232,7 @@ pub fn list_channels() {
/// - it should be able to handle commands within delimiters (quotes, brackets, etc.)
pub fn guess_channel_from_prompt(
prompt: &str,
command_mapping: &HashMap<String, String>,
command_mapping: &FxHashMap<String, String>,
) -> Result<ParsedCliChannel> {
debug!("Guessing channel from prompt: {}", prompt);
// git checkout -qf

View File

@ -1,8 +1,8 @@
use crate::action::Action;
use crate::event::{convert_raw_event_to_key, Key};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::fmt::Display;
use std::ops::{Deref, DerefMut};
use television_screen::mode::Mode;
@ -56,10 +56,10 @@ impl<'de> Deserialize<'de> for KeyBindings {
where
D: Deserializer<'de>,
{
let parsed_map =
HashMap::<Mode, HashMap<Action, SerializedBinding>>::deserialize(
deserializer,
)?;
let parsed_map = FxHashMap::<
Mode,
FxHashMap<Action, SerializedBinding>,
>::deserialize(deserializer)?;
let keybindings = parsed_map
.into_iter()

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use config::ValueKind;
use serde::Deserialize;
use std::collections::HashMap;
use television_previewers::previewers;
use television_previewers::previewers::PreviewerConfig;

View File

@ -1,9 +1,11 @@
use serde::Deserialize;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use serde::Deserialize;
#[derive(Clone, Debug, Deserialize, Default)]
pub struct ShellIntegrationConfig {
pub commands: HashMap<String, String>,
pub commands: FxHashMap<String, String>,
}
impl From<ShellIntegrationConfig> for config::ValueKind {

View File

@ -1,16 +1,14 @@
use ratatui::prelude::{Color, Modifier, Style};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Deserializer};
use std::{
collections::HashMap,
ops::{Deref, DerefMut},
};
use std::ops::{Deref, DerefMut};
use television_screen::mode::Mode;
#[derive(Clone, Debug, Default)]
pub struct Styles(pub HashMap<Mode, HashMap<String, Style>>);
pub struct Styles(pub FxHashMap<Mode, FxHashMap<String, Style>>);
impl Deref for Styles {
type Target = HashMap<Mode, HashMap<String, Style>>;
type Target = FxHashMap<Mode, FxHashMap<String, Style>>;
fn deref(&self) -> &Self::Target {
&self.0
}
@ -28,7 +26,7 @@ impl<'de> Deserialize<'de> for Styles {
D: Deserializer<'de>,
{
let parsed_map =
HashMap::<Mode, HashMap<String, String>>::deserialize(
FxHashMap::<Mode, FxHashMap<String, String>>::deserialize(
deserializer,
)?;

View File

@ -1,10 +1,10 @@
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use lazy_static::lazy_static;
lazy_static! {
pub static ref BUILTIN_THEMES: HashMap<&'static str, &'static str> = {
let mut m = HashMap::new();
pub static ref BUILTIN_THEMES: FxHashMap<&'static str, &'static str> = {
let mut m = FxHashMap::default();
m.insert("default", include_str!("../../../../themes/default.toml"));
m.insert(
"television",

View File

@ -1,6 +1,7 @@
use std::collections::HashMap;
use config::ValueKind;
use serde::Deserialize;
use std::collections::HashMap;
use television_screen::layout::{InputPosition, PreviewTitlePosition};

View File

@ -1,4 +1,4 @@
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::ops::Deref;
use color_eyre::Result;
@ -9,10 +9,10 @@ use crate::config::{Binding, KeyBindings};
use crate::event::Key;
#[derive(Default, Debug)]
pub struct Keymap(pub HashMap<Mode, HashMap<Key, Action>>);
pub struct Keymap(pub FxHashMap<Mode, FxHashMap<Key, Action>>);
impl Deref for Keymap {
type Target = HashMap<Mode, HashMap<Key, Action>>;
type Target = FxHashMap<Mode, FxHashMap<Key, Action>>;
fn deref(&self) -> &Self::Target {
&self.0
}
@ -20,9 +20,9 @@ impl Deref for Keymap {
impl From<&KeyBindings> for Keymap {
fn from(keybindings: &KeyBindings) -> Self {
let mut keymap = HashMap::new();
let mut keymap = FxHashMap::default();
for (mode, bindings) in keybindings.iter() {
let mut mode_keymap = HashMap::new();
let mut mode_keymap = FxHashMap::default();
for (action, binding) in bindings {
match binding {
Binding::SingleKey(key) => {

View File

@ -6,7 +6,8 @@ use crate::{cable::load_cable_channels, keymap::Keymap};
use color_eyre::Result;
use copypasta::{ClipboardContext, ClipboardProvider};
use ratatui::{layout::Rect, style::Color, Frame};
use std::collections::{HashMap, HashSet};
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use std::collections::HashSet;
use std::sync::{Arc, Mutex};
use television_channels::channels::{
remote_control::{load_builtin_channels, RemoteControl},
@ -46,7 +47,7 @@ pub struct Television {
pub preview_scroll: Option<u16>,
pub preview_pane_height: u16,
current_preview_total_lines: u16,
pub icon_color_cache: HashMap<String, Color>,
pub icon_color_cache: FxHashMap<String, Color>,
pub rendered_preview_cache: Arc<Mutex<RenderedPreviewCache<'static>>>,
pub(crate) spinner: Spinner,
pub(crate) spinner_state: SpinnerState,
@ -102,7 +103,7 @@ impl Television {
preview_scroll: None,
preview_pane_height: 0,
current_preview_total_lines: 0,
icon_color_cache: HashMap::new(),
icon_color_cache: FxHashMap::default(),
rendered_preview_cache: Arc::new(Mutex::new(
RenderedPreviewCache::default(),
)),
@ -169,12 +170,12 @@ impl Television {
pub fn get_selected_entries(
&mut self,
mode: Option<Mode>,
) -> Option<HashSet<Entry>> {
) -> Option<FxHashSet<Entry>> {
if self.channel.selected_entries().is_empty()
|| matches!(mode, Some(Mode::RemoteControl))
{
return self.get_selected_entry(mode).map(|e| {
let mut set = HashSet::new();
let mut set = HashSet::with_hasher(FxBuildHasher);
set.insert(e);
set
});
@ -615,10 +616,10 @@ impl Television {
}
impl KeyBindings {
pub fn to_displayable(&self) -> HashMap<Mode, DisplayableKeybindings> {
pub fn to_displayable(&self) -> FxHashMap<Mode, DisplayableKeybindings> {
// channel mode keybindings
let channel_bindings: HashMap<DisplayableAction, Vec<String>> =
HashMap::from_iter(vec![
let channel_bindings: FxHashMap<DisplayableAction, Vec<String>> =
FxHashMap::from_iter(vec![
(
DisplayableAction::ResultsNavigation,
serialized_keys_for_actions(
@ -676,58 +677,56 @@ impl KeyBindings {
]);
// remote control mode keybindings
let remote_control_bindings: HashMap<DisplayableAction, Vec<String>> =
HashMap::from_iter(vec![
(
DisplayableAction::ResultsNavigation,
serialized_keys_for_actions(
self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
),
let remote_control_bindings: FxHashMap<
DisplayableAction,
Vec<String>,
> = FxHashMap::from_iter(vec![
(
DisplayableAction::ResultsNavigation,
serialized_keys_for_actions(
self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
),
(
DisplayableAction::SelectEntry,
serialized_keys_for_actions(
self,
&[Action::ConfirmSelection],
),
),
(
DisplayableAction::SelectEntry,
serialized_keys_for_actions(self, &[Action::ConfirmSelection]),
),
(
DisplayableAction::ToggleRemoteControl,
serialized_keys_for_actions(
self,
&[Action::ToggleRemoteControl],
),
(
DisplayableAction::ToggleRemoteControl,
serialized_keys_for_actions(
self,
&[Action::ToggleRemoteControl],
),
),
]);
),
]);
// send to channel mode keybindings
let send_to_channel_bindings: HashMap<DisplayableAction, Vec<String>> =
HashMap::from_iter(vec![
(
DisplayableAction::ResultsNavigation,
serialized_keys_for_actions(
self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
),
let send_to_channel_bindings: FxHashMap<
DisplayableAction,
Vec<String>,
> = FxHashMap::from_iter(vec![
(
DisplayableAction::ResultsNavigation,
serialized_keys_for_actions(
self,
&[Action::SelectPrevEntry, Action::SelectNextEntry],
),
(
DisplayableAction::SelectEntry,
serialized_keys_for_actions(
self,
&[Action::ConfirmSelection],
),
),
(
DisplayableAction::SelectEntry,
serialized_keys_for_actions(self, &[Action::ConfirmSelection]),
),
(
DisplayableAction::Cancel,
serialized_keys_for_actions(
self,
&[Action::ToggleSendToChannel],
),
(
DisplayableAction::Cancel,
serialized_keys_for_actions(
self,
&[Action::ToggleSendToChannel],
),
),
]);
),
]);
HashMap::from_iter(vec![
FxHashMap::from_iter(vec![
(Mode::Channel, DisplayableKeybindings::new(channel_bindings)),
(
Mode::RemoteControl,