]>
Commit | Line | Data |
---|---|---|
064997fb FG |
1 | //! Maps paths to compact integer ids. We don't care about clearings paths which |
2 | //! no longer exist -- the assumption is total size of paths we ever look at is | |
3 | //! not too big. | |
4 | use std::hash::BuildHasherDefault; | |
5 | ||
6 | use indexmap::IndexSet; | |
7 | use rustc_hash::FxHasher; | |
8 | ||
9 | use crate::{FileId, VfsPath}; | |
10 | ||
11 | /// Structure to map between [`VfsPath`] and [`FileId`]. | |
f25598a0 | 12 | #[derive(Default)] |
064997fb FG |
13 | pub(crate) struct PathInterner { |
14 | map: IndexSet<VfsPath, BuildHasherDefault<FxHasher>>, | |
15 | } | |
16 | ||
064997fb FG |
17 | impl PathInterner { |
18 | /// Get the id corresponding to `path`. | |
19 | /// | |
20 | /// If `path` does not exists in `self`, returns [`None`]. | |
21 | pub(crate) fn get(&self, path: &VfsPath) -> Option<FileId> { | |
22 | self.map.get_index_of(path).map(|i| FileId(i as u32)) | |
23 | } | |
24 | ||
25 | /// Insert `path` in `self`. | |
26 | /// | |
27 | /// - If `path` already exists in `self`, returns its associated id; | |
28 | /// - Else, returns a newly allocated id. | |
29 | pub(crate) fn intern(&mut self, path: VfsPath) -> FileId { | |
30 | let (id, _added) = self.map.insert_full(path); | |
31 | assert!(id < u32::MAX as usize); | |
32 | FileId(id as u32) | |
33 | } | |
34 | ||
35 | /// Returns the path corresponding to `id`. | |
36 | /// | |
37 | /// # Panics | |
38 | /// | |
39 | /// Panics if `id` does not exists in `self`. | |
40 | pub(crate) fn lookup(&self, id: FileId) -> &VfsPath { | |
41 | self.map.get_index(id.0 as usize).unwrap() | |
42 | } | |
43 | } |