perf: use rustc-hash for HashMap and HashSet
Since we already depend on `rustc-hash` transiently, this doesn't add any more dependencies. As long as DOS attacks aren't a concern (which I don't think they are?), this should be free performance. In my (admittedly naive) testing, this really improved CPU usage in some cases, which is pretty nice to get for free.
This commit is contained in:
parent
4be92ae8ca
commit
43a9fca4ec
11 changed files with 68 additions and 68 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1496,6 +1496,7 @@ dependencies = [
|
|||
"recently-used-xbel",
|
||||
"regex",
|
||||
"rust-embed",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"shlex",
|
||||
"slotmap",
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ notify-rust = { version = "4", optional = true }
|
|||
open = "5.3.2"
|
||||
paste = "1.0"
|
||||
regex = "1"
|
||||
rustc-hash = "2.1"
|
||||
serde = { version = "1", features = ["serde_derive"] }
|
||||
shlex = { version = "1.3" }
|
||||
tempfile = "3"
|
||||
|
|
|
|||
48
src/app.rs
48
src/app.rs
|
|
@ -47,10 +47,11 @@ use notify_debouncer_full::{
|
|||
DebouncedEvent, Debouncer, RecommendedCache, new_debouncer,
|
||||
notify::{self, RecommendedWatcher},
|
||||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use slotmap::Key as SlotMapKey;
|
||||
use std::{
|
||||
any::TypeId,
|
||||
collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque},
|
||||
collections::{BTreeMap, BTreeSet, HashMap, VecDeque},
|
||||
env, fmt, fs,
|
||||
future::Future,
|
||||
io,
|
||||
|
|
@ -67,6 +68,7 @@ use trash::TrashItem;
|
|||
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||
|
||||
use crate::{
|
||||
FxOrderMap,
|
||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||
config::{
|
||||
AppTheme, Config, DesktopConfig, Favorite, IconSizes, TIME_CONFIG_ID, TabConfig,
|
||||
|
|
@ -654,16 +656,16 @@ pub struct App {
|
|||
dialog_pages: DialogPages,
|
||||
dialog_text_input: widget::Id,
|
||||
key_binds: HashMap<KeyBind, Action>,
|
||||
margin: HashMap<window::Id, (f32, f32, f32, f32)>,
|
||||
margin: FxHashMap<window::Id, (f32, f32, f32, f32)>,
|
||||
mime_app_cache: MimeAppCache,
|
||||
modifiers: Modifiers,
|
||||
mounter_items: HashMap<MounterKey, MounterItems>,
|
||||
mounter_items: FxHashMap<MounterKey, MounterItems>,
|
||||
must_save_sort_names: bool,
|
||||
network_drive_connecting: Option<(MounterKey, String)>,
|
||||
network_drive_input: String,
|
||||
#[cfg(feature = "notify")]
|
||||
notification_opt: Option<Arc<Mutex<notify_rust::NotificationHandle>>>,
|
||||
overlap: HashMap<String, (window::Id, Rectangle)>,
|
||||
overlap: FxHashMap<String, (window::Id, Rectangle)>,
|
||||
pending_operation_id: u64,
|
||||
pending_operations: BTreeMap<u64, (Operation, Controller)>,
|
||||
progress_operations: BTreeSet<u64>,
|
||||
|
|
@ -673,17 +675,17 @@ pub struct App {
|
|||
search_id: widget::Id,
|
||||
size: Option<Size>,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
layer_sizes: HashMap<window::Id, Size>,
|
||||
layer_sizes: FxHashMap<window::Id, Size>,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
surface_ids: HashMap<WlOutput, WindowId>,
|
||||
surface_ids: FxHashMap<WlOutput, WindowId>,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
surface_names: HashMap<WindowId, String>,
|
||||
surface_names: FxHashMap<WindowId, String>,
|
||||
toasts: widget::toaster::Toasts<Message>,
|
||||
watcher_opt: Option<(
|
||||
Debouncer<RecommendedWatcher, RecommendedCache>,
|
||||
HashSet<PathBuf>,
|
||||
FxHashSet<PathBuf>,
|
||||
)>,
|
||||
windows: HashMap<window::Id, WindowKind>,
|
||||
windows: FxHashMap<window::Id, WindowKind>,
|
||||
nav_dnd_hover: Option<(Location, Instant)>,
|
||||
tab_dnd_hover: Option<(Entity, Instant)>,
|
||||
nav_drag_id: DragId,
|
||||
|
|
@ -699,7 +701,7 @@ impl App {
|
|||
// Associate all paths to its MIME type
|
||||
// This allows handling paths as groups if possible, such as launching a single video
|
||||
// player that is passed every path.
|
||||
let mut groups: HashMap<Mime, Vec<PathBuf>> = HashMap::new();
|
||||
let mut groups: FxHashMap<Mime, Vec<PathBuf>> = FxHashMap::default();
|
||||
let mut all_archives = true;
|
||||
let supported_archive_types = crate::archive::SUPPORTED_ARCHIVE_TYPES
|
||||
.iter()
|
||||
|
|
@ -915,7 +917,7 @@ impl App {
|
|||
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
fn handle_overlap(&mut self) {
|
||||
let mut overlaps: HashMap<_, _> = self
|
||||
let mut overlaps: FxHashMap<_, _> = self
|
||||
.windows
|
||||
.keys()
|
||||
.map(|k| (*k, (0., 0., 0., 0.)))
|
||||
|
|
@ -1573,7 +1575,7 @@ impl App {
|
|||
|
||||
fn update_watcher(&mut self) -> Task<Message> {
|
||||
if let Some((mut watcher, old_paths)) = self.watcher_opt.take() {
|
||||
let mut new_paths = HashSet::new();
|
||||
let mut new_paths = FxHashSet::default();
|
||||
for entity in self.tab_model.iter() {
|
||||
if let Some(tab) = self.tab_model.data::<Tab>(entity) {
|
||||
if let Some(path) = tab.location.path_opt() {
|
||||
|
|
@ -1942,7 +1944,7 @@ impl App {
|
|||
fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&MimeApp, MimeAppMatch)> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
let mut dedupe = HashSet::new();
|
||||
let mut dedupe = FxHashSet::default();
|
||||
|
||||
// start with exact matches
|
||||
for mime_app in self.mime_app_cache.get(mime_type) {
|
||||
|
|
@ -2124,16 +2126,16 @@ impl Application for App {
|
|||
dialog_pages: DialogPages::new(),
|
||||
dialog_text_input: widget::Id::unique(),
|
||||
key_binds,
|
||||
margin: HashMap::new(),
|
||||
margin: FxHashMap::default(),
|
||||
mime_app_cache: MimeAppCache::new(),
|
||||
modifiers: Modifiers::empty(),
|
||||
mounter_items: HashMap::new(),
|
||||
mounter_items: FxHashMap::default(),
|
||||
must_save_sort_names: false,
|
||||
network_drive_connecting: None,
|
||||
network_drive_input: String::new(),
|
||||
#[cfg(feature = "notify")]
|
||||
notification_opt: None,
|
||||
overlap: HashMap::new(),
|
||||
overlap: FxHashMap::default(),
|
||||
pending_operation_id: 0,
|
||||
pending_operations: BTreeMap::new(),
|
||||
progress_operations: BTreeSet::new(),
|
||||
|
|
@ -2143,12 +2145,12 @@ impl Application for App {
|
|||
search_id: widget::Id::unique(),
|
||||
size: None,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
surface_ids: HashMap::new(),
|
||||
surface_ids: FxHashMap::default(),
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
surface_names: HashMap::new(),
|
||||
surface_names: FxHashMap::default(),
|
||||
toasts: widget::toaster::Toasts::new(Message::CloseToast),
|
||||
watcher_opt: None,
|
||||
windows: HashMap::new(),
|
||||
windows: FxHashMap::default(),
|
||||
nav_dnd_hover: None,
|
||||
tab_dnd_hover: None,
|
||||
nav_drag_id: DragId::new(),
|
||||
|
|
@ -2156,7 +2158,7 @@ impl Application for App {
|
|||
auto_scroll_speed: None,
|
||||
file_dialog_opt: None,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
layer_sizes: HashMap::new(),
|
||||
layer_sizes: FxHashMap::default(),
|
||||
};
|
||||
|
||||
let mut commands = vec![app.update_config()];
|
||||
|
|
@ -3211,7 +3213,7 @@ impl Application for App {
|
|||
Message::NotifyWatcher(mut watcher_wrapper) => match watcher_wrapper.watcher_opt.take()
|
||||
{
|
||||
Some(watcher) => {
|
||||
self.watcher_opt = Some((watcher, HashSet::new()));
|
||||
self.watcher_opt = Some((watcher, FxHashSet::default()));
|
||||
return self.update_watcher();
|
||||
}
|
||||
None => {
|
||||
|
|
@ -4678,8 +4680,8 @@ impl Application for App {
|
|||
Message::SaveSortNames => {
|
||||
self.must_save_sort_names = false;
|
||||
if let Some(state_handler) = self.state_handler.as_ref() {
|
||||
if let Err(err) =
|
||||
state_handler.set::<ordermap::OrderMap<String, (HeadingOptions, bool)>>(
|
||||
if let Err(err) = state_handler
|
||||
.set::<FxOrderMap<String, (HeadingOptions, bool)>>(
|
||||
"sort_names",
|
||||
self.state.sort_names.clone(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ use cosmic::{
|
|||
iced::Subscription,
|
||||
theme,
|
||||
};
|
||||
use ordermap::OrderMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
FxOrderMap,
|
||||
app::App,
|
||||
tab::{HeadingOptions, Location, View},
|
||||
};
|
||||
|
|
@ -115,13 +115,13 @@ pub enum TypeToSearch {
|
|||
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct State {
|
||||
pub sort_names: ordermap::OrderMap<String, (HeadingOptions, bool)>,
|
||||
pub sort_names: FxOrderMap<String, (HeadingOptions, bool)>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sort_names: OrderMap::from_iter(dirs::download_dir().into_iter().map(|dir| {
|
||||
sort_names: FxOrderMap::from_iter(dirs::download_dir().into_iter().map(|dir| {
|
||||
(
|
||||
Location::Path(dir).normalize().to_string(),
|
||||
(HeadingOptions::Modified, false),
|
||||
|
|
|
|||
|
|
@ -25,9 +25,10 @@ use notify_debouncer_full::{
|
|||
notify::{self, RecommendedWatcher},
|
||||
};
|
||||
use recently_used_xbel::update_recently_used;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
collections::{HashMap, HashSet, VecDeque},
|
||||
collections::{HashMap, VecDeque},
|
||||
env, fmt, fs,
|
||||
num::NonZeroU16,
|
||||
path::PathBuf,
|
||||
|
|
@ -509,7 +510,7 @@ struct App {
|
|||
filter_selected: Option<usize>,
|
||||
filename_id: widget::Id,
|
||||
modifiers: Modifiers,
|
||||
mounter_items: HashMap<MounterKey, MounterItems>,
|
||||
mounter_items: FxHashMap<MounterKey, MounterItems>,
|
||||
nav_model: segmented_button::SingleSelectModel,
|
||||
result_opt: Option<DialogResult>,
|
||||
search_id: widget::Id,
|
||||
|
|
@ -517,7 +518,7 @@ struct App {
|
|||
key_binds: HashMap<KeyBind, Action>,
|
||||
watcher_opt: Option<(
|
||||
Debouncer<RecommendedWatcher, RecommendedCache>,
|
||||
HashSet<PathBuf>,
|
||||
FxHashSet<PathBuf>,
|
||||
)>,
|
||||
auto_scroll_speed: Option<i16>,
|
||||
}
|
||||
|
|
@ -871,7 +872,7 @@ impl App {
|
|||
|
||||
fn update_watcher(&mut self) -> Task<Message> {
|
||||
if let Some((mut watcher, old_paths)) = self.watcher_opt.take() {
|
||||
let mut new_paths = HashSet::new();
|
||||
let mut new_paths = FxHashSet::default();
|
||||
if let Some(path) = &self.tab.location.path_opt() {
|
||||
new_paths.insert(path.to_path_buf());
|
||||
}
|
||||
|
|
@ -981,7 +982,7 @@ impl Application for App {
|
|||
filter_selected: None,
|
||||
filename_id: widget::Id::unique(),
|
||||
modifiers: Modifiers::empty(),
|
||||
mounter_items: HashMap::new(),
|
||||
mounter_items: FxHashMap::default(),
|
||||
nav_model: segmented_button::ModelBuilder::default().build(),
|
||||
result_opt: None,
|
||||
search_id: widget::Id::unique(),
|
||||
|
|
@ -1519,7 +1520,7 @@ impl Application for App {
|
|||
Message::NotifyWatcher(mut watcher_wrapper) => match watcher_wrapper.watcher_opt.take()
|
||||
{
|
||||
Some(watcher) => {
|
||||
self.watcher_opt = Some((watcher, HashSet::new()));
|
||||
self.watcher_opt = Some((watcher, FxHashSet::default()));
|
||||
return self.update_watcher();
|
||||
}
|
||||
None => {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ pub mod tab;
|
|||
mod thumbnail_cacher;
|
||||
mod thumbnailer;
|
||||
|
||||
pub(crate) type FxOrderMap<K, V> = ordermap::OrderMap<K, V, rustc_hash::FxBuildHasher>;
|
||||
|
||||
pub(crate) fn err_str<T: ToString>(err: T) -> String {
|
||||
err.to_string()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
use cosmic::desktop;
|
||||
use cosmic::widget;
|
||||
pub use mime_guess::Mime;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashMap,
|
||||
env,
|
||||
ffi::OsStr,
|
||||
fs, io,
|
||||
|
|
@ -221,8 +221,8 @@ fn filename_eq(path_opt: &Option<PathBuf>, filename: &str) -> bool {
|
|||
|
||||
pub struct MimeAppCache {
|
||||
apps: Vec<MimeApp>,
|
||||
cache: HashMap<Mime, Vec<MimeApp>>,
|
||||
icons: HashMap<Mime, Vec<widget::icon::Handle>>,
|
||||
cache: FxHashMap<Mime, Vec<MimeApp>>,
|
||||
icons: FxHashMap<Mime, Vec<widget::icon::Handle>>,
|
||||
terminals: Vec<MimeApp>,
|
||||
}
|
||||
|
||||
|
|
@ -230,8 +230,8 @@ impl MimeAppCache {
|
|||
pub fn new() -> Self {
|
||||
let mut mime_app_cache = Self {
|
||||
apps: Vec::new(),
|
||||
cache: HashMap::new(),
|
||||
icons: HashMap::new(),
|
||||
cache: FxHashMap::default(),
|
||||
icons: FxHashMap::default(),
|
||||
terminals: Vec::new(),
|
||||
};
|
||||
mime_app_cache.reload();
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use cosmic::widget::icon;
|
||||
use mime_guess::Mime;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
path::Path,
|
||||
sync::{LazyLock, Mutex},
|
||||
|
|
@ -18,14 +18,14 @@ struct MimeIconKey {
|
|||
}
|
||||
|
||||
struct MimeIconCache {
|
||||
cache: HashMap<MimeIconKey, Option<icon::Handle>>,
|
||||
cache: FxHashMap<MimeIconKey, Option<icon::Handle>>,
|
||||
shared_mime_info: xdg_mime::SharedMimeInfo,
|
||||
}
|
||||
|
||||
impl MimeIconCache {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
cache: HashMap::new(),
|
||||
cache: FxHashMap::default(),
|
||||
shared_mime_info: xdg_mime::SharedMimeInfo::new(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
src/tab.rs
39
src/tab.rs
|
|
@ -49,7 +49,7 @@ use icu::{
|
|||
use image::ImageDecoder;
|
||||
use jxl_oxide::integration::JxlDecoder;
|
||||
use mime_guess::{Mime, mime};
|
||||
use ordermap::OrderMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
|
|
@ -73,6 +73,7 @@ use trash::TrashItemSize;
|
|||
use walkdir::WalkDir;
|
||||
|
||||
use crate::{
|
||||
FxOrderMap,
|
||||
app::{Action, PreviewItem, PreviewKind},
|
||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||
config::{DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, ThumbCfg},
|
||||
|
|
@ -100,9 +101,9 @@ const THUMBNAIL_SIZE: u32 = (ICON_SIZE_GRID as u32) * (ICON_SCALE_MAX as u32);
|
|||
pub static THUMB_SEMAPHORE: LazyLock<tokio::sync::Semaphore> =
|
||||
LazyLock::new(|| tokio::sync::Semaphore::const_new(num_cpus::get()));
|
||||
|
||||
pub(crate) static SORT_OPTION_FALLBACK: LazyLock<HashMap<String, (HeadingOptions, bool)>> =
|
||||
pub(crate) static SORT_OPTION_FALLBACK: LazyLock<FxHashMap<String, (HeadingOptions, bool)>> =
|
||||
LazyLock::new(|| {
|
||||
HashMap::from_iter(dirs::download_dir().into_iter().map(|dir| {
|
||||
FxHashMap::from_iter(dirs::download_dir().into_iter().map(|dir| {
|
||||
(
|
||||
Location::Path(dir).normalize().to_string(),
|
||||
(HeadingOptions::Modified, false),
|
||||
|
|
@ -131,8 +132,8 @@ static MODE_NAMES: LazyLock<Vec<String>> = LazyLock::new(|| {
|
|||
]
|
||||
});
|
||||
|
||||
static SPECIAL_DIRS: LazyLock<HashMap<PathBuf, &'static str>> = LazyLock::new(|| {
|
||||
let mut special_dirs = HashMap::new();
|
||||
static SPECIAL_DIRS: LazyLock<FxHashMap<PathBuf, &'static str>> = LazyLock::new(|| {
|
||||
let mut special_dirs = FxHashMap::default();
|
||||
if let Some(dir) = dirs::document_dir() {
|
||||
special_dirs.insert(dir, "folder-documents");
|
||||
}
|
||||
|
|
@ -534,25 +535,17 @@ pub enum FsKind {
|
|||
pub fn fs_kind(metadata: &Metadata) -> FsKind {
|
||||
//TODO: method to reload remote filesystems dynamically
|
||||
//TODO: fix for https://github.com/eminence/procfs/issues/262
|
||||
static DEVICES: LazyLock<HashMap<u64, FsKind>> = LazyLock::new(|| {
|
||||
let mut devices = HashMap::new();
|
||||
static DEVICES: LazyLock<FxHashMap<u64, FsKind>> = LazyLock::new(|| {
|
||||
let mut devices = FxHashMap::default();
|
||||
match procfs::process::Process::myself() {
|
||||
Ok(process) => match process.mountinfo() {
|
||||
Ok(mount_infos) => {
|
||||
for mount_info in mount_infos.iter() {
|
||||
devices = FxHashMap::from_iter(mount_infos.iter().filter_map(|mount_info| {
|
||||
let mut parts = mount_info.majmin.split(':');
|
||||
let Some(major_str) = parts.next() else {
|
||||
continue;
|
||||
};
|
||||
let Some(minor_str) = parts.next() else {
|
||||
continue;
|
||||
};
|
||||
let Ok(major) = major_str.parse::<libc::c_uint>() else {
|
||||
continue;
|
||||
};
|
||||
let Ok(minor) = minor_str.parse::<libc::c_uint>() else {
|
||||
continue;
|
||||
};
|
||||
let major_str = parts.next()?;
|
||||
let minor_str = parts.next()?;
|
||||
let major = major_str.parse::<libc::c_uint>().ok()?;
|
||||
let minor = minor_str.parse::<libc::c_uint>().ok()?;
|
||||
let dev = libc::makedev(major, minor);
|
||||
//TODO: make sure this list is exhaustive
|
||||
let kind = match mount_info.fs_type.as_str() {
|
||||
|
|
@ -561,8 +554,8 @@ pub fn fs_kind(metadata: &Metadata) -> FsKind {
|
|||
"fuse.gvfsd-fuse" => FsKind::Gvfs,
|
||||
_ => FsKind::Local,
|
||||
};
|
||||
devices.insert(dev, kind);
|
||||
}
|
||||
Some((dev, kind))
|
||||
}));
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("failed to get mount info: {err}");
|
||||
|
|
@ -2525,7 +2518,7 @@ impl Tab {
|
|||
location: Location,
|
||||
config: TabConfig,
|
||||
thumb_config: ThumbCfg,
|
||||
sorting_options: Option<&OrderMap<String, (HeadingOptions, bool)>>,
|
||||
sorting_options: Option<&FxOrderMap<String, (HeadingOptions, bool)>>,
|
||||
scrollable_id: widget::Id,
|
||||
window_id: Option<window::Id>,
|
||||
) -> Self {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use image::DynamicImage;
|
||||
use md5::{Digest, Md5};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
error::Error,
|
||||
fs::{self, File},
|
||||
io::{self, BufReader, BufWriter},
|
||||
|
|
@ -143,7 +143,7 @@ impl ThumbnailCacher {
|
|||
let mut reader = decoder.read_info()?;
|
||||
let (width, height, color_type, bit_depth, mut text_chunks) = {
|
||||
let info = reader.info();
|
||||
let text_chunks: HashMap<String, String> = info
|
||||
let text_chunks: FxHashMap<String, String> = info
|
||||
.uncompressed_latin1_text
|
||||
.clone()
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use mime_guess::Mime;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
path::Path,
|
||||
process,
|
||||
|
|
@ -56,13 +56,13 @@ impl Thumbnailer {
|
|||
}
|
||||
|
||||
pub struct ThumbnailerCache {
|
||||
cache: HashMap<Mime, Vec<Thumbnailer>>,
|
||||
cache: FxHashMap<Mime, Vec<Thumbnailer>>,
|
||||
}
|
||||
|
||||
impl ThumbnailerCache {
|
||||
pub fn new() -> Self {
|
||||
let mut thumbnailer_cache = Self {
|
||||
cache: HashMap::new(),
|
||||
cache: FxHashMap::default(),
|
||||
};
|
||||
thumbnailer_cache.reload();
|
||||
thumbnailer_cache
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue