@@ -28,11 +28,13 @@ const GraphHelpers = require("./GraphHelpers");
2828
2929/**
3030 * @typedef {Object } ChunkGroupInfo
31+ * @property {ChunkGroup } chunkGroup the chunk group
3132 * @property {Set<Module> } minAvailableModules current minimal set of modules available at this point
3233 * @property {boolean } minAvailableModulesOwned true, if minAvailableModules is owned and can be modified
3334 * @property {Set<Module>[] } availableModulesToBeMerged enqueued updates to the minimal set of available modules
3435 * @property {QueueItem[] } skippedItems queue items that were skipped because module is already available in parent chunks (need to reconsider when minAvailableModules is shrinking)
3536 * @property {Set<Module> } resultingAvailableModules set of modules available including modules from this chunk group
37+ * @property {Set<ChunkGroup> } children set of children chunk groups, that will be revisited when availableModules shrink
3638 */
3739
3840/**
@@ -196,11 +198,13 @@ const visitModules = (
196198 } ) ;
197199 }
198200 chunkGroupInfoMap . set ( chunkGroup , {
201+ chunkGroup,
199202 minAvailableModules : new Set ( ) ,
200203 minAvailableModulesOwned : true ,
201204 availableModulesToBeMerged : [ ] ,
202205 skippedItems : [ ] ,
203- resultingAvailableModules : undefined
206+ resultingAvailableModules : undefined ,
207+ children : undefined
204208 } ) ;
205209 return queue ;
206210 } ;
@@ -418,7 +422,7 @@ const visitModules = (
418422 }
419423 logger . timeEnd ( "visiting" ) ;
420424
421- if ( queueConnect . size > 0 ) {
425+ while ( queueConnect . size > 0 ) {
422426 logger . time ( "calculating available modules" ) ;
423427
424428 // Figure out new parents for chunk groups
@@ -435,17 +439,26 @@ const visitModules = (
435439 }
436440 }
437441 info . resultingAvailableModules = resultingAvailableModules ;
442+ if ( info . children === undefined ) {
443+ info . children = targets ;
444+ } else {
445+ for ( const target of targets ) {
446+ info . children . add ( target ) ;
447+ }
448+ }
438449
439450 // 2. Update chunk group info
440451 for ( const target of targets ) {
441452 let chunkGroupInfo = chunkGroupInfoMap . get ( target ) ;
442453 if ( chunkGroupInfo === undefined ) {
443454 chunkGroupInfo = {
455+ chunkGroup : target ,
444456 minAvailableModules : undefined ,
445457 minAvailableModulesOwned : undefined ,
446458 availableModulesToBeMerged : [ ] ,
447459 skippedItems : [ ] ,
448- resultingAvailableModules : undefined
460+ resultingAvailableModules : undefined ,
461+ children : undefined
449462 } ;
450463 chunkGroupInfoMap . set ( target , chunkGroupInfo ) ;
451464 }
@@ -463,7 +476,7 @@ const visitModules = (
463476 // Execute the merge
464477 for ( const info of outdatedChunkGroupInfo ) {
465478 const availableModulesToBeMerged = info . availableModulesToBeMerged ;
466- let minAvailableModules = info . minAvailableModules ;
479+ let cachedMinAvailableModules = info . minAvailableModules ;
467480
468481 // 1. Get minimal available modules
469482 // It doesn't make sense to traverse a chunk again with more available modules.
@@ -474,29 +487,31 @@ const visitModules = (
474487 }
475488 let changed = false ;
476489 for ( const availableModules of availableModulesToBeMerged ) {
477- if ( minAvailableModules === undefined ) {
478- minAvailableModules = availableModules ;
479- info . minAvailableModules = minAvailableModules ;
490+ if ( cachedMinAvailableModules === undefined ) {
491+ cachedMinAvailableModules = availableModules ;
492+ info . minAvailableModules = cachedMinAvailableModules ;
480493 info . minAvailableModulesOwned = false ;
481494 changed = true ;
482495 } else {
483496 if ( info . minAvailableModulesOwned ) {
484497 // We own it and can modify it
485- for ( const m of minAvailableModules ) {
498+ for ( const m of cachedMinAvailableModules ) {
486499 if ( ! availableModules . has ( m ) ) {
487- minAvailableModules . delete ( m ) ;
500+ cachedMinAvailableModules . delete ( m ) ;
488501 changed = true ;
489502 }
490503 }
491504 } else {
492- for ( const m of minAvailableModules ) {
505+ for ( const m of cachedMinAvailableModules ) {
493506 if ( ! availableModules . has ( m ) ) {
494- // minAvailableModules need to be modified
507+ // cachedMinAvailableModules need to be modified
495508 // but we don't own it
496- // construct a new Set as intersection of minAvailableModules and availableModules
509+ // construct a new Set as intersection of cachedMinAvailableModules and availableModules
497510 /** @type {Set<Module> } */
498511 const newSet = new Set ( ) ;
499- const iterator = minAvailableModules [ Symbol . iterator ] ( ) ;
512+ const iterator = cachedMinAvailableModules [
513+ Symbol . iterator
514+ ] ( ) ;
500515 /** @type {IteratorResult<Module> } */
501516 let it ;
502517 while ( ! ( it = iterator . next ( ) ) . done ) {
@@ -510,9 +525,16 @@ const visitModules = (
510525 newSet . add ( module ) ;
511526 }
512527 }
513- minAvailableModules = newSet ;
528+ cachedMinAvailableModules = newSet ;
514529 info . minAvailableModulesOwned = true ;
515530 info . minAvailableModules = newSet ;
531+
532+ // Update the cache from the first queue
533+ // if the chunkGroup is currently cached
534+ if ( chunkGroup === info . chunkGroup ) {
535+ minAvailableModules = cachedMinAvailableModules ;
536+ }
537+
516538 changed = true ;
517539 break ;
518540 }
@@ -528,6 +550,19 @@ const visitModules = (
528550 queue . push ( queueItem ) ;
529551 }
530552 info . skippedItems . length = 0 ;
553+
554+ // 3. Reconsider children chunk groups
555+ if ( info . children !== undefined ) {
556+ const chunkGroup = info . chunkGroup ;
557+ for ( const c of info . children ) {
558+ let connectList = queueConnect . get ( chunkGroup ) ;
559+ if ( connectList === undefined ) {
560+ connectList = new Set ( ) ;
561+ queueConnect . set ( chunkGroup , connectList ) ;
562+ }
563+ connectList . add ( c ) ;
564+ }
565+ }
531566 }
532567 outdatedChunkGroupInfo . clear ( ) ;
533568 logger . timeEnd ( "merging available modules" ) ;
0 commit comments