From cb22a799d60c6c5f81ad0f3d0361f575264f3bc2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 18 Nov 2018 15:44:24 +0300 Subject: Add Loc2IdMap --- crates/ra_analysis/src/loc2id.rs | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 crates/ra_analysis/src/loc2id.rs (limited to 'crates/ra_analysis/src/loc2id.rs') 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 @@ +use std::hash::Hash; + +use rustc_hash::FxHashMap; + +/// There are two principle ways to refer to things: +/// - by their locatinon (module in foo/bar/baz.rs at line 42) +/// - by their numeric id (module `ModuleId(42)`) +/// +/// The first one is more powerful (you can actually find the thing in question +/// by id), but the second one is so much more compact. +/// +/// `Loc2IdMap` allows us to have a cake an eat it as well: by maintaining a +/// bidirectional mapping between positional and numeric ids, we can use compact +/// representation wich still allows us to get the actual item +#[derive(Debug)] +pub(crate) struct Loc2IdMap +where + ID: NumericId, + L: Clone + Eq + Hash, +{ + loc2id: FxHashMap, + id2loc: FxHashMap, +} + +impl Default for Loc2IdMap +where + ID: NumericId, + L: Clone + Eq + Hash, +{ + fn default() -> Self { + Loc2IdMap { + loc2id: FxHashMap::default(), + id2loc: FxHashMap::default(), + } + } +} + +impl Loc2IdMap +where + ID: NumericId, + L: Clone + Eq + Hash, +{ + pub fn loc2id(&mut self, loc: &L) -> ID { + match self.loc2id.get(loc) { + Some(id) => return id.clone(), + None => (), + } + let id = self.loc2id.len(); + assert!(id < u32::max_value() as usize); + let id = ID::from_u32(id as u32); + self.loc2id.insert(loc.clone(), id.clone()); + self.id2loc.insert(id.clone(), loc.clone()); + id + } + + pub fn id2loc(&self, id: &ID) -> L { + self.id2loc[id].clone() + } +} + +pub(crate) trait NumericId: Clone + Eq + Hash { + fn from_u32(id: u32) -> Self; + fn to_u32(self) -> u32; +} -- cgit v1.2.3 From 4e48917c00d24e1e1785e1959a2f3495a902410b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 18 Nov 2018 16:21:23 +0300 Subject: use loc2id for FnIds --- crates/ra_analysis/src/loc2id.rs | 50 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) (limited to 'crates/ra_analysis/src/loc2id.rs') diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs index a53ce8348..8eaa24997 100644 --- a/crates/ra_analysis/src/loc2id.rs +++ b/crates/ra_analysis/src/loc2id.rs @@ -1,7 +1,16 @@ -use std::hash::Hash; +use parking_lot::Mutex; + +use std::{ + hash::Hash, + sync::Arc, +}; use rustc_hash::FxHashMap; +use crate::{ + syntax_ptr::SyntaxPtr, +}; + /// There are two principle ways to refer to things: /// - by their locatinon (module in foo/bar/baz.rs at line 42) /// - by their numeric id (module `ModuleId(42)`) @@ -53,8 +62,8 @@ where id } - pub fn id2loc(&self, id: &ID) -> L { - self.id2loc[id].clone() + pub fn id2loc(&self, id: ID) -> L { + self.id2loc[&id].clone() } } @@ -62,3 +71,38 @@ pub(crate) trait NumericId: Clone + Eq + Hash { fn from_u32(id: u32) -> Self; fn to_u32(self) -> u32; } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct FnId(u32); + +impl NumericId for FnId { + fn from_u32(id: u32) -> FnId { + FnId(id) + } + fn to_u32(self) -> u32 { + self.0 + } +} + +pub(crate) trait IdDatabase: salsa::Database { + fn id_maps(&self) -> &IdMaps; +} + +#[derive(Debug, Default, Clone)] +pub(crate) struct IdMaps { + inner: Arc, +} + +impl IdMaps { + pub(crate) fn fn_id(&self, ptr: SyntaxPtr) -> FnId { + self.inner.fns.lock().loc2id(&ptr) + } + pub(crate) fn fn_ptr(&self, fn_id: FnId) -> SyntaxPtr { + self.inner.fns.lock().id2loc(fn_id) + } +} + +#[derive(Debug, Default)] +struct IdMapsInner { + fns: Mutex>, +} -- cgit v1.2.3