Use an hashmap instead of symlinks for cache

This commit is contained in:
nik012003
2023-03-12 01:31:57 +01:00
parent 4f599d5af6
commit 28f73101a2
3 changed files with 447 additions and 244 deletions

598
Cargo.lock generated

File diff suppressed because it is too large Load Diff

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.38.1" stardust-xr-fusion = "0.38.1"
stardust-xr-molecules = "0.22.0" stardust-xr-molecules = "0.22.0"
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(), 128) { 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") {