完成缓存优化的编写
This commit is contained in:
parent
a6411df61a
commit
96670359c5
91
Cargo.lock
generated
91
Cargo.lock
generated
@ -99,12 +99,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "async-trait"
|
||||
version = "0.1.72"
|
||||
@ -332,8 +326,8 @@ dependencies = [
|
||||
name = "digital-lsp"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"dirs-next",
|
||||
"flexi_logger",
|
||||
"log",
|
||||
"path-clean",
|
||||
@ -351,10 +345,8 @@ dependencies = [
|
||||
"tempdir",
|
||||
"tokio",
|
||||
"tower-lsp",
|
||||
"uuid",
|
||||
"vhdl_lang",
|
||||
"walkdir",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -366,6 +358,16 @@ dependencies = [
|
||||
"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]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
@ -378,6 +380,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "dunce"
|
||||
version = "1.0.5"
|
||||
@ -416,16 +429,6 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "flexi_logger"
|
||||
version = "0.29.0"
|
||||
@ -603,15 +606,6 @@ version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
@ -713,12 +707,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
@ -1171,19 +1159,6 @@ version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "rustversion"
|
||||
version = "1.0.14"
|
||||
@ -1729,15 +1704,6 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
@ -1849,19 +1815,6 @@ version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -7,7 +7,7 @@ edition = "2018"
|
||||
[dependencies]
|
||||
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
|
||||
vhdl_lang = { version = "^0.83.0", path = "rust_hdl/vhdl_lang" }
|
||||
uuid = { version = "1.0", features = ["v4"] }
|
||||
dirs-next = "2.0"
|
||||
bincode = "1.3"
|
||||
percent-encoding = "2.1.0"
|
||||
log = "0.4.19"
|
||||
@ -21,8 +21,6 @@ walkdir = "2.3.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.9.25"
|
||||
anyhow = "1.0.72"
|
||||
which = "6.0.0"
|
||||
regex = "1.9.1"
|
||||
structopt = "0.3.26"
|
||||
strum = "0.26.1"
|
||||
|
@ -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 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;
|
||||
|
||||
@ -16,7 +17,7 @@ pub enum CacheResult<T> {
|
||||
Error(String)
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct CacheItem {
|
||||
/// 文件名字
|
||||
pub file_name: String,
|
||||
@ -40,11 +41,9 @@ pub struct CacheManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl CacheManager {
|
||||
pub fn new(root_dir: &str) -> Self {
|
||||
pub fn new(root_dir: PathBuf) -> 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);
|
||||
@ -106,8 +105,45 @@ impl CacheManager {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ use std::fs::{self, File};
|
||||
use std::io::BufRead;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use anyhow::Error;
|
||||
use regex::Regex;
|
||||
use ropey::Rope;
|
||||
use tower_lsp::lsp_types::Url;
|
||||
@ -38,7 +37,7 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
||||
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);
|
||||
|
||||
|
@ -346,7 +346,7 @@ pub fn hover_module_declaration(
|
||||
let port_num = module.ports.len();
|
||||
let param_num = module.params.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
|
||||
let mut input_count = 0 as u32;
|
||||
|
@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
|
||||
use tower_lsp::jsonrpc::Result;
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
||||
use crate::core::cache_storage::CacheResult;
|
||||
use crate::core::hdlparam::FastHdlparam;
|
||||
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);
|
||||
|
||||
let language_id = get_language_id_by_path_str(&path);
|
||||
let res = match language_id.as_str() {
|
||||
"vhdl" => do_vhdl_fast(&path, backend),
|
||||
"verilog" | "systemverilog" => do_sv_fast(&path, backend),
|
||||
_ => Err(tower_lsp::jsonrpc::Error {
|
||||
code: tower_lsp::jsonrpc::ErrorCode::InvalidRequest,
|
||||
message: Cow::Owned(format!("invalid file: {path}, expect vhdl, verilog or system verilog!")),
|
||||
data: None
|
||||
})
|
||||
|
||||
let parse_fast_by_language_id = |language_id: &str| {
|
||||
match language_id {
|
||||
"vhdl" => {
|
||||
do_vhdl_fast(&path, backend)
|
||||
}
|
||||
|
||||
"verilog" | "systemverilog" => {
|
||||
do_sv_fast(&path, backend)
|
||||
}
|
||||
|
||||
_ => Err(tower_lsp::jsonrpc::Error {
|
||||
code: tower_lsp::jsonrpc::ErrorCode::InvalidRequest,
|
||||
message: Cow::Owned(format!("invalid file: {path}, expect vhdl, verilog or system verilog!")),
|
||||
data: None
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
info!("finish parse");
|
||||
res
|
||||
let path_buf = PathBuf::from_str(&path).unwrap();
|
||||
// 做缓存优化
|
||||
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> {
|
||||
|
@ -6,12 +6,13 @@ use flexi_logger::LoggerHandle;
|
||||
use log::{debug, info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::string::ToString;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Mutex, RwLock};
|
||||
use tower_lsp::jsonrpc::Result;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use tower_lsp::{Client, LanguageServer};
|
||||
pub struct LSPServer {
|
||||
pub srcs: Sources,
|
||||
pub cache: CacheManager,
|
||||
pub key_comps: Vec<CompletionItem>,
|
||||
pub sys_tasks: Vec<CompletionItem>,
|
||||
pub directives: Vec<CompletionItem>,
|
||||
@ -22,8 +23,11 @@ pub struct LSPServer {
|
||||
|
||||
impl 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 {
|
||||
srcs: Sources::new(),
|
||||
cache: CacheManager::new(dide_home),
|
||||
key_comps: keyword_completions(KEYWORDS),
|
||||
sys_tasks: other_completions(SYS_TASKS),
|
||||
directives: other_completions(DIRECTIVES),
|
||||
@ -166,9 +170,8 @@ impl Default for VeribleFormat {
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
|
||||
async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
|
||||
self.server.srcs.init();
|
||||
// params.client_info.unwrap().name
|
||||
|
||||
// 申明 LSP 的基本信息和提供的能力
|
||||
let server_info = Some(ServerInfo {
|
||||
|
@ -448,7 +448,7 @@ pub fn recovery_sv_parse(
|
||||
return Some(syntax_tree);
|
||||
}
|
||||
Err(err) => {
|
||||
println!("err: {err:?}");
|
||||
// println!("err: {err:?}");
|
||||
match err {
|
||||
// 语法错误
|
||||
sv_parser::Error::Parse(trace) => match trace {
|
||||
|
Loading…
x
Reference in New Issue
Block a user