完成缓存优化的编写

This commit is contained in:
锦恢 2024-10-03 01:10:47 +08:00
parent a6411df61a
commit 96670359c5
8 changed files with 118 additions and 96 deletions

91
Cargo.lock generated
View File

@ -99,12 +99,6 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "anyhow"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.72" version = "0.1.72"
@ -332,8 +326,8 @@ dependencies = [
name = "digital-lsp" name = "digital-lsp"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"anyhow",
"bincode", "bincode",
"dirs-next",
"flexi_logger", "flexi_logger",
"log", "log",
"path-clean", "path-clean",
@ -351,10 +345,8 @@ dependencies = [
"tempdir", "tempdir",
"tokio", "tokio",
"tower-lsp", "tower-lsp",
"uuid",
"vhdl_lang", "vhdl_lang",
"walkdir", "walkdir",
"which",
] ]
[[package]] [[package]]
@ -366,6 +358,16 @@ dependencies = [
"dirs-sys", "dirs-sys",
] ]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]] [[package]]
name = "dirs-sys" name = "dirs-sys"
version = "0.4.1" version = "0.4.1"
@ -378,6 +380,17 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "dunce" name = "dunce"
version = "1.0.5" version = "1.0.5"
@ -416,16 +429,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "flexi_logger" name = "flexi_logger"
version = "0.29.0" version = "0.29.0"
@ -603,15 +606,6 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.8.0" version = "1.8.0"
@ -713,12 +707,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "linux-raw-sys"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.10" version = "0.4.10"
@ -1171,19 +1159,6 @@ version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustix"
version = "0.38.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca"
dependencies = [
"bitflags 2.4.2",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.14" version = "1.0.14"
@ -1729,15 +1704,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "vec_map" name = "vec_map"
version = "0.8.2" version = "0.8.2"
@ -1849,19 +1815,6 @@ version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "which"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fa5e0c10bf77f44aac573e498d1a82d5fbd5e91f6fc0a99e7be4b38e85e101c"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View File

@ -7,7 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"} sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
vhdl_lang = { version = "^0.83.0", path = "rust_hdl/vhdl_lang" } vhdl_lang = { version = "^0.83.0", path = "rust_hdl/vhdl_lang" }
uuid = { version = "1.0", features = ["v4"] } dirs-next = "2.0"
bincode = "1.3" bincode = "1.3"
percent-encoding = "2.1.0" percent-encoding = "2.1.0"
log = "0.4.19" log = "0.4.19"
@ -21,8 +21,6 @@ walkdir = "2.3.3"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_yaml = "0.9.25" serde_yaml = "0.9.25"
anyhow = "1.0.72"
which = "6.0.0"
regex = "1.9.1" regex = "1.9.1"
structopt = "0.3.26" structopt = "0.3.26"
strum = "0.26.1" strum = "0.26.1"

View File

@ -1,9 +1,10 @@
use std::{collections::HashMap, fs::{self, File}, io::Read, path::PathBuf, str::FromStr, sync::{Arc, RwLock}}; use core::hash;
use std::{borrow::{Borrow, Cow}, collections::HashMap, fs::{self}, hash::{DefaultHasher, Hash, Hasher}, os::unix::thread, path::PathBuf, sync::{Arc, RwLock}};
use log::info; use log::info;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::utils::{file_size_in_kb, get_last_modified_time, k_deserialize}; use crate::utils::{file_size_in_kb, get_last_modified_time, k_deserialize, k_serialize};
use super::hdlparam::FastHdlparam; use super::hdlparam::FastHdlparam;
@ -16,7 +17,7 @@ pub enum CacheResult<T> {
Error(String) Error(String)
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CacheItem { pub struct CacheItem {
/// 文件名字 /// 文件名字
pub file_name: String, pub file_name: String,
@ -40,11 +41,9 @@ pub struct CacheManager {
} }
impl CacheManager { impl CacheManager {
pub fn new(root_dir: &str) -> Self { pub fn new(root_dir: PathBuf) -> Self {
// 读入 meta 文件 // 读入 meta 文件
let root_dir = PathBuf::from_str(root_dir).unwrap();
let meta_name = "index.cache"; let meta_name = "index.cache";
let meta_path = root_dir.join(meta_name); let meta_path = root_dir.join(meta_name);
let meta = get_or_init_meta(&meta_path); let meta = get_or_init_meta(&meta_path);
@ -106,8 +105,45 @@ impl CacheManager {
CacheResult::CacheNotFound CacheResult::CacheNotFound
} }
pub fn update_cache() { pub fn get_uuid_cache_name(&self, path_string: String) -> String {
// 采用 sip 哈希算法计算哈希
let mut hasher = DefaultHasher::new();
path_string.hash(&mut hasher);
let hash_value = hasher.finish();
let hash_string = format!("{:x}", hash_value);
let mut hash_string: String = hash_string.chars().take(32).collect();
hash_string.push_str(".cache");
hash_string
}
pub fn update_cache(&self, path: &PathBuf, fast: FastHdlparam) {
let path_string = path.to_str().unwrap();
let version = self.get_version(path);
let size = file_size_in_kb(path_string).unwrap();
let file_name = path.file_name().unwrap().to_str().unwrap().to_string();
let cache_name = self.get_uuid_cache_name(path_string.to_string());
let cache_item = CacheItem {
file_name,
version,
size,
cache_name: cache_name.clone()
};
let mut meta_handle = self.meta.write().unwrap();
meta_handle.insert(path_string.to_string(), cache_item);
// 准备必要的独立数据塞入线程进行调度
let meta = (&*meta_handle).clone();
let meta_save_path = self.root_dir.join(self.meta_name.clone());
let cache_save_path = self.root_dir.join(cache_name);
std::thread::spawn(move || {
info!("save meta to {meta_save_path:?}");
k_serialize(&meta_save_path, meta);
info!("save index to {cache_save_path:?}");
k_serialize(&cache_save_path, fast);
});
} }
} }

View File

@ -2,7 +2,6 @@ use std::fs::{self, File};
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::path::PathBuf; use std::path::PathBuf;
use anyhow::Error;
use regex::Regex; use regex::Regex;
use ropey::Rope; use ropey::Rope;
use tower_lsp::lsp_types::Url; use tower_lsp::lsp_types::Url;
@ -38,7 +37,7 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
None None
} }
pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Result<FastHdlparam, Error> { pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Result<FastHdlparam, std::io::Error> {
// 对不同操作系统文件路径的支持 // 对不同操作系统文件路径的支持
let path = to_escape_path(path); let path = to_escape_path(path);

View File

@ -346,7 +346,7 @@ pub fn hover_module_declaration(
let port_num = module.ports.len(); let port_num = module.ports.len();
let param_num = module.params.len(); let param_num = module.params.len();
let instance_num = module.instances.len(); let instance_num = module.instances.len();
let port_desc = format!("`$(instance-param) ` {port_num}, `param` {param_num}, `instantiation` {instance_num}"); let port_desc = format!("`port` {port_num}, `param` {param_num}, `instantiation` {instance_num}");
// 统计 dir // 统计 dir
let mut input_count = 0 as u32; let mut input_count = 0 as u32;

View File

@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
use tower_lsp::jsonrpc::Result; use tower_lsp::jsonrpc::Result;
use tower_lsp::lsp_types::*; use tower_lsp::lsp_types::*;
use crate::core::cache_storage::CacheResult;
use crate::core::hdlparam::FastHdlparam; use crate::core::hdlparam::FastHdlparam;
use crate::core::sv_parser::make_fast_from_syntaxtree; use crate::core::sv_parser::make_fast_from_syntaxtree;
@ -92,18 +93,50 @@ pub fn do_fast<'a>(path: String, backend: &Arc<Backend>) -> Result<FastHdlparam>
info!("parse fast \"{}\"", path); info!("parse fast \"{}\"", path);
let language_id = get_language_id_by_path_str(&path); let language_id = get_language_id_by_path_str(&path);
let res = match language_id.as_str() {
"vhdl" => do_vhdl_fast(&path, backend), let parse_fast_by_language_id = |language_id: &str| {
"verilog" | "systemverilog" => do_sv_fast(&path, backend), match language_id {
"vhdl" => {
do_vhdl_fast(&path, backend)
}
"verilog" | "systemverilog" => {
do_sv_fast(&path, backend)
}
_ => Err(tower_lsp::jsonrpc::Error { _ => Err(tower_lsp::jsonrpc::Error {
code: tower_lsp::jsonrpc::ErrorCode::InvalidRequest, code: tower_lsp::jsonrpc::ErrorCode::InvalidRequest,
message: Cow::Owned(format!("invalid file: {path}, expect vhdl, verilog or system verilog!")), message: Cow::Owned(format!("invalid file: {path}, expect vhdl, verilog or system verilog!")),
data: None data: None
}) })
}
}; };
info!("finish parse"); let path_buf = PathBuf::from_str(&path).unwrap();
res // 做缓存优化
let cache = &backend.server.cache;
match cache.try_get_fast_cache(&path_buf) {
// 找到缓存,直接返回
CacheResult::Ok(fast) => {
return Ok(fast);
}
// cache 没找到,那么就需要计算并存入
CacheResult::CacheNotFound => {
match parse_fast_by_language_id(&language_id) {
Ok(fast) => {
cache.update_cache(&path_buf, fast.clone());
return Ok(fast);
},
Err(err) => Err(err)
}
}
// 不需要缓存的文件正常进行 fast 计算即可
_ => {
parse_fast_by_language_id(&language_id)
}
}
} }
fn do_sv_fast(path: &str, backend: &Arc<Backend>) -> Result<FastHdlparam> { fn do_sv_fast(path: &str, backend: &Arc<Backend>) -> Result<FastHdlparam> {

View File

@ -6,12 +6,13 @@ use flexi_logger::LoggerHandle;
use log::{debug, info, warn}; use log::{debug, info, warn};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::string::ToString; use std::string::ToString;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Mutex, RwLock};
use tower_lsp::jsonrpc::Result; use tower_lsp::jsonrpc::Result;
use tower_lsp::lsp_types::*; use tower_lsp::lsp_types::*;
use tower_lsp::{Client, LanguageServer}; use tower_lsp::{Client, LanguageServer};
pub struct LSPServer { pub struct LSPServer {
pub srcs: Sources, pub srcs: Sources,
pub cache: CacheManager,
pub key_comps: Vec<CompletionItem>, pub key_comps: Vec<CompletionItem>,
pub sys_tasks: Vec<CompletionItem>, pub sys_tasks: Vec<CompletionItem>,
pub directives: Vec<CompletionItem>, pub directives: Vec<CompletionItem>,
@ -22,8 +23,11 @@ pub struct LSPServer {
impl LSPServer { impl LSPServer {
pub fn new(log_handle: Option<LoggerHandle>) -> LSPServer { pub fn new(log_handle: Option<LoggerHandle>) -> LSPServer {
let user_home = dirs_next::home_dir().unwrap();
let dide_home = user_home.join(".digital-ide");
LSPServer { LSPServer {
srcs: Sources::new(), srcs: Sources::new(),
cache: CacheManager::new(dide_home),
key_comps: keyword_completions(KEYWORDS), key_comps: keyword_completions(KEYWORDS),
sys_tasks: other_completions(SYS_TASKS), sys_tasks: other_completions(SYS_TASKS),
directives: other_completions(DIRECTIVES), directives: other_completions(DIRECTIVES),
@ -166,9 +170,8 @@ impl Default for VeribleFormat {
#[tower_lsp::async_trait] #[tower_lsp::async_trait]
impl LanguageServer for Backend { impl LanguageServer for Backend {
async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> { async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
self.server.srcs.init(); self.server.srcs.init();
// params.client_info.unwrap().name
// 申明 LSP 的基本信息和提供的能力 // 申明 LSP 的基本信息和提供的能力
let server_info = Some(ServerInfo { let server_info = Some(ServerInfo {

View File

@ -448,7 +448,7 @@ pub fn recovery_sv_parse(
return Some(syntax_tree); return Some(syntax_tree);
} }
Err(err) => { Err(err) => {
println!("err: {err:?}"); // println!("err: {err:?}");
match err { match err {
// 语法错误 // 语法错误
sv_parser::Error::Parse(trace) => match trace { sv_parser::Error::Parse(trace) => match trace {