diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-07-11 08:00:48 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-07-11 22:16:00 +0000 |
| commit | 1eb6d0b485acc5f6e0d9f9b0946000bce12f5bfc (patch) | |
| tree | 6e9133cd328816c9c03bc1bc854c7bf74d202232 /src/libsyntax/util | |
| parent | f8a934e971fdef496e69e82ab0e7166363efd3f5 (diff) | |
| download | rust-1eb6d0b485acc5f6e0d9f9b0946000bce12f5bfc.tar.gz rust-1eb6d0b485acc5f6e0d9f9b0946000bce12f5bfc.zip | |
Remove `Interner<T>` and rename `StrInterner` to `Interner`.
Diffstat (limited to 'src/libsyntax/util')
| -rw-r--r-- | src/libsyntax/util/interner.rs | 149 |
1 files changed, 13 insertions, 136 deletions
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 68dbd6272f4..2dd69c76958 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -17,122 +17,45 @@ use ast::Name; use std::borrow::Borrow; use std::cell::RefCell; use std::collections::HashMap; -use std::hash::Hash; use std::rc::Rc; -pub struct Interner<T> { - map: RefCell<HashMap<T, Name>>, - vect: RefCell<Vec<T> >, -} - -// when traits can extend traits, we should extend index<Name,T> to get [] -impl<T: Eq + Hash + Clone + 'static> Interner<T> { - pub fn new() -> Interner<T> { - Interner { - map: RefCell::new(HashMap::new()), - vect: RefCell::new(Vec::new()), - } - } - - pub fn prefill(init: &[T]) -> Interner<T> { - let rv = Interner::new(); - for v in init { - rv.intern((*v).clone()); - } - rv - } - - pub fn intern(&self, val: T) -> Name { - let mut map = self.map.borrow_mut(); - if let Some(&idx) = (*map).get(&val) { - return idx; - } - - let mut vect = self.vect.borrow_mut(); - let new_idx = Name((*vect).len() as u32); - (*map).insert(val.clone(), new_idx); - (*vect).push(val); - new_idx - } - - pub fn gensym(&self, val: T) -> Name { - let mut vect = self.vect.borrow_mut(); - let new_idx = Name((*vect).len() as u32); - // leave out of .map to avoid colliding - (*vect).push(val); - new_idx - } - - pub fn get(&self, idx: Name) -> T { - let vect = self.vect.borrow(); - (*vect)[idx.0 as usize].clone() - } - - pub fn len(&self) -> usize { - let vect = self.vect.borrow(); - (*vect).len() - } - - pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name> - where T: Borrow<Q>, Q: Eq + Hash { - let map = self.map.borrow(); - match (*map).get(val) { - Some(v) => Some(*v), - None => None, - } - } - - pub fn clear(&self) { - *self.map.borrow_mut() = HashMap::new(); - *self.vect.borrow_mut() = Vec::new(); - } -} - -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(PartialEq, Eq, Hash)] struct RcStr(Rc<String>); -impl RcStr { - fn new(string: &str) -> Self { - RcStr(Rc::new(string.to_owned())) - } -} - impl Borrow<str> for RcStr { fn borrow(&self) -> &str { &self.0 } } -/// A StrInterner differs from Interner<String> in that it accepts -/// &str rather than RcStr, resulting in less allocation. -pub struct StrInterner { +pub struct Interner { map: RefCell<HashMap<RcStr, Name>>, vect: RefCell<Vec<Rc<String>> >, } /// When traits can extend traits, we should extend index<Name,T> to get [] -impl StrInterner { - pub fn new() -> StrInterner { - StrInterner { +impl Interner { + pub fn new() -> Self { + Interner { map: RefCell::new(HashMap::new()), vect: RefCell::new(Vec::new()), } } - pub fn prefill(init: &[&str]) -> StrInterner { - let rv = StrInterner::new(); + pub fn prefill(init: &[&str]) -> Self { + let rv = Interner::new(); for &v in init { rv.intern(v); } rv } - pub fn intern(&self, val: &str) -> Name { + pub fn intern<T: Borrow<str> + Into<String>>(&self, val: T) -> Name { let mut map = self.map.borrow_mut(); - if let Some(&idx) = map.get(val) { + if let Some(&idx) = map.get(val.borrow()) { return idx; } let new_idx = Name(self.len() as u32); - let val = Rc::new(val.to_owned()); + let val = Rc::new(val.into()); map.insert(RcStr(val.clone()), new_idx); self.vect.borrow_mut().push(val); new_idx @@ -181,7 +104,7 @@ impl StrInterner { *self.vect.borrow_mut() = Vec::new(); } - pub fn reset(&self, other: StrInterner) { + pub fn reset(&self, other: Interner) { *self.map.borrow_mut() = other.map.into_inner(); *self.vect.borrow_mut() = other.vect.into_inner(); } @@ -190,57 +113,11 @@ impl StrInterner { #[cfg(test)] mod tests { use super::*; - use super::RcStr; use ast::Name; #[test] - #[should_panic] - fn i1 () { - let i : Interner<RcStr> = Interner::new(); - i.get(Name(13)); - } - - #[test] - fn interner_tests () { - let i : Interner<RcStr> = Interner::new(); - // first one is zero: - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // re-use gets the same entry: - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // different string gets a different #: - assert_eq!(i.intern(RcStr::new("cat")), Name(1)); - assert_eq!(i.intern(RcStr::new("cat")), Name(1)); - // dog is still at zero - assert_eq!(i.intern(RcStr::new("dog")), Name(0)); - // gensym gets 3 - assert_eq!(i.gensym(RcStr::new("zebra") ), Name(2)); - // gensym of same string gets new number : - assert_eq!(i.gensym (RcStr::new("zebra") ), Name(3)); - // gensym of *existing* string gets new number: - assert_eq!(i.gensym(RcStr::new("dog")), Name(4)); - assert_eq!(i.get(Name(0)), RcStr::new("dog")); - assert_eq!(i.get(Name(1)), RcStr::new("cat")); - assert_eq!(i.get(Name(2)), RcStr::new("zebra")); - assert_eq!(i.get(Name(3)), RcStr::new("zebra")); - assert_eq!(i.get(Name(4)), RcStr::new("dog")); - } - - #[test] - fn i3 () { - let i : Interner<RcStr> = Interner::prefill(&[ - RcStr::new("Alan"), - RcStr::new("Bob"), - RcStr::new("Carol") - ]); - assert_eq!(i.get(Name(0)), RcStr::new("Alan")); - assert_eq!(i.get(Name(1)), RcStr::new("Bob")); - assert_eq!(i.get(Name(2)), RcStr::new("Carol")); - assert_eq!(i.intern(RcStr::new("Bob")), Name(1)); - } - - #[test] - fn string_interner_tests() { - let i : StrInterner = StrInterner::new(); + fn interner_tests() { + let i : Interner = Interner::new(); // first one is zero: assert_eq!(i.intern("dog"), Name(0)); // re-use gets the same entry: |
