Skip to content

Commit

Permalink
fix: lsp db clone. (#1174)
Browse files Browse the repository at this point in the history
fix: lsp db clone. Fix the performance loss caused by lsp AnalysisDatabase clone, use Arc::clone instead

Signed-off-by: he1pa <18012015693@163.com>
  • Loading branch information
He1pa committed Mar 29, 2024
1 parent 2234ca8 commit 17dc370
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 19 deletions.
2 changes: 1 addition & 1 deletion kclvm/tools/src/LSP/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ use std::{collections::HashMap, sync::Arc};

#[derive(Default)]
pub struct Analysis {
pub db: Arc<RwLock<HashMap<FileId, AnalysisDatabase>>>,
pub db: Arc<RwLock<HashMap<FileId, Arc<AnalysisDatabase>>>>,
}
29 changes: 14 additions & 15 deletions kclvm/tools/src/LSP/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use kclvm_sema::info::is_valid_kcl_name;
use lsp_types::{Location, SemanticTokensResult, TextEdit};
use ra_ap_vfs::VfsPath;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Instant;

use crate::error::LSPError;
Expand Down Expand Up @@ -100,11 +101,11 @@ impl LanguageServerSnapshot {
valid
}

pub(crate) fn get_db(&self, path: &VfsPath) -> anyhow::Result<AnalysisDatabase> {
pub(crate) fn get_db(&self, path: &VfsPath) -> anyhow::Result<Arc<AnalysisDatabase>> {
let file_id = self.vfs.read().file_id(path);
match file_id {
Some(id) => match self.db.read().get(&id) {
Some(db) => Ok(db.clone()),
Some(db) => Ok(Arc::clone(db)),
None => Err(anyhow::anyhow!(LSPError::FileIdNotFound(path.clone()))),
},
None => Err(anyhow::anyhow!(LSPError::AnalysisDatabaseNotFound(
Expand All @@ -114,11 +115,14 @@ impl LanguageServerSnapshot {
}

/// Attempts to get db in cache, this function does not block.
pub(crate) fn try_get_db(&self, path: &VfsPath) -> anyhow::Result<Option<AnalysisDatabase>> {
pub(crate) fn try_get_db(
&self,
path: &VfsPath,
) -> anyhow::Result<Option<Arc<AnalysisDatabase>>> {
match self.vfs.try_read() {
Some(vfs) => match vfs.file_id(path) {
Some(file_id) => match self.db.try_read() {
Some(db) => Ok(db.get(&file_id).cloned()),
Some(db) => Ok(db.get(&file_id).map(|db| Arc::clone(db))),
None => Ok(None),
},
None => Err(anyhow::anyhow!(LSPError::AnalysisDatabaseNotFound(
Expand Down Expand Up @@ -275,7 +279,8 @@ pub(crate) fn handle_completion(
.context
.and_then(|ctx| ctx.trigger_character)
.and_then(|s| s.chars().next());
let (prog, gs) = match completion_trigger_character {

let db = match completion_trigger_character {
// Some trigger characters need to re-compile
Some(ch) => match ch {
'=' | ':' => {
Expand All @@ -285,23 +290,17 @@ pub(crate) fn handle_completion(
scope_cache: None,
vfs: Some(snapshot.vfs.clone()),
}) {
Ok((prog, _, gs)) => (prog, gs),
Ok((prog, diags, gs)) => Arc::new(AnalysisDatabase { prog, diags, gs }),
Err(_) => return Ok(None),
}
}
_ => {
let db = snapshot.get_db(&path.clone().into())?;
(db.prog, db.gs)
}
_ => snapshot.get_db(&path.clone().into())?,
},

None => {
let db = snapshot.get_db(&path.clone().into())?;
(db.prog, db.gs)
}
None => snapshot.get_db(&path.clone().into())?,
};

let res = completion(completion_trigger_character, &prog, &kcl_pos, &gs);
let res = completion(completion_trigger_character, &db.prog, &kcl_pos, &db.gs);

if res.is_none() {
log_message("Completion item not found".to_string(), &sender)?;
Expand Down
6 changes: 3 additions & 3 deletions kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub(crate) struct LanguageServerSnapshot {
/// The virtual filesystem that holds all the file contents
pub vfs: Arc<RwLock<Vfs>>,
/// Holds the state of the analysis process
pub db: Arc<RwLock<HashMap<FileId, AnalysisDatabase>>>,
pub db: Arc<RwLock<HashMap<FileId, Arc<AnalysisDatabase>>>>,
/// Documents that are currently kept in memory from the client
pub opened_files: IndexSet<FileId>,
/// The word index map
Expand Down Expand Up @@ -232,11 +232,11 @@ impl LanguageServerState {
Ok((prog, diags, gs)) => {
db.insert(
file.file_id,
AnalysisDatabase {
Arc::new(AnalysisDatabase {
prog,
diags: diags.clone(),
gs,
},
}),
);

let diagnostics = diags
Expand Down

0 comments on commit 17dc370

Please sign in to comment.