From 3d91b795413e0c375c3df7e3f0c0eb6a2464ef67 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 18 Nov 2018 21:06:15 +0000 Subject: [PATCH] Intern SourceId --- src/cargo/core/source/source_id.rs | 45 ++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index f30d18ffd..6b640aefe 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -1,8 +1,9 @@ use std::cmp::{self, Ordering}; +use std::collections::HashSet; use std::fmt::{self, Formatter}; use std::hash::{self, Hash}; use std::path::Path; -use std::sync::Arc; +use std::sync::Mutex; use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT}; use std::sync::atomic::Ordering::SeqCst; @@ -16,13 +17,17 @@ use sources::{GitSource, PathSource, RegistrySource, CRATES_IO_INDEX}; use sources::DirectorySource; use util::{CargoResult, Config, ToUrl}; +lazy_static! { + static ref SOURCE_ID_CACHE: Mutex> = Mutex::new(HashSet::new()); +} + /// Unique identifier for a source of packages. #[derive(Clone, Eq, Debug)] pub struct SourceId { - inner: Arc, + inner: &'static SourceIdInner, } -#[derive(Eq, Clone, Debug)] +#[derive(Eq, Clone, Debug, Hash)] struct SourceIdInner { /// The source URL url: Url, @@ -68,18 +73,28 @@ impl SourceId { /// /// The canonical url will be calculated, but the precise field will not fn new(kind: Kind, url: Url) -> CargoResult { - let source_id = SourceId { - inner: Arc::new(SourceIdInner { + let source_id = SourceId::wrap( + SourceIdInner { kind, canonical_url: git::canonicalize_url(&url)?, url, precise: None, name: None, - }), - }; + } + ); Ok(source_id) } + fn wrap(inner: SourceIdInner) -> SourceId { + let mut cache = SOURCE_ID_CACHE.lock().unwrap(); + let inner = cache.get(&inner).map(|&x| x).unwrap_or_else(|| { + let inner = Box::leak(Box::new(inner)); + cache.insert(inner); + inner + }); + SourceId { inner } + } + /// Parses a source URL and returns the corresponding ID. /// /// ## Example @@ -193,15 +208,15 @@ impl SourceId { pub fn alt_registry(config: &Config, key: &str) -> CargoResult { let url = config.get_registry_index(key)?; - Ok(SourceId { - inner: Arc::new(SourceIdInner { + Ok(SourceId::wrap( + SourceIdInner { kind: Kind::Registry, canonical_url: git::canonicalize_url(&url)?, url, precise: None, name: Some(key.to_string()), - }), - }) + } + )) } /// Get this source URL @@ -288,12 +303,12 @@ impl SourceId { /// Create a new SourceId from this source with the given `precise` pub fn with_precise(&self, v: Option) -> SourceId { - SourceId { - inner: Arc::new(SourceIdInner { + SourceId::wrap( + SourceIdInner { precise: v, ..(*self.inner).clone() - }), - } + } + ) } /// Whether the remote registry is the standard https://crates.io -- 2.39.5