add unsafe
authorEh2406 <YeomanYaacov@gmail.com>
Tue, 6 Mar 2018 22:44:31 +0000 (17:44 -0500)
committerEh2406 <YeomanYaacov@gmail.com>
Tue, 6 Mar 2018 22:44:31 +0000 (17:44 -0500)
src/cargo/core/interning.rs
src/cargo/core/resolver/mod.rs

index c24b6e70f8108dbbfc24e4e4526a9ae61be276cf..16f9c134742e0c792b919ce5f437b5e1db4da09e 100644 (file)
@@ -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<String>, HashMap<String, usize>)> =
-        RwLock::new((Vec::new(), HashMap::new()));
+    static ref STRING_CASHE: RwLock<HashSet<&'static str>> =
+        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())
     }
 }
index 1232151afbf5b8848df5e91efee3e003df46bcb9..011766d952bcbfa60aeeb57ecbeede97d8831654 100644 (file)
@@ -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(),
     };