34
34
import net .sf .json .JSONObject ;
35
35
36
36
import org .apache .commons .lang .StringUtils ;
37
+ import org .jenkins .plugins .lockableresources .queue .LockableResourcesCandidatesStruct ;
37
38
import org .jenkins .plugins .lockableresources .queue .LockableResourcesStruct ;
38
39
import org .jenkinsci .plugins .scriptsecurity .sandbox .groovy .SecureGroovyScript ;
39
40
import org .jenkins .plugins .lockableresources .queue .QueuedContextStruct ;
@@ -638,9 +639,9 @@ public boolean configure(StaplerRequest req, JSONObject json)
638
639
public synchronized Set <LockableResource > checkResourcesAvailability (List <LockableResourcesStruct > requiredResourcesList ,
639
640
@ Nullable PrintStream logger , @ Nullable List <String > lockedResourcesAboutToBeUnlocked ) {
640
641
641
- // Build possible resources for each requirement
642
- Map <List <LockableResource >, Integer > allCandidates = new HashMap <>();
642
+ List <LockableResourcesCandidatesStruct > requiredResourcesCandidatesList = new ArrayList <>();
643
643
644
+ // Build possible resources for each requirement
644
645
for (LockableResourcesStruct requiredResources : requiredResourcesList ) {
645
646
// get possible resources
646
647
int requiredAmount = 0 ; // 0 means all
@@ -662,25 +663,21 @@ public synchronized Set<LockableResource> checkResourcesAvailability(List<Lockab
662
663
requiredAmount = candidates .size ();
663
664
}
664
665
665
- allCandidates . put ( candidates , requiredAmount );
666
+ requiredResourcesCandidatesList . add ( new LockableResourcesCandidatesStruct ( candidates , requiredAmount ) );
666
667
}
667
668
668
669
// Process freed resources
669
- Map <Map .Entry <List <LockableResource >, Integer >, List <LockableResource >> currentSelection = new HashMap <>();
670
670
int totalSelected = 0 ;
671
671
672
- for (Map .Entry <List <LockableResource >, Integer > entry : allCandidates .entrySet ()) {
673
- List <LockableResource > candidates = entry .getKey ();
674
- int requiredAmount = entry .getValue ();
675
-
672
+ for (LockableResourcesCandidatesStruct requiredResources : requiredResourcesCandidatesList ) {
676
673
// start with an empty set of selected resources
677
674
List <LockableResource > selected = new ArrayList <LockableResource >();
678
675
679
676
// some resources might be already locked, but will be freed.
680
677
// Determine if these resources can be reused
681
678
if (lockedResourcesAboutToBeUnlocked != null ) {
682
- for (LockableResource candidate : candidates ) {
683
- if (selected .size () >= requiredAmount ) {
679
+ for (LockableResource candidate : requiredResources . candidates ) {
680
+ if (selected .size () >= requiredResources . requiredAmount ) {
684
681
break ;
685
682
}
686
683
if (lockedResourcesAboutToBeUnlocked .contains (candidate .getName ())) {
@@ -690,7 +687,7 @@ public synchronized Set<LockableResource> checkResourcesAvailability(List<Lockab
690
687
}
691
688
692
689
totalSelected += selected .size ();
693
- currentSelection . put ( entry , selected ) ;
690
+ requiredResources . selected = selected ;
694
691
}
695
692
696
693
// if none of the currently locked resources can be reused,
@@ -702,11 +699,24 @@ public synchronized Set<LockableResource> checkResourcesAvailability(List<Lockab
702
699
// Find remaining resources
703
700
Set <LockableResource > allSelected = new HashSet <>();
704
701
705
- for (Map .Entry <Map .Entry <List <LockableResource >, Integer >, List <LockableResource >> entry : currentSelection .entrySet ()) {
706
- List <LockableResource > candidates = entry .getKey ().getKey ();
707
- List <LockableResource > selected = entry .getValue ();
708
- int requiredAmount = entry .getKey ().getValue ();
702
+ for (LockableResourcesCandidatesStruct requiredResources : requiredResourcesCandidatesList ) {
703
+ List <LockableResource > candidates = requiredResources .candidates ;
704
+ List <LockableResource > selected = requiredResources .selected ;
705
+ int requiredAmount = requiredResources .requiredAmount ;
706
+
707
+ // Try and re-use as many previously selected resources first
708
+ List <LockableResource > alreadySelectedCandidates = new ArrayList <>(candidates );
709
+ alreadySelectedCandidates .retainAll (allSelected );
710
+ for (LockableResource rs : alreadySelectedCandidates ) {
711
+ if (selected .size () >= requiredAmount ) {
712
+ break ;
713
+ }
714
+ if (!rs .isReserved () && !rs .isLocked ()) {
715
+ selected .add (rs );
716
+ }
717
+ }
709
718
719
+ candidates .removeAll (alreadySelectedCandidates );
710
720
for (LockableResource rs : candidates ) {
711
721
if (selected .size () >= requiredAmount ) {
712
722
break ;
0 commit comments