11// SPDX-License-Identifier: MPL-2.0
22
33use std:: cell:: RefCell ;
4+ use std:: collections:: BTreeMap ;
5+ use std:: fmt:: { Debug , Display } ;
6+ use std:: hash:: Hash ;
47
5- use pubgrub:: { resolve, Dependencies , DependencyProvider , OfflineDependencyProvider , Ranges } ;
8+ use pubgrub:: {
9+ resolve, Dependencies , DependencyConstraints , DependencyProvider , Map ,
10+ OfflineDependencyProvider , PackageArena , PackageId , Ranges ,
11+ } ;
612
713type NumVS = Ranges < u32 > ;
14+ type CachedDeps < V , VS > = RefCell < Map < PackageId , BTreeMap < V , DependencyConstraints < VS > > > > ;
815
916// An example implementing caching dependency provider that will
1017// store queried dependencies in memory and check them before querying more from remote.
11- struct CachingDependencyProvider < DP : DependencyProvider > {
18+ struct CachingDependencyProvider < DP : DependencyProvider >
19+ where
20+ DP :: P : Debug + Display + Clone + Eq + Hash ,
21+ {
1222 remote_dependencies : DP ,
13- cached_dependencies : RefCell < OfflineDependencyProvider < DP :: P , DP :: VS > > ,
23+ cached_dependencies : CachedDeps < DP :: V , DP :: VS > ,
1424}
1525
16- impl < DP : DependencyProvider > CachingDependencyProvider < DP > {
26+ impl < DP : DependencyProvider > CachingDependencyProvider < DP >
27+ where
28+ DP :: P : Debug + Display + Clone + Eq + Hash ,
29+ {
1730 pub fn new ( remote_dependencies_provider : DP ) -> Self {
1831 CachingDependencyProvider {
1932 remote_dependencies : remote_dependencies_provider,
20- cached_dependencies : RefCell :: new ( OfflineDependencyProvider :: new ( ) ) ,
33+ cached_dependencies : Default :: default ( ) ,
2134 }
2235 }
2336}
2437
25- impl < DP : DependencyProvider < M = String > > DependencyProvider for CachingDependencyProvider < DP > {
26- // Caches dependencies if they were already queried
38+ impl < DP : DependencyProvider < M = & ' static str > > DependencyProvider for CachingDependencyProvider < DP >
39+ where
40+ DP :: P : Debug + Display + Clone + Eq + Hash ,
41+ {
42+ // Cache dependencies if they were already queried
2743 fn get_dependencies (
28- & self ,
29- package : & DP :: P ,
44+ & mut self ,
45+ package_id : PackageId ,
3046 version : & DP :: V ,
31- ) -> Result < Dependencies < DP :: P , DP :: VS , DP :: M > , DP :: Err > {
47+ package_store : & mut PackageArena < Self :: P > ,
48+ ) -> Result < Dependencies < DP :: VS , DP :: M > , DP :: Err > {
3249 let mut cache = self . cached_dependencies . borrow_mut ( ) ;
33- match cache. get_dependencies ( package, version) {
34- Ok ( Dependencies :: Unavailable ( _) ) => {
35- let dependencies = self . remote_dependencies . get_dependencies ( package, version) ;
36- match dependencies {
37- Ok ( Dependencies :: Available ( dependencies) ) => {
38- cache. add_dependencies (
39- package. clone ( ) ,
40- version. clone ( ) ,
41- dependencies. clone ( ) ,
42- ) ;
43- Ok ( Dependencies :: Available ( dependencies) )
44- }
45- Ok ( Dependencies :: Unavailable ( reason) ) => Ok ( Dependencies :: Unavailable ( reason) ) ,
46- error @ Err ( _) => error,
47- }
50+ if let Some ( deps) = cache. get ( & package_id) . and_then ( |vmap| vmap. get ( version) ) {
51+ return Ok ( Dependencies :: Available ( deps. clone ( ) ) ) ;
52+ }
53+
54+ match self
55+ . remote_dependencies
56+ . get_dependencies ( package_id, version, package_store)
57+ {
58+ Ok ( Dependencies :: Available ( deps) ) => {
59+ cache
60+ . entry ( package_id)
61+ . or_default ( )
62+ . insert ( version. clone ( ) , deps. clone ( ) ) ;
63+ Ok ( Dependencies :: Available ( deps) )
4864 }
49- Ok ( dependencies) => Ok ( dependencies) ,
50- Err ( _) => unreachable ! ( ) ,
65+
66+ Ok ( Dependencies :: Unavailable ( reason) ) => Ok ( Dependencies :: Unavailable ( reason) ) ,
67+ error @ Err ( _) => error,
5168 }
5269 }
5370
54- fn choose_version ( & self , package : & DP :: P , ranges : & DP :: VS ) -> Result < Option < DP :: V > , DP :: Err > {
55- self . remote_dependencies . choose_version ( package, ranges)
71+ fn choose_version (
72+ & mut self ,
73+ package_id : PackageId ,
74+ ranges : & DP :: VS ,
75+ package_store : & PackageArena < Self :: P > ,
76+ ) -> Result < Option < DP :: V > , DP :: Err > {
77+ self . remote_dependencies
78+ . choose_version ( package_id, ranges, package_store)
5679 }
5780
5881 type Priority = DP :: Priority ;
5982
60- fn prioritize ( & self , package : & DP :: P , ranges : & DP :: VS ) -> Self :: Priority {
61- self . remote_dependencies . prioritize ( package, ranges)
83+ fn prioritize (
84+ & mut self ,
85+ package_id : PackageId ,
86+ ranges : & DP :: VS ,
87+ package_store : & PackageArena < Self :: P > ,
88+ ) -> Self :: Priority {
89+ self . remote_dependencies
90+ . prioritize ( package_id, ranges, package_store)
6291 }
6392
6493 type Err = DP :: Err ;
@@ -76,9 +105,9 @@ fn main() {
76105 // Add dependencies as needed. Here only root package is added.
77106 remote_dependencies_provider. add_dependencies ( "root" , 1u32 , Vec :: new ( ) ) ;
78107
79- let caching_dependencies_provider =
108+ let mut caching_dependencies_provider =
80109 CachingDependencyProvider :: new ( remote_dependencies_provider) ;
81110
82- let solution = resolve ( & caching_dependencies_provider, "root" , 1u32 ) ;
111+ let solution = resolve ( & mut caching_dependencies_provider, "root" , 1u32 ) ;
83112 println ! ( "Solution: {:?}" , solution) ;
84113}
0 commit comments