Skip to content

Commit 52a2630

Browse files
committed
Auto merge of #14260 - Eh2406:summary_sync, r=weihanglo
make summary sync by using Arc not Rc ### What does this PR try to resolve? For my PubGrub testing work I want to be able to read the entire crates.io index into memory and then run lots of resolution questions against that data in parallel. Currently cargoes `Summary` and `Dependency` types use `Rc` internally which prevents this pattern. Using `Arc` in cargo makes my life a lot easier! It does not noticeably slow down single threaded performance. (Measured by running my PubGrub testing in single threaded mode before and after.) The team largely agreed to this at a meeting and in discussions https://rust-lang.zulipchat.com/#narrow/stream/246057-t-cargo/topic/Make.20summary.20sync ### How should we test and review this PR? Tests still pass ### Additional information Should be add a test a this is sync?
2 parents a2b58c3 + c27579a commit 52a2630

File tree

2 files changed

+33
-27
lines changed

2 files changed

+33
-27
lines changed

src/cargo/core/dependency.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use serde::Serialize;
55
use std::borrow::Cow;
66
use std::fmt;
77
use std::path::PathBuf;
8-
use std::rc::Rc;
8+
use std::sync::Arc;
99
use tracing::trace;
1010

1111
use crate::core::compiler::{CompileKind, CompileTarget};
@@ -18,7 +18,7 @@ use crate::util::OptVersionReq;
1818
/// Cheap to copy.
1919
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
2020
pub struct Dependency {
21-
inner: Rc<Inner>,
21+
inner: Arc<Inner>,
2222
}
2323

2424
/// The data underlying a `Dependency`.
@@ -152,7 +152,7 @@ impl Dependency {
152152

153153
let mut ret = Dependency::new_override(name, source_id);
154154
{
155-
let ptr = Rc::make_mut(&mut ret.inner);
155+
let ptr = Arc::make_mut(&mut ret.inner);
156156
ptr.only_match_name = false;
157157
ptr.req = version_req;
158158
ptr.specified_req = specified_req;
@@ -163,7 +163,7 @@ impl Dependency {
163163
pub fn new_override(name: InternedString, source_id: SourceId) -> Dependency {
164164
assert!(!name.is_empty());
165165
Dependency {
166-
inner: Rc::new(Inner {
166+
inner: Arc::new(Inner {
167167
name,
168168
source_id,
169169
registry_id: None,
@@ -241,7 +241,7 @@ impl Dependency {
241241
}
242242

243243
pub fn set_registry_id(&mut self, registry_id: SourceId) -> &mut Dependency {
244-
Rc::make_mut(&mut self.inner).registry_id = Some(registry_id);
244+
Arc::make_mut(&mut self.inner).registry_id = Some(registry_id);
245245
self
246246
}
247247

@@ -259,7 +259,7 @@ impl Dependency {
259259
// Setting 'public' only makes sense for normal dependencies
260260
assert_eq!(self.kind(), DepKind::Normal);
261261
}
262-
Rc::make_mut(&mut self.inner).public = public;
262+
Arc::make_mut(&mut self.inner).public = public;
263263
self
264264
}
265265

@@ -286,7 +286,7 @@ impl Dependency {
286286
// Setting 'public' only makes sense for normal dependencies
287287
assert_eq!(kind, DepKind::Normal);
288288
}
289-
Rc::make_mut(&mut self.inner).kind = kind;
289+
Arc::make_mut(&mut self.inner).kind = kind;
290290
self
291291
}
292292

@@ -295,44 +295,44 @@ impl Dependency {
295295
&mut self,
296296
features: impl IntoIterator<Item = impl Into<InternedString>>,
297297
) -> &mut Dependency {
298-
Rc::make_mut(&mut self.inner).features = features.into_iter().map(|s| s.into()).collect();
298+
Arc::make_mut(&mut self.inner).features = features.into_iter().map(|s| s.into()).collect();
299299
self
300300
}
301301

302302
/// Sets whether the dependency requests default features of the package.
303303
pub fn set_default_features(&mut self, default_features: bool) -> &mut Dependency {
304-
Rc::make_mut(&mut self.inner).default_features = default_features;
304+
Arc::make_mut(&mut self.inner).default_features = default_features;
305305
self
306306
}
307307

308308
/// Sets whether the dependency is optional.
309309
pub fn set_optional(&mut self, optional: bool) -> &mut Dependency {
310-
Rc::make_mut(&mut self.inner).optional = optional;
310+
Arc::make_mut(&mut self.inner).optional = optional;
311311
self
312312
}
313313

314314
/// Sets the source ID for this dependency.
315315
pub fn set_source_id(&mut self, id: SourceId) -> &mut Dependency {
316-
Rc::make_mut(&mut self.inner).source_id = id;
316+
Arc::make_mut(&mut self.inner).source_id = id;
317317
self
318318
}
319319

320320
/// Sets the version requirement for this dependency.
321321
pub fn set_version_req(&mut self, req: OptVersionReq) -> &mut Dependency {
322-
Rc::make_mut(&mut self.inner).req = req;
322+
Arc::make_mut(&mut self.inner).req = req;
323323
self
324324
}
325325

326326
pub fn set_platform(&mut self, platform: Option<Platform>) -> &mut Dependency {
327-
Rc::make_mut(&mut self.inner).platform = platform;
327+
Arc::make_mut(&mut self.inner).platform = platform;
328328
self
329329
}
330330

331331
pub fn set_explicit_name_in_toml(
332332
&mut self,
333333
name: impl Into<InternedString>,
334334
) -> &mut Dependency {
335-
Rc::make_mut(&mut self.inner).explicit_name_in_toml = Some(name.into());
335+
Arc::make_mut(&mut self.inner).explicit_name_in_toml = Some(name.into());
336336
self
337337
}
338338

@@ -346,7 +346,7 @@ impl Dependency {
346346
self.source_id(),
347347
id
348348
);
349-
let me = Rc::make_mut(&mut self.inner);
349+
let me = Arc::make_mut(&mut self.inner);
350350
me.req.lock_to(id.version());
351351

352352
// Only update the `precise` of this source to preserve other
@@ -361,7 +361,7 @@ impl Dependency {
361361
/// Mainly used in dependency patching like `[patch]` or `[replace]`, which
362362
/// doesn't need to lock the entire dependency to a specific [`PackageId`].
363363
pub fn lock_version(&mut self, version: &semver::Version) -> &mut Dependency {
364-
let me = Rc::make_mut(&mut self.inner);
364+
let me = Arc::make_mut(&mut self.inner);
365365
me.req.lock_to(version);
366366
self
367367
}
@@ -430,7 +430,7 @@ impl Dependency {
430430
}
431431

432432
pub(crate) fn set_artifact(&mut self, artifact: Artifact) {
433-
Rc::make_mut(&mut self.inner).artifact = Some(artifact);
433+
Arc::make_mut(&mut self.inner).artifact = Some(artifact);
434434
}
435435

436436
pub(crate) fn artifact(&self) -> Option<&Artifact> {
@@ -453,7 +453,7 @@ impl Dependency {
453453
/// This information represents a requirement in the package this dependency refers to.
454454
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
455455
pub struct Artifact {
456-
inner: Rc<Vec<ArtifactKind>>,
456+
inner: Arc<Vec<ArtifactKind>>,
457457
is_lib: bool,
458458
target: Option<ArtifactTarget>,
459459
}
@@ -492,7 +492,7 @@ impl Artifact {
492492
.collect::<Result<Vec<_>, _>>()?,
493493
)?;
494494
Ok(Artifact {
495-
inner: Rc::new(kinds),
495+
inner: Arc::new(kinds),
496496
is_lib,
497497
target: target.map(ArtifactTarget::parse).transpose()?,
498498
})

src/cargo/core/summary.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ use std::collections::{BTreeMap, HashMap, HashSet};
99
use std::fmt;
1010
use std::hash::{Hash, Hasher};
1111
use std::mem;
12-
use std::rc::Rc;
12+
use std::sync::Arc;
1313

1414
/// Subset of a `Manifest`. Contains only the most important information about
1515
/// a package.
1616
///
1717
/// Summaries are cloned, and should not be mutated after creation
1818
#[derive(Debug, Clone)]
1919
pub struct Summary {
20-
inner: Rc<Inner>,
20+
inner: Arc<Inner>,
2121
}
2222

2323
#[derive(Debug, Clone)]
2424
struct Inner {
2525
package_id: PackageId,
2626
dependencies: Vec<Dependency>,
27-
features: Rc<FeatureMap>,
27+
features: Arc<FeatureMap>,
2828
checksum: Option<String>,
2929
links: Option<InternedString>,
3030
rust_version: Option<RustVersion>,
@@ -82,10 +82,10 @@ impl Summary {
8282
}
8383
let feature_map = build_feature_map(features, &dependencies)?;
8484
Ok(Summary {
85-
inner: Rc::new(Inner {
85+
inner: Arc::new(Inner {
8686
package_id: pkg_id,
8787
dependencies,
88-
features: Rc::new(feature_map),
88+
features: Arc::new(feature_map),
8989
checksum: None,
9090
links: links.map(|l| l.into()),
9191
rust_version,
@@ -124,12 +124,12 @@ impl Summary {
124124
}
125125

126126
pub fn override_id(mut self, id: PackageId) -> Summary {
127-
Rc::make_mut(&mut self.inner).package_id = id;
127+
Arc::make_mut(&mut self.inner).package_id = id;
128128
self
129129
}
130130

131131
pub fn set_checksum(&mut self, cksum: String) {
132-
Rc::make_mut(&mut self.inner).checksum = Some(cksum);
132+
Arc::make_mut(&mut self.inner).checksum = Some(cksum);
133133
}
134134

135135
pub fn map_dependencies<F>(self, mut f: F) -> Summary
@@ -144,7 +144,7 @@ impl Summary {
144144
F: FnMut(Dependency) -> CargoResult<Dependency>,
145145
{
146146
{
147-
let slot = &mut Rc::make_mut(&mut self.inner).dependencies;
147+
let slot = &mut Arc::make_mut(&mut self.inner).dependencies;
148148
*slot = mem::take(slot)
149149
.into_iter()
150150
.map(f)
@@ -178,6 +178,12 @@ impl Hash for Summary {
178178
}
179179
}
180180

181+
// A check that only compiles if Summary is Sync
182+
const _: fn() = || {
183+
fn is_sync<T: Sync>() {}
184+
is_sync::<Summary>();
185+
};
186+
181187
/// Checks features for errors, bailing out a CargoResult:Err if invalid,
182188
/// and creates FeatureValues for each feature.
183189
fn build_feature_map(

0 commit comments

Comments
 (0)