aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/loc2id.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/loc2id.rs')
-rw-r--r--crates/ra_analysis/src/loc2id.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs
new file mode 100644
index 000000000..a53ce8348
--- /dev/null
+++ b/crates/ra_analysis/src/loc2id.rs
@@ -0,0 +1,64 @@
1use std::hash::Hash;
2
3use rustc_hash::FxHashMap;
4
5/// There are two principle ways to refer to things:
6/// - by their locatinon (module in foo/bar/baz.rs at line 42)
7/// - by their numeric id (module `ModuleId(42)`)
8///
9/// The first one is more powerful (you can actually find the thing in question
10/// by id), but the second one is so much more compact.
11///
12/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a
13/// bidirectional mapping between positional and numeric ids, we can use compact
14/// representation wich still allows us to get the actual item
15#[derive(Debug)]
16pub(crate) struct Loc2IdMap<L, ID>
17where
18 ID: NumericId,
19 L: Clone + Eq + Hash,
20{
21 loc2id: FxHashMap<L, ID>,
22 id2loc: FxHashMap<ID, L>,
23}
24
25impl<L, ID> Default for Loc2IdMap<L, ID>
26where
27 ID: NumericId,
28 L: Clone + Eq + Hash,
29{
30 fn default() -> Self {
31 Loc2IdMap {
32 loc2id: FxHashMap::default(),
33 id2loc: FxHashMap::default(),
34 }
35 }
36}
37
38impl<L, ID> Loc2IdMap<L, ID>
39where
40 ID: NumericId,
41 L: Clone + Eq + Hash,
42{
43 pub fn loc2id(&mut self, loc: &L) -> ID {
44 match self.loc2id.get(loc) {
45 Some(id) => return id.clone(),
46 None => (),
47 }
48 let id = self.loc2id.len();
49 assert!(id < u32::max_value() as usize);
50 let id = ID::from_u32(id as u32);
51 self.loc2id.insert(loc.clone(), id.clone());
52 self.id2loc.insert(id.clone(), loc.clone());
53 id
54 }
55
56 pub fn id2loc(&self, id: &ID) -> L {
57 self.id2loc[id].clone()
58 }
59}
60
61pub(crate) trait NumericId: Clone + Eq + Hash {
62 fn from_u32(id: u32) -> Self;
63 fn to_u32(self) -> u32;
64}