127 lines
3.4 KiB
Rust
127 lines
3.4 KiB
Rust
use std::{collections::HashMap, fs::{self, File}, io::Read, path::PathBuf, str::FromStr, sync::{Arc, RwLock}};
|
||
|
||
use log::info;
|
||
use serde::{Deserialize, Serialize};
|
||
|
||
use crate::utils::{file_size_in_kb, get_last_modified_time, k_deserialize};
|
||
|
||
use super::hdlparam::FastHdlparam;
|
||
|
||
pub enum CacheResult<T> {
|
||
Ok(T),
|
||
NotNeedCache,
|
||
CacheNotFound,
|
||
NotHit,
|
||
FailDeserialize,
|
||
Error(String)
|
||
}
|
||
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct CacheItem {
|
||
/// 文件名字
|
||
pub file_name: String,
|
||
/// 文件大小,单位 KB
|
||
pub size: u64,
|
||
/// 版本,根据特定算法得出
|
||
pub version: String,
|
||
/// 缓存文件的名字
|
||
pub cache_name: String
|
||
}
|
||
|
||
|
||
/// 用于进行高效 IR 缓存的模块
|
||
pub struct CacheManager {
|
||
/// 缓存文件夹根目录
|
||
pub root_dir: PathBuf,
|
||
/// meta 文件内容
|
||
pub meta_name: String,
|
||
/// meta 内容
|
||
pub meta: Arc<RwLock<HashMap<String, CacheItem>>>
|
||
}
|
||
|
||
|
||
|
||
impl CacheManager {
|
||
pub fn new(root_dir: &str) -> Self {
|
||
// 读入 meta 文件
|
||
let root_dir = PathBuf::from_str(root_dir).unwrap();
|
||
let meta_name = "index.cache";
|
||
let meta_path = root_dir.join(meta_name);
|
||
let meta = get_or_init_meta(&meta_path);
|
||
|
||
// 如果不存在 root dir,则创建
|
||
if !root_dir.exists() {
|
||
match fs::create_dir_all(&root_dir) {
|
||
Ok(_) => {},
|
||
Err(err) => info!("error happen when create {root_dir:?}: {err:?}")
|
||
}
|
||
}
|
||
|
||
CacheManager {
|
||
root_dir,
|
||
meta_name: meta_name.to_string(),
|
||
meta: Arc::new(RwLock::new(meta))
|
||
}
|
||
}
|
||
|
||
pub fn is_big_file(&self, path: &PathBuf) -> bool {
|
||
if let Ok(size) = file_size_in_kb(path.to_str().unwrap()) {
|
||
return size >= 1024;
|
||
}
|
||
|
||
false
|
||
}
|
||
|
||
fn get_version(&self, path: &PathBuf) -> String {
|
||
let path_str = path.to_str().unwrap();
|
||
if let Ok(modify_ts) = get_last_modified_time(path_str) {
|
||
return modify_ts.to_string();
|
||
}
|
||
"".to_string()
|
||
}
|
||
|
||
/// ## 说明
|
||
/// 尝试获取当前的路径文件的 fast 的缓存
|
||
///
|
||
/// ## None
|
||
///
|
||
/// * 如果本来就没有缓存
|
||
/// * 缓冲的 version 对不上
|
||
pub fn try_get_fast_cache(&self, path: &PathBuf) -> CacheResult<FastHdlparam> {
|
||
if !self.is_big_file(path) {
|
||
return CacheResult::NotNeedCache
|
||
}
|
||
let path_string = path.to_str().unwrap();
|
||
let meta_handle = self.meta.read().unwrap();
|
||
if let Some(cache_item) = meta_handle.get(path_string) {
|
||
let current_version = self.get_version(path);
|
||
let cache_path = self.root_dir.join(&cache_item.cache_name);
|
||
if current_version == cache_item.version && cache_path.exists() {
|
||
// hit cache
|
||
if let Ok(fast) = k_deserialize::<FastHdlparam>(&cache_path) {
|
||
return CacheResult::Ok(fast);
|
||
}
|
||
}
|
||
}
|
||
CacheResult::CacheNotFound
|
||
}
|
||
|
||
pub fn update_cache() {
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
fn get_or_init_meta(meta_path: &PathBuf) -> HashMap<String, CacheItem> {
|
||
if meta_path.exists() {
|
||
// 读取文件
|
||
if let Ok(meta_map) = k_deserialize::<HashMap<String, CacheItem>>(meta_path) {
|
||
return meta_map;
|
||
}
|
||
}
|
||
|
||
// 重新创建新的
|
||
HashMap::<String, CacheItem>::new()
|
||
} |