blob: 6e049f0d40f73bf266c7b0de53d622e268a43288 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
//! 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 std::hash::BuildHasherDefault;
use indexmap::IndexSet;
use rustc_hash::FxHasher;
use crate::{FileId, VfsPath};
/// Structure to map between [`VfsPath`] and [`FileId`].
pub(crate) struct PathInterner {
map: IndexSet<VfsPath, BuildHasherDefault<FxHasher>>,
}
impl Default for PathInterner {
fn default() -> Self {
Self { map: IndexSet::default() }
}
}
impl PathInterner {
/// Get the id corresponding to `path`.
///
/// If `path` does not exists in `self`, returns [`None`].
pub(crate) fn get(&self, path: &VfsPath) -> Option<FileId> {
self.map.get_index_of(path).map(|i| FileId(i as u32))
}
/// Insert `path` in `self`.
///
/// - 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 {
let (id, _added) = self.map.insert_full(path);
assert!(id < u32::MAX as usize);
FileId(id as u32)
}
/// Returns the path corresponding to `id`.
///
/// # Panics
///
/// Panics if `id` does not exists in `self`.
pub(crate) fn lookup(&self, id: FileId) -> &VfsPath {
self.map.get_index(id.0 as usize).unwrap()
}
}
|