1
- use std:: cell:: RefCell ;
2
1
use std:: collections:: HashMap ;
3
2
4
3
use core:: { Source , SourceId , SourceMap , Summary , Dependency , PackageId } ;
@@ -53,10 +52,7 @@ impl<'a, T: ?Sized + Registry + 'a> Registry for Box<T> {
53
52
/// a `Source`. Each `Source` in the map has been updated (using network
54
53
/// operations if necessary) and is ready to be queried for packages.
55
54
pub struct PackageRegistry < ' cfg > {
56
- // Note that in general we don't have interior mutability but the
57
- // implementation of `query` below necessitates the need for this `RefCell`,
58
- // see comments there for more.
59
- sources : RefCell < SourceMap < ' cfg > > ,
55
+ sources : SourceMap < ' cfg > ,
60
56
61
57
// A list of sources which are considered "overrides" which take precedent
62
58
// when querying for packages.
@@ -79,10 +75,12 @@ pub struct PackageRegistry<'cfg> {
79
75
// what exactly the key is.
80
76
source_ids : HashMap < SourceId , ( SourceId , Kind ) > ,
81
77
82
- locked : HashMap < SourceId , HashMap < String , Vec < ( PackageId , Vec < PackageId > ) > > > ,
78
+ locked : LockedMap ,
83
79
source_config : SourceConfigMap < ' cfg > ,
84
80
}
85
81
82
+ type LockedMap = HashMap < SourceId , HashMap < String , Vec < ( PackageId , Vec < PackageId > ) > > > ;
83
+
86
84
#[ derive( PartialEq , Eq , Clone , Copy ) ]
87
85
enum Kind {
88
86
Override ,
@@ -94,7 +92,7 @@ impl<'cfg> PackageRegistry<'cfg> {
94
92
pub fn new ( config : & ' cfg Config ) -> CargoResult < PackageRegistry < ' cfg > > {
95
93
let source_config = SourceConfigMap :: new ( config) ?;
96
94
Ok ( PackageRegistry {
97
- sources : RefCell :: new ( SourceMap :: new ( ) ) ,
95
+ sources : SourceMap :: new ( ) ,
98
96
source_ids : HashMap :: new ( ) ,
99
97
overrides : Vec :: new ( ) ,
100
98
source_config : source_config,
@@ -103,9 +101,8 @@ impl<'cfg> PackageRegistry<'cfg> {
103
101
}
104
102
105
103
pub fn get ( self , package_ids : & [ PackageId ] ) -> PackageSet < ' cfg > {
106
- let sources = self . sources . into_inner ( ) ;
107
- trace ! ( "getting packages; sources={}" , sources. len( ) ) ;
108
- PackageSet :: new ( package_ids, sources)
104
+ trace ! ( "getting packages; sources={}" , self . sources. len( ) ) ;
105
+ PackageSet :: new ( package_ids, self . sources )
109
106
}
110
107
111
108
fn ensure_loaded ( & mut self , namespace : & SourceId , kind : Kind ) -> CargoResult < ( ) > {
@@ -157,7 +154,7 @@ impl<'cfg> PackageRegistry<'cfg> {
157
154
158
155
fn add_source ( & mut self , source : Box < Source + ' cfg > , kind : Kind ) {
159
156
let id = source. source_id ( ) . clone ( ) ;
160
- self . sources . get_mut ( ) . insert ( source) ;
157
+ self . sources . insert ( source) ;
161
158
self . source_ids . insert ( id. clone ( ) , ( id, kind) ) ;
162
159
}
163
160
@@ -190,14 +187,14 @@ impl<'cfg> PackageRegistry<'cfg> {
190
187
191
188
// Ensure the source has fetched all necessary remote data.
192
189
let _p = profile:: start ( format ! ( "updating: {}" , source_id) ) ;
193
- self . sources . get_mut ( ) . get_mut ( source_id) . unwrap ( ) . update ( )
190
+ self . sources . get_mut ( source_id) . unwrap ( ) . update ( )
194
191
} ) ( ) . chain_err ( || format ! ( "Unable to update {}" , source_id) )
195
192
}
196
193
197
194
fn query_overrides ( & mut self , dep : & Dependency )
198
195
-> CargoResult < Option < Summary > > {
199
196
for s in self . overrides . iter ( ) {
200
- let src = self . sources . get_mut ( ) . get_mut ( s) . unwrap ( ) ;
197
+ let src = self . sources . get_mut ( s) . unwrap ( ) ;
201
198
let dep = Dependency :: new_override ( dep. name ( ) , s) ;
202
199
let mut results = src. query_vec ( & dep) ?;
203
200
if results. len ( ) > 0 {
@@ -225,71 +222,7 @@ impl<'cfg> PackageRegistry<'cfg> {
225
222
/// possible. If we're unable to map a dependency though, we just pass it on
226
223
/// through.
227
224
pub fn lock ( & self , summary : Summary ) -> Summary {
228
- let pair = self . locked . get ( summary. source_id ( ) ) . and_then ( |map| {
229
- map. get ( summary. name ( ) )
230
- } ) . and_then ( |vec| {
231
- vec. iter ( ) . find ( |& & ( ref id, _) | id == summary. package_id ( ) )
232
- } ) ;
233
-
234
- trace ! ( "locking summary of {}" , summary. package_id( ) ) ;
235
-
236
- // Lock the summary's id if possible
237
- let summary = match pair {
238
- Some ( & ( ref precise, _) ) => summary. override_id ( precise. clone ( ) ) ,
239
- None => summary,
240
- } ;
241
- summary. map_dependencies ( |mut dep| {
242
- trace ! ( "\t {}/{}/{}" , dep. name( ) , dep. version_req( ) ,
243
- dep. source_id( ) ) ;
244
-
245
- // If we've got a known set of overrides for this summary, then
246
- // one of a few cases can arise:
247
- //
248
- // 1. We have a lock entry for this dependency from the same
249
- // source as it's listed as coming from. In this case we make
250
- // sure to lock to precisely the given package id.
251
- //
252
- // 2. We have a lock entry for this dependency, but it's from a
253
- // different source than what's listed, or the version
254
- // requirement has changed. In this case we must discard the
255
- // locked version because the dependency needs to be
256
- // re-resolved.
257
- //
258
- // 3. We don't have a lock entry for this dependency, in which
259
- // case it was likely an optional dependency which wasn't
260
- // included previously so we just pass it through anyway.
261
- //
262
- // Cases 1/2 are handled by `matches_id` and case 3 is handled by
263
- // falling through to the logic below.
264
- if let Some ( & ( _, ref locked_deps) ) = pair {
265
- let locked = locked_deps. iter ( ) . find ( |id| dep. matches_id ( id) ) ;
266
- if let Some ( locked) = locked {
267
- trace ! ( "\t first hit on {}" , locked) ;
268
- dep. lock_to ( locked) ;
269
- return dep
270
- }
271
- }
272
-
273
- // If this dependency did not have a locked version, then we query
274
- // all known locked packages to see if they match this dependency.
275
- // If anything does then we lock it to that and move on.
276
- let v = self . locked . get ( dep. source_id ( ) ) . and_then ( |map| {
277
- map. get ( dep. name ( ) )
278
- } ) . and_then ( |vec| {
279
- vec. iter ( ) . find ( |& & ( ref id, _) | dep. matches_id ( id) )
280
- } ) ;
281
- match v {
282
- Some ( & ( ref id, _) ) => {
283
- trace ! ( "\t second hit on {}" , id) ;
284
- dep. lock_to ( id) ;
285
- return dep
286
- }
287
- None => {
288
- trace ! ( "\t remaining unlocked" ) ;
289
- dep
290
- }
291
- }
292
- } )
225
+ lock ( & self . locked , summary)
293
226
}
294
227
295
228
fn warn_bad_override ( & self ,
@@ -347,42 +280,34 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
347
280
on `{}`", dep. name( ) )
348
281
} ) ?;
349
282
350
- // Look for an override and get ready to query the real source.
351
- //
352
- // Note that we're not using `&mut self` to load `self.sources` here but
353
- // rather we're going through `RefCell::borrow_mut`. This is currently
354
- // done to have access to both the `lock` function and the
355
- // `warn_bad_override` functions we call below.
356
- let override_summary = self . query_overrides ( & dep) ?;
357
- let mut sources = self . sources . borrow_mut ( ) ;
358
- let source = match sources. get_mut ( dep. source_id ( ) ) {
359
- Some ( src) => src,
360
- None => {
361
- if override_summary. is_some ( ) {
362
- bail ! ( "override found but no real ones" ) ;
363
- }
364
- return Ok ( ( ) )
365
- }
366
- } ;
367
283
368
- let ( override_summary, n, to_warn) = match override_summary {
369
- // If we have an override summary then we query the source to sanity
370
- // check its results. We don't actually use any of the summaries it
371
- // gives us though.
372
- Some ( s) => {
373
- let mut n = 0 ;
374
- let mut to_warn = None ;
375
- source. query ( dep, & mut |summary| {
376
- n += 1 ;
377
- to_warn = Some ( summary) ;
378
- } ) ?;
379
- ( s, n, to_warn)
380
- }
284
+ let ( override_summary, n, to_warn) = {
285
+ // Look for an override and get ready to query the real source.
286
+ let override_summary = self . query_overrides ( & dep) ?;
287
+ let source = self . sources . get_mut ( dep. source_id ( ) ) ;
288
+ match ( override_summary, source) {
289
+ ( Some ( _) , None ) => bail ! ( "override found but no real ones" ) ,
290
+ ( None , None ) => return Ok ( ( ) ) ,
381
291
382
- // If we don't have an override then we just ship everything
383
- // upstairs after locking the summary
384
- None => {
385
- return source. query ( dep, & mut |summary| f ( self . lock ( summary) ) )
292
+ // If we don't have an override then we just ship everything
293
+ // upstairs after locking the summary
294
+ ( None , Some ( source) ) => {
295
+ let locked = & self . locked ;
296
+ return source. query ( dep, & mut |summary| f ( lock ( locked, summary) ) )
297
+ }
298
+
299
+ // If we have an override summary then we query the source to sanity
300
+ // check its results. We don't actually use any of the summaries it
301
+ // gives us though.
302
+ ( Some ( override_summary) , Some ( source) ) => {
303
+ let mut n = 0 ;
304
+ let mut to_warn = None ;
305
+ source. query ( dep, & mut |summary| {
306
+ n += 1 ;
307
+ to_warn = Some ( summary) ;
308
+ } ) ?;
309
+ ( override_summary, n, to_warn)
310
+ }
386
311
}
387
312
} ;
388
313
@@ -396,6 +321,74 @@ impl<'cfg> Registry for PackageRegistry<'cfg> {
396
321
}
397
322
}
398
323
324
+ fn lock ( locked : & LockedMap , summary : Summary ) -> Summary {
325
+ let pair = locked. get ( summary. source_id ( ) ) . and_then ( |map| {
326
+ map. get ( summary. name ( ) )
327
+ } ) . and_then ( |vec| {
328
+ vec. iter ( ) . find ( |& & ( ref id, _) | id == summary. package_id ( ) )
329
+ } ) ;
330
+
331
+ trace ! ( "locking summary of {}" , summary. package_id( ) ) ;
332
+
333
+ // Lock the summary's id if possible
334
+ let summary = match pair {
335
+ Some ( & ( ref precise, _) ) => summary. override_id ( precise. clone ( ) ) ,
336
+ None => summary,
337
+ } ;
338
+ summary. map_dependencies ( |mut dep| {
339
+ trace ! ( "\t {}/{}/{}" , dep. name( ) , dep. version_req( ) ,
340
+ dep. source_id( ) ) ;
341
+
342
+ // If we've got a known set of overrides for this summary, then
343
+ // one of a few cases can arise:
344
+ //
345
+ // 1. We have a lock entry for this dependency from the same
346
+ // source as it's listed as coming from. In this case we make
347
+ // sure to lock to precisely the given package id.
348
+ //
349
+ // 2. We have a lock entry for this dependency, but it's from a
350
+ // different source than what's listed, or the version
351
+ // requirement has changed. In this case we must discard the
352
+ // locked version because the dependency needs to be
353
+ // re-resolved.
354
+ //
355
+ // 3. We don't have a lock entry for this dependency, in which
356
+ // case it was likely an optional dependency which wasn't
357
+ // included previously so we just pass it through anyway.
358
+ //
359
+ // Cases 1/2 are handled by `matches_id` and case 3 is handled by
360
+ // falling through to the logic below.
361
+ if let Some ( & ( _, ref locked_deps) ) = pair {
362
+ let locked = locked_deps. iter ( ) . find ( |id| dep. matches_id ( id) ) ;
363
+ if let Some ( locked) = locked {
364
+ trace ! ( "\t first hit on {}" , locked) ;
365
+ dep. lock_to ( locked) ;
366
+ return dep
367
+ }
368
+ }
369
+
370
+ // If this dependency did not have a locked version, then we query
371
+ // all known locked packages to see if they match this dependency.
372
+ // If anything does then we lock it to that and move on.
373
+ let v = locked. get ( dep. source_id ( ) ) . and_then ( |map| {
374
+ map. get ( dep. name ( ) )
375
+ } ) . and_then ( |vec| {
376
+ vec. iter ( ) . find ( |& & ( ref id, _) | dep. matches_id ( id) )
377
+ } ) ;
378
+ match v {
379
+ Some ( & ( ref id, _) ) => {
380
+ trace ! ( "\t second hit on {}" , id) ;
381
+ dep. lock_to ( id) ;
382
+ return dep
383
+ }
384
+ None => {
385
+ trace ! ( "\t remaining unlocked" ) ;
386
+ dep
387
+ }
388
+ }
389
+ } )
390
+ }
391
+
399
392
#[ cfg( test) ]
400
393
pub mod test {
401
394
use core:: { Summary , Registry , Dependency } ;
0 commit comments