From 26bfc7de367860794ea81f468a44ae68cd6deb70 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Tue, 6 Mar 2018 17:44:31 -0500 Subject: [PATCH] add unsafe --- src/cargo/core/interning.rs | 43 ++++++++++++++++++++++++---------- src/cargo/core/resolver/mod.rs | 2 +- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/cargo/core/interning.rs b/src/cargo/core/interning.rs index c24b6e70f81..16f9c134742 100644 --- a/src/cargo/core/interning.rs +++ b/src/cargo/core/interning.rs @@ -1,34 +1,51 @@ use std::fmt; use std::sync::RwLock; -use std::collections::HashMap; +use std::collections::HashSet; +use std::slice; +use std::str; +use std::mem; + +pub fn leek(s: String) -> &'static str { + let ptr = s.as_ptr(); + let len = s.len(); + mem::forget(s); + unsafe { + let slice = slice::from_raw_parts(ptr, len); + str::from_utf8_unchecked(slice) + } +} lazy_static! { - static ref STRING_CASHE: RwLock<(Vec, HashMap)> = - RwLock::new((Vec::new(), HashMap::new())); + static ref STRING_CASHE: RwLock> = + RwLock::new(HashSet::new()); } #[derive(Eq, PartialEq, Hash, Clone, Copy)] pub struct InternedString { - id: usize + ptr: *const u8, + len: usize, } impl InternedString { pub fn new(str: &str) -> InternedString { - let (ref mut str_from_id, ref mut id_from_str) = *STRING_CASHE.write().unwrap(); - if let Some(&id) = id_from_str.get(str) { - return InternedString { id }; + let mut cache = STRING_CASHE.write().unwrap(); + if let Some(&s) = cache.get(str) { + return InternedString { ptr: s.as_ptr(), len: s.len() }; } - str_from_id.push(str.to_string()); - id_from_str.insert(str.to_string(), str_from_id.len() - 1); - return InternedString { id: str_from_id.len() - 1 } + let s = leek(str.to_string()); + cache.insert(s); + InternedString { ptr: s.as_ptr(), len: s.len() } } - pub fn to_inner(&self) -> String { - STRING_CASHE.read().unwrap().0[self.id].to_string() + pub fn to_inner(&self) -> &'static str { + unsafe { + let slice = slice::from_raw_parts(self.ptr, self.len); + str::from_utf8_unchecked(slice) + } } } impl fmt::Debug for InternedString { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "InternedString {{ {} }}", STRING_CASHE.read().unwrap().0[self.id]) + write!(f, "InternedString {{ {} }}", self.to_inner()) } } diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index 1232151afbf..011766d952b 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -371,7 +371,7 @@ pub fn resolve(summaries: &[(Summary, Method)], metadata: BTreeMap::new(), replacements: cx.resolve_replacements(), features: cx.resolve_features.iter().map(|(k, v)| { - (k.clone(), v.iter().map(|x| x.to_inner()).collect()) + (k.clone(), v.iter().map(|x| x.to_inner().to_string()).collect()) }).collect(), unused_patches: Vec::new(), };