Use an hashmap instead of symlinks for cache

This commit is contained in:
Nova
2023-05-11 00:18:38 -04:00
parent d41e34d746
commit 3fbeebd594
3 changed files with 179 additions and 13 deletions

99
Cargo.lock generated
View File

@@ -174,6 +174,12 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.21.0" version = "0.21.0"
@@ -276,7 +282,8 @@ dependencies = [
"js-sys", "js-sys",
"num-integer", "num-integer",
"num-traits", "num-traits",
"time", "serde",
"time 0.1.45",
"wasm-bindgen", "wasm-bindgen",
"winapi", "winapi",
] ]
@@ -944,6 +951,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.56" version = "0.1.56"
@@ -1013,6 +1026,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown 0.12.3", "hashbrown 0.12.3",
"serde",
] ]
[[package]] [[package]]
@@ -1047,6 +1061,12 @@ dependencies = [
"windows-sys 0.48.0", "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]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
version = "0.3.0" version = "0.3.0"
@@ -1637,6 +1657,9 @@ dependencies = [
"regex", "regex",
"resvg", "resvg",
"rustc-hash", "rustc-hash",
"serde",
"serde_json",
"serde_with",
"stardust-xr-fusion", "stardust-xr-fusion",
"stardust-xr-molecules", "stardust-xr-molecules",
"tempdir", "tempdir",
@@ -1932,6 +1955,12 @@ dependencies = [
"unicode-script", "unicode-script",
] ]
[[package]]
name = "ryu"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@@ -1979,6 +2008,17 @@ dependencies = [
"syn 2.0.15", "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]] [[package]]
name = "serde_repr" name = "serde_repr"
version = "0.1.12" version = "0.1.12"
@@ -1990,6 +2030,34 @@ dependencies = [
"syn 2.0.15", "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]] [[package]]
name = "sharded-slab" name = "sharded-slab"
version = "0.1.4" version = "0.1.4"
@@ -2270,6 +2338,33 @@ dependencies = [
"winapi", "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]] [[package]]
name = "tiny-skia" name = "tiny-skia"
version = "0.8.4" version = "0.8.4"
@@ -2492,7 +2587,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63b6bb4e62619d9f68aa2d8a823fea2bff302340a1f2d45c264d5b0be170832e" checksum = "63b6bb4e62619d9f68aa2d8a823fea2bff302340a1f2d45c264d5b0be170832e"
dependencies = [ dependencies = [
"base64", "base64 0.21.0",
"data-url", "data-url",
"flate2", "flate2",
"imagesize", "imagesize",

View File

@@ -20,6 +20,9 @@ nix = "0.26.1"
regex = "1.7.1" regex = "1.7.1"
resvg = "0.29.0" resvg = "0.29.0"
rustc-hash = "1.1.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-fusion = "0.40.2"
stardust-xr-molecules = "0.24.3" stardust-xr-molecules = "0.24.3"
tokio = { version = "1.24.1", features = ["full"] } tokio = { version = "1.24.1", features = ["full"] }

View File

@@ -1,18 +1,68 @@
use cached::proc_macro::cached;
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use lazy_static::lazy_static;
use linicon; use linicon;
use regex::Regex; use regex::Regex;
use resvg::render; use resvg::render;
use resvg::tiny_skia::{Pixmap, Transform}; use resvg::tiny_skia::{Pixmap, Transform};
use resvg::usvg::{FitTo, Tree}; 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::ffi::OsString;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::fs::File;
use std::io::{BufRead, BufReader, ErrorKind}; use std::io::{BufRead, BufReader, ErrorKind};
use std::os::unix::fs::symlink; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::sync::Mutex;
use std::{env, fs}; use std::{env, fs};
use walkdir::WalkDir; use walkdir::WalkDir;
#[serde_as]
#[derive(Deserialize, Serialize)]
struct ImageCache {
path: PathBuf,
#[serde_as(as = "Vec<(_, _)>")]
pub map: HashMap<String, PathBuf>,
}
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<ImageCache> = Mutex::new(ImageCache::new(
get_image_cache_dir().join("imagechache.map")
));
}
fn get_data_dirs() -> Vec<PathBuf> { fn get_data_dirs() -> Vec<PathBuf> {
let xdg_data_dirs_str = std::env::var("XDG_DATA_DIRS").unwrap_or_default(); 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 let Some(cache_icon_path) = IMAGE_CACHE.lock().unwrap().map.get(icon_name) {
if cache_icon_path.is_ok() { if cache_icon_path.exists() {
if let Some(icon) = Icon::from_path(cache_icon_path.unwrap(), preferred_px_size) { if let Some(icon) = Icon::from_path(cache_icon_path.to_owned(), 128) {
return vec![icon]; return vec![icon];
}
} }
} }
@@ -247,10 +298,28 @@ impl Icon {
} }
pub fn cached_process(self, size: u16) -> Result<Icon, std::io::Error> { pub fn cached_process(self, size: u16) -> Result<Icon, std::io::Error> {
let new_path = if !IMAGE_CACHE.lock().unwrap().map.contains_key(
get_image_cache_dir().join(self.path.with_extension("").file_name().unwrap()); &self
if !new_path.exists() { .path
_ = symlink(self.path.clone(), new_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 { match self.icon_type {
IconType::Svg => Ok(Icon::from_path(get_png_from_svg(self.path, size)?, size).unwrap()), 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 { pub fn get_image_cache_dir() -> PathBuf {
let cache_dir; let cache_dir;
if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") { if let Ok(xdg_cache_home) = std::env::var("XDG_CACHE_HOME") {