Skip to content

Commit

Permalink
Optimize manifest directory lookup with efficient caching (#6444)
Browse files Browse the repository at this point in the history
## Description
Implemented a caching mechanism for manifest directory lookups using a
DashMap. This optimization reduces average lookup time from
approximately 421µs to 0.47µs, resulting in an 895x speed improvement
for subsequent calls.

part of #5445

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] If my change requires substantial documentation changes, I have
[requested support from the DevRel
team](https://github.com/FuelLabs/devrel-requests/issues/new/choose)
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

Co-authored-by: Sophie Dankel <47993817+sdankel@users.noreply.github.com>
Co-authored-by: IGI-111 <igi-111@protonmail.com>
  • Loading branch information
3 people authored Aug 22, 2024
1 parent 5e0e3a4 commit 5840e8d
Showing 1 changed file with 25 additions and 14 deletions.
39 changes: 25 additions & 14 deletions sway-lsp/src/server_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub struct ServerState {
pub(crate) cb_rx: Arc<Receiver<TaskMessage>>,
pub(crate) finished_compilation: Arc<Notify>,
pub(crate) pid_locked_files: PidLockedFiles,
manifest_cache: DashMap<Url, Arc<PathBuf>>,
last_compilation_state: Arc<RwLock<LastCompilationState>>,
}

Expand All @@ -68,6 +69,7 @@ impl Default for ServerState {
cb_rx: Arc::new(cb_rx),
finished_compilation: Arc::new(Notify::new()),
pid_locked_files: PidLockedFiles::new(),
manifest_cache: DashMap::new(),
last_compilation_state: Arc::new(RwLock::new(LastCompilationState::Uninitialized)),
};
// Spawn a new thread dedicated to handling compilation tasks
Expand Down Expand Up @@ -351,19 +353,27 @@ impl ServerState {
}

async fn url_to_session(&self, uri: &Url) -> Result<Arc<Session>, LanguageServerError> {
let path = PathBuf::from(uri.path());
let manifest = PackageManifestFile::from_dir(&path).map_err(|_| {
DocumentError::ManifestFileNotFound {
dir: path.to_string_lossy().to_string(),
}
})?;

// strip Forc.toml from the path to get the manifest directory
let manifest_dir = manifest
.path()
.parent()
.ok_or(DirectoryError::ManifestDirNotFound)?
.to_path_buf();
// Try to get the manifest directory from the cache
let manifest_dir = if let Some(cached_dir) = self.manifest_cache.get(uri) {
cached_dir.clone()
} else {
// Otherwise, find the manifest directory from the uri and cache it
let path = PathBuf::from(uri.path());
let manifest = PackageManifestFile::from_dir(&path).map_err(|_| {
DocumentError::ManifestFileNotFound {
dir: path.to_string_lossy().to_string(),
}
})?;
let dir = Arc::new(
manifest
.path()
.parent()
.ok_or(DirectoryError::ManifestDirNotFound)?
.to_path_buf(),
);
self.manifest_cache.insert(uri.clone(), dir.clone());
dir
};

// If the session is already in the cache, return it
if let Some(session) = self.sessions.get(&manifest_dir) {
Expand All @@ -373,7 +383,8 @@ impl ServerState {
// If no session can be found, then we need to call init and insert a new session into the map
let session = Arc::new(Session::new());
session.init(uri, &self.documents).await?;
self.sessions.insert(manifest_dir.clone(), session.clone());
self.sessions
.insert((*manifest_dir).clone(), session.clone());

Ok(session)
}
Expand Down

0 comments on commit 5840e8d

Please sign in to comment.