Skip to content

Commit 22b1135

Browse files
committed
refactor(dependencies): share package using Rc instead of cloning ♻️
Although Rc is used, it is still cloned in dependency::DependencyProvider as it needs to sort the releases
1 parent c4c8340 commit 22b1135

File tree

2 files changed

+28
-18
lines changed

2 files changed

+28
-18
lines changed

compiler-cli/src/dependencies.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{
22
cell::RefCell,
33
collections::{HashMap, HashSet},
4+
rc::Rc,
45
time::Instant,
56
};
67

@@ -1045,7 +1046,7 @@ async fn lookup_package(
10451046
}
10461047

10471048
struct PackageFetcher {
1048-
runtime_cache: RefCell<HashMap<String, hexpm::Package>>,
1049+
runtime_cache: RefCell<HashMap<String, Rc<hexpm::Package>>>,
10491050
runtime: tokio::runtime::Handle,
10501051
http: HttpClient,
10511052
}
@@ -1062,7 +1063,7 @@ impl PackageFetcher {
10621063
/// Caches the result of `get_dependencies` so that we don't need to make a network request.
10631064
/// Currently dependencies are fetched during initial version resolution, and then during check
10641065
/// for major version availability.
1065-
fn cache_package(&self, package: &str, result: hexpm::Package) {
1066+
fn cache_package(&self, package: &str, result: Rc<hexpm::Package>) {
10661067
let mut runtime_cache = self.runtime_cache.borrow_mut();
10671068
let _ = runtime_cache.insert(package.to_string(), result);
10681069
}
@@ -1098,7 +1099,7 @@ impl dependency::PackageFetcher for PackageFetcher {
10981099
fn get_dependencies(
10991100
&self,
11001101
package: &str,
1101-
) -> Result<hexpm::Package, Box<dyn std::error::Error>> {
1102+
) -> Result<Rc<hexpm::Package>, Box<dyn std::error::Error>> {
11021103
{
11031104
let runtime_cache = self.runtime_cache.borrow();
11041105
let result = runtime_cache.get(package);
@@ -1117,9 +1118,11 @@ impl dependency::PackageFetcher for PackageFetcher {
11171118
.map_err(Box::new)?;
11181119

11191120
match hexpm::get_package_response(response, HEXPM_PUBLIC_KEY) {
1120-
Ok(a) => {
1121-
self.cache_package(package, a.clone());
1122-
Ok(a)
1121+
Ok(pkg) => {
1122+
let pkg = Rc::new(pkg);
1123+
let pkg_ref = Rc::clone(&pkg);
1124+
self.cache_package(package, pkg);
1125+
Ok(pkg_ref)
11231126
}
11241127
Err(e) => match e {
11251128
hexpm::ApiError::NotFound => {

compiler-core/src/dependency.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, error::Error as StdError};
1+
use std::{borrow::Borrow, cell::RefCell, collections::HashMap, error::Error as StdError, rc::Rc};
22

33
use crate::{manifest, Error, Result};
44

@@ -197,7 +197,7 @@ but it is locked to {locked_version}, which is incompatible.",
197197
}
198198

199199
pub trait PackageFetcher {
200-
fn get_dependencies(&self, package: &str) -> Result<hexpm::Package, Box<dyn StdError>>;
200+
fn get_dependencies(&self, package: &str) -> Result<Rc<hexpm::Package>, Box<dyn StdError>>;
201201
}
202202

203203
struct DependencyProvider<'a, T: PackageFetcher> {
@@ -247,7 +247,9 @@ where
247247
) -> Result<(), Box<dyn StdError>> {
248248
let mut packages = self.packages.borrow_mut();
249249
if packages.get(name).is_none() {
250-
let mut package = self.remote.get_dependencies(name)?;
250+
let package = self.remote.get_dependencies(name)?;
251+
// mut (therefore clone) is required here in order to sort the releases
252+
let mut package = (*package).clone();
251253
// Sort the packages from newest to oldest, pres after all others
252254
package.releases.sort_by(|a, b| a.version.cmp(&b.version));
253255
package.releases.reverse();
@@ -362,14 +364,14 @@ mod tests {
362364
use super::*;
363365

364366
struct Remote {
365-
deps: HashMap<String, hexpm::Package>,
367+
deps: HashMap<String, Rc<hexpm::Package>>,
366368
}
367369

368370
impl PackageFetcher for Remote {
369-
fn get_dependencies(&self, package: &str) -> Result<hexpm::Package, Box<dyn StdError>> {
371+
fn get_dependencies(&self, package: &str) -> Result<Rc<hexpm::Package>, Box<dyn StdError>> {
370372
self.deps
371373
.get(package)
372-
.cloned()
374+
.map(Rc::clone)
373375
.ok_or(Box::new(hexpm::ApiError::NotFound))
374376
}
375377
}
@@ -411,7 +413,8 @@ mod tests {
411413
meta: (),
412414
},
413415
],
414-
},
416+
}
417+
.into(),
415418
);
416419
let _ = deps.insert(
417420
"gleam_otp".into(),
@@ -484,7 +487,8 @@ mod tests {
484487
meta: (),
485488
},
486489
],
487-
},
490+
}
491+
.into(),
488492
);
489493
let _ = deps.insert(
490494
"package_with_retired".into(),
@@ -510,7 +514,8 @@ mod tests {
510514
meta: (),
511515
},
512516
],
513-
},
517+
}
518+
.into(),
514519
);
515520

516521
let _ = deps.insert(
@@ -534,7 +539,8 @@ mod tests {
534539
outer_checksum: vec![1, 2, 3],
535540
meta: (),
536541
}],
537-
},
542+
}
543+
.into(),
538544
);
539545

540546
let simple_deps_for_major_version_check = vec![
@@ -577,7 +583,7 @@ mod tests {
577583

578584
fn insert_simplified_deps(
579585
simple_deps: Vec<(&str, Vec<(&str, Vec<(&str, &str)>)>)>,
580-
deps: &mut HashMap<String, hexpm::Package>,
586+
deps: &mut HashMap<String, Rc<hexpm::Package>>,
581587
) {
582588
for (name, releases) in simple_deps {
583589
let _ = deps.insert(
@@ -608,7 +614,8 @@ mod tests {
608614
meta: (),
609615
})
610616
.collect(),
611-
},
617+
}
618+
.into(),
612619
);
613620
}
614621
}

0 commit comments

Comments
 (0)