1
1
//! Maps paths to compact integer ids. We don't care about clearings paths which
2
2
//! no longer exist -- the assumption is total size of paths we ever look at is
3
3
//! not too big.
4
- use rustc_hash:: FxHashMap ;
4
+ use std:: hash:: BuildHasherDefault ;
5
+
6
+ use indexmap:: IndexSet ;
7
+ use rustc_hash:: FxHasher ;
5
8
6
9
use crate :: { FileId , VfsPath } ;
7
10
8
11
/// Structure to map between [`VfsPath`] and [`FileId`].
9
- #[ derive( Default ) ]
10
12
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
+ }
13
20
}
14
21
15
22
impl PathInterner {
16
23
/// Get the id corresponding to `path`.
17
24
///
18
25
/// If `path` does not exists in `self`, returns [`None`].
19
26
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 ) )
21
28
}
22
29
23
30
/// Insert `path` in `self`.
24
31
///
25
32
/// - If `path` already exists in `self`, returns its associated id;
26
33
/// - Else, returns a newly allocated id.
27
34
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 )
35
38
}
36
39
37
40
/// Returns the path corresponding to `id`.
@@ -40,6 +43,6 @@ impl PathInterner {
40
43
///
41
44
/// Panics if `id` does not exists in `self`.
42
45
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 ( )
44
47
}
45
48
}
0 commit comments