From 3fbeebd594183b37d4667acd093b33b3df541846 Mon Sep 17 00:00:00 2001 From: Nova Date: Thu, 11 May 2023 00:18:38 -0400 Subject: [PATCH] Use an hashmap instead of symlinks for cache --- Cargo.lock | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 3 ++ src/xdg.rs | 90 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 179 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f03af8c..a6758b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.0" @@ -276,7 +282,8 @@ dependencies = [ "js-sys", "num-integer", "num-traits", - "time", + "serde", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -944,6 +951,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "iana-time-zone" version = "0.1.56" @@ -1013,6 +1026,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -1047,6 +1061,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + [[package]] name = "jpeg-decoder" version = "0.3.0" @@ -1637,6 +1657,9 @@ dependencies = [ "regex", "resvg", "rustc-hash", + "serde", + "serde_json", + "serde_with", "stardust-xr-fusion", "stardust-xr-molecules", "tempdir", @@ -1932,6 +1955,12 @@ dependencies = [ "unicode-script", ] +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + [[package]] name = "same-file" version = "1.0.6" @@ -1979,6 +2008,17 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "serde_json" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.12" @@ -1990,6 +2030,34 @@ dependencies = [ "syn 2.0.15", ] +[[package]] +name = "serde_with" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85456ffac572dc8826334164f2fb6fb40a7c766aebe195a2a21ee69ee2885ecf" +dependencies = [ + "base64 0.13.1", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.20", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cbcd6104f8a4ab6af7f6be2a0da6be86b9de3c401f6e86bb856ab2af739232f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -2270,6 +2338,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +dependencies = [ + "time-core", +] + [[package]] name = "tiny-skia" version = "0.8.4" @@ -2492,7 +2587,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b6bb4e62619d9f68aa2d8a823fea2bff302340a1f2d45c264d5b0be170832e" dependencies = [ - "base64", + "base64 0.21.0", "data-url", "flate2", "imagesize", diff --git a/Cargo.toml b/Cargo.toml index dfe4147..1b44b81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,9 @@ nix = "0.26.1" regex = "1.7.1" resvg = "0.29.0" rustc-hash = "1.1.0" +serde = "1.0.155" +serde_json = "1.0.94" +serde_with = "2.3.1" stardust-xr-fusion = "0.40.2" stardust-xr-molecules = "0.24.3" tokio = { version = "1.24.1", features = ["full"] } diff --git a/src/xdg.rs b/src/xdg.rs index e024843..df6c11a 100644 --- a/src/xdg.rs +++ b/src/xdg.rs @@ -1,18 +1,68 @@ -use cached::proc_macro::cached; use color_eyre::eyre::Result; +use lazy_static::lazy_static; use linicon; use regex::Regex; use resvg::render; use resvg::tiny_skia::{Pixmap, Transform}; use resvg::usvg::{FitTo, Tree}; +use serde::{Deserialize, Serialize}; +use serde_json; +use serde_with::serde_as; +use std::collections::HashMap; use std::ffi::OsString; use std::fs::create_dir_all; +use std::fs::File; use std::io::{BufRead, BufReader, ErrorKind}; -use std::os::unix::fs::symlink; +use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::str::FromStr; +use std::sync::Mutex; use std::{env, fs}; use walkdir::WalkDir; + +#[serde_as] +#[derive(Deserialize, Serialize)] +struct ImageCache { + path: PathBuf, + #[serde_as(as = "Vec<(_, _)>")] + pub map: HashMap, +} + +impl ImageCache { + fn new(path: PathBuf) -> Self { + if let Ok(mut file) = File::open(&path) { + let mut buf = vec![]; + if file.read_to_end(&mut buf).is_ok() { + if let Ok(cache) = serde_json::from_slice(&buf[..]) { + return cache; + } + } + } + + //There was no file, or the file failed to load, create a new World. + ImageCache { + path, + map: HashMap::new(), + } + } + + fn insert(&mut self, k: String, v: PathBuf) { + self.map.insert(k, v); + } + + fn save(&self) { + let mut f = File::create(&self.path).unwrap(); + let buf = serde_json::to_vec(&self).unwrap(); + f.write_all(&buf[..]).unwrap(); + } +} + +lazy_static! { + static ref IMAGE_CACHE: Mutex = Mutex::new(ImageCache::new( + get_image_cache_dir().join("imagechache.map") + )); +} + fn get_data_dirs() -> Vec { let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default(); @@ -193,10 +243,11 @@ impl DesktopFile { } } - let cache_icon_path = get_image_cache_dir().join(icon_name).canonicalize(); - if cache_icon_path.is_ok() { - if let Some(icon) = Icon::from_path(cache_icon_path.unwrap(), preferred_px_size) { - return vec![icon]; + if let Some(cache_icon_path) = IMAGE_CACHE.lock().unwrap().map.get(icon_name) { + if cache_icon_path.exists() { + if let Some(icon) = Icon::from_path(cache_icon_path.to_owned(), 128) { + return vec![icon]; + } } } @@ -247,10 +298,28 @@ impl Icon { } pub fn cached_process(self, size: u16) -> Result { - let new_path = - get_image_cache_dir().join(self.path.with_extension("").file_name().unwrap()); - if !new_path.exists() { - _ = symlink(self.path.clone(), new_path); + if !IMAGE_CACHE.lock().unwrap().map.contains_key( + &self + .path + .with_extension("") + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_owned(), + ) { + dbg!("Saving value in the DB"); + IMAGE_CACHE.lock().unwrap().insert( + self.path + .with_extension("") + .file_name() + .unwrap() + .to_str() + .unwrap() + .to_owned(), + self.path.clone(), + ); + IMAGE_CACHE.lock().unwrap().save(); } match self.icon_type { IconType::Svg => Ok(Icon::from_path(get_png_from_svg(self.path, size)?, size).unwrap()), @@ -285,7 +354,6 @@ fn test_get_icon_path() { )); } -#[cached] pub fn get_image_cache_dir() -> PathBuf { let cache_dir; if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") {