mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 05:08:52 +00:00
Avoid duplicating VfsPath in vfs::path_interner::PathInterner by using an IndexSet
This commit is contained in:
parent
32304d14a1
commit
4e2a6ac7ea
3 changed files with 18 additions and 13 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1867,6 +1867,7 @@ name = "vfs"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"fst",
|
||||
"indexmap",
|
||||
"paths",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
|
|
@ -14,3 +14,4 @@ rustc-hash = "1.0"
|
|||
fst = "0.4"
|
||||
|
||||
paths = { path = "../paths", version = "0.0.0" }
|
||||
indexmap = "1.6.2"
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
//! Maps paths to compact integer ids. We don't care about clearings paths which
|
||||
//! no longer exist -- the assumption is total size of paths we ever look at is
|
||||
//! not too big.
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use rustc_hash::FxHasher;
|
||||
|
||||
use crate::{FileId, VfsPath};
|
||||
|
||||
/// Structure to map between [`VfsPath`] and [`FileId`].
|
||||
#[derive(Default)]
|
||||
pub(crate) struct PathInterner {
|
||||
map: FxHashMap<VfsPath, FileId>,
|
||||
vec: Vec<VfsPath>,
|
||||
map: IndexSet<VfsPath, BuildHasherDefault<FxHasher>>,
|
||||
}
|
||||
|
||||
impl Default for PathInterner {
|
||||
fn default() -> Self {
|
||||
Self { map: IndexSet::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl PathInterner {
|
||||
|
@ -17,7 +24,7 @@ impl PathInterner {
|
|||
///
|
||||
/// If `path` does not exists in `self`, returns [`None`].
|
||||
pub(crate) fn get(&self, path: &VfsPath) -> Option<FileId> {
|
||||
self.map.get(path).copied()
|
||||
self.map.get_index_of(path).map(|i| FileId(i as u32))
|
||||
}
|
||||
|
||||
/// Insert `path` in `self`.
|
||||
|
@ -25,13 +32,9 @@ impl PathInterner {
|
|||
/// - If `path` already exists in `self`, returns its associated id;
|
||||
/// - Else, returns a newly allocated id.
|
||||
pub(crate) fn intern(&mut self, path: VfsPath) -> FileId {
|
||||
if let Some(id) = self.get(&path) {
|
||||
return id;
|
||||
}
|
||||
let id = FileId(self.vec.len() as u32);
|
||||
self.map.insert(path.clone(), id);
|
||||
self.vec.push(path);
|
||||
id
|
||||
let (id, _added) = self.map.insert_full(path);
|
||||
assert!(id < u32::MAX as usize);
|
||||
FileId(id as u32)
|
||||
}
|
||||
|
||||
/// Returns the path corresponding to `id`.
|
||||
|
@ -40,6 +43,6 @@ impl PathInterner {
|
|||
///
|
||||
/// Panics if `id` does not exists in `self`.
|
||||
pub(crate) fn lookup(&self, id: FileId) -> &VfsPath {
|
||||
&self.vec[id.0 as usize]
|
||||
self.map.get_index(id.0 as usize).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue