2727import org .commonjava .indy .data .ArtifactStoreQuery ;
2828import org .commonjava .indy .model .core .ArtifactStore ;
2929import org .commonjava .indy .model .core .StoreKey ;
30+ import org .commonjava .indy .promote .conf .PromoteConfig ;
3031import org .commonjava .indy .promote .validate .model .ValidationRequest ;
3132import org .commonjava .indy .util .LocationUtils ;
3233import org .commonjava .atlas .maven .graph .rel .ProjectRelationship ;
@@ -112,6 +113,9 @@ public class PromotionValidationTools
112113 @ Inject
113114 private ContentDigester contentDigester ;
114115
116+ @ Inject
117+ private PromoteConfig promoteConfig ;
118+
115119 @ Inject
116120 @ WeftManaged
117121 @ ExecutorConfig ( named = "promote-validation-rules-executor" , threads = 8 )
@@ -124,7 +128,8 @@ protected PromotionValidationTools()
124128 public PromotionValidationTools ( final ContentManager manager , final StoreDataManager storeDataManager ,
125129 final MavenPomReader pomReader , final MavenMetadataReader metadataReader ,
126130 final MavenModelProcessor modelProcessor , final TypeMapper typeMapper ,
127- final TransferManager transferManager , final ContentDigester contentDigester )
131+ final TransferManager transferManager , final ContentDigester contentDigester ,
132+ final Executor ruleParallelExecutor , final PromoteConfig config )
128133 {
129134 contentManager = manager ;
130135 this .storeDataManager = storeDataManager ;
@@ -134,6 +139,8 @@ public PromotionValidationTools( final ContentManager manager, final StoreDataMa
134139 this .typeMapper = typeMapper ;
135140 this .transferManager = transferManager ;
136141 this .contentDigester = contentDigester ;
142+ this .ruleParallelExecutor = ruleParallelExecutor ;
143+ this .promoteConfig = config ;
137144 }
138145
139146 public StoreKey [] getValidationStoreKeys ( final ValidationRequest request , final boolean includeSource )
@@ -561,6 +568,72 @@ public <K, V> void paralleledEach( Map<K, V> map, Closure closure )
561568 runParallelAndWait ( entries , closure , logger );
562569 }
563570
571+ public <T > void paralleledInBatch ( Collection <T > collection , Closure closure )
572+ {
573+ int batchSize = promoteConfig .getParalleledBatchSize ();
574+ logger .trace ( "Exe parallel on collection {} with closure {} in batch {}" , collection , closure , batchSize );
575+ Collection <Collection <T >> batches = batch ( collection , batchSize );
576+ runParallelInBatchAndWait ( batches , closure , logger );
577+ }
578+
579+ public <T > void paralleledInBatch ( T [] array , Closure closure )
580+ {
581+ int batchSize = promoteConfig .getParalleledBatchSize ();
582+ logger .trace ( "Exe parallel on array {} with closure {} in batch {}" , array , closure , batchSize );
583+ Collection <Collection <T >> batches = batch ( Arrays .asList ( array ), batchSize );
584+ runParallelInBatchAndWait ( batches , closure , logger );
585+ }
586+
587+ public <K , V > void paralleledInBatch ( Map <K , V > map , Closure closure )
588+ {
589+ int batchSize = promoteConfig .getParalleledBatchSize ();
590+ Set <Map .Entry <K , V >> entries = map .entrySet ();
591+ logger .trace ( "Exe parallel on map {} with closure {} in batch {}" , entries , closure , batchSize );
592+ Collection <Collection <Map .Entry <K , V >>> batches = batch ( entries , batchSize );
593+ runParallelInBatchAndWait ( batches , closure , logger );
594+ }
595+
596+ private <T > void runParallelInBatchAndWait ( Collection <Collection <T >> batches , Closure closure , Logger logger )
597+ {
598+ final CountDownLatch latch = new CountDownLatch ( batches .size () );
599+ batches .forEach ( batch -> ruleParallelExecutor .execute ( () -> {
600+ try
601+ {
602+ logger .trace ( "The paralleled exe on batch {}" , batch );
603+ batch .forEach ( e -> closure .call ( e ) );
604+ }
605+ finally
606+ {
607+ latch .countDown ();
608+ }
609+ } ) );
610+
611+ waitForCompletion ( latch );
612+ }
613+
614+ private <T > Collection <Collection <T >> batch ( Collection <T > collection , int batchSize )
615+ {
616+ Collection <Collection <T >> batches = new ArrayList <>();
617+ Collection <T > batch = new ArrayList <>( batchSize );
618+ int count = 0 ;
619+ for ( T t : collection )
620+ {
621+ ( (ArrayList <T >) batch ).add ( t );
622+ count ++;
623+ if ( count >= batchSize )
624+ {
625+ ( (ArrayList <Collection <T >>) batches ).add ( batch );
626+ batch = new ArrayList <>( batchSize );
627+ count = 0 ;
628+ }
629+ }
630+ if ( batch != null && !batch .isEmpty () )
631+ {
632+ ( (ArrayList <Collection <T >>) batches ).add ( batch ); // first batch
633+ }
634+ return batches ;
635+ }
636+
564637 private <T > void runParallelAndWait ( Collection <T > runCollection , Closure closure , Logger logger )
565638 {
566639 Set <T > todo = new HashSet <>( runCollection );
@@ -577,6 +650,11 @@ private <T> void runParallelAndWait( Collection<T> runCollection, Closure closur
577650 }
578651 } ) );
579652
653+ waitForCompletion ( latch );
654+ }
655+
656+ private void waitForCompletion ( CountDownLatch latch )
657+ {
580658 try
581659 {
582660 // true if the count reached zero and false if timeout
0 commit comments