Skip to content

Commit 4e2a6ac

Browse files
committed
Avoid duplicating VfsPath in vfs::path_interner::PathInterner by using an IndexSet
1 parent 32304d1 commit 4e2a6ac

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/vfs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ rustc-hash = "1.0"
1414
fst = "0.4"
1515

1616
paths = { path = "../paths", version = "0.0.0" }
17+
indexmap = "1.6.2"

crates/vfs/src/path_interner.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
//! Maps paths to compact integer ids. We don't care about clearings paths which
22
//! no longer exist -- the assumption is total size of paths we ever look at is
33
//! not too big.
4-
use rustc_hash::FxHashMap;
4+
use std::hash::BuildHasherDefault;
5+
6+
use indexmap::IndexSet;
7+
use rustc_hash::FxHasher;
58

69
use crate::{FileId, VfsPath};
710

811
/// Structure to map between [`VfsPath`] and [`FileId`].
9-
#[derive(Default)]
1012
pub(crate) struct PathInterner {
11-
map: FxHashMap<VfsPath, FileId>,
12-
vec: Vec<VfsPath>,
13+
map: IndexSet<VfsPath, BuildHasherDefault<FxHasher>>,
14+
}
15+
16+
impl Default for PathInterner {
17+
fn default() -> Self {
18+
Self { map: IndexSet::default() }
19+
}
1320
}
1421

1522
impl PathInterner {
1623
/// Get the id corresponding to `path`.
1724
///
1825
/// If `path` does not exists in `self`, returns [`None`].
1926
pub(crate) fn get(&self, path: &VfsPath) -> Option<FileId> {
20-
self.map.get(path).copied()
27+
self.map.get_index_of(path).map(|i| FileId(i as u32))
2128
}
2229

2330
/// Insert `path` in `self`.
2431
///
2532
/// - If `path` already exists in `self`, returns its associated id;
2633
/// - Else, returns a newly allocated id.
2734
pub(crate) fn intern(&mut self, path: VfsPath) -> FileId {
28-
if let Some(id) = self.get(&path) {
29-
return id;
30-
}
31-
let id = FileId(self.vec.len() as u32);
32-
self.map.insert(path.clone(), id);
33-
self.vec.push(path);
34-
id
35+
let (id, _added) = self.map.insert_full(path);
36+
assert!(id < u32::MAX as usize);
37+
FileId(id as u32)
3538
}
3639

3740
/// Returns the path corresponding to `id`.
@@ -40,6 +43,6 @@ impl PathInterner {
4043
///
4144
/// Panics if `id` does not exists in `self`.
4245
pub(crate) fn lookup(&self, id: FileId) -> &VfsPath {
43-
&self.vec[id.0 as usize]
46+
self.map.get_index(id.0 as usize).unwrap()
4447
}
4548
}

0 commit comments

Comments
 (0)