1
1
package ai .timefold .solver .core .impl .score .director ;
2
2
3
+ import java .util .Arrays ;
3
4
import java .util .Collections ;
4
5
import java .util .IdentityHashMap ;
5
6
import java .util .LinkedHashSet ;
6
- import java .util .List ;
7
7
import java .util .Map ;
8
8
import java .util .Objects ;
9
9
import java .util .Set ;
26
26
import ai .timefold .solver .core .impl .domain .variable .descriptor .ListVariableDescriptor ;
27
27
import ai .timefold .solver .core .impl .domain .variable .descriptor .VariableDescriptor ;
28
28
import ai .timefold .solver .core .impl .heuristic .selector .common .ReachableValues ;
29
- import ai .timefold .solver .core .impl .util .CollectionUtils ;
30
29
import ai .timefold .solver .core .impl .util .MathUtils ;
31
30
import ai .timefold .solver .core .impl .util .MutableInt ;
32
31
import ai .timefold .solver .core .impl .util .MutableLong ;
58
57
public final class ValueRangeManager <Solution_ > {
59
58
60
59
private final SolutionDescriptor <Solution_ > solutionDescriptor ;
61
- private final List < CountableValueRange <?>> fromSolutionList ;
62
- private final Map <Object , List < CountableValueRange <?>> > fromEntityMap =
60
+ private final CountableValueRange <?>[] fromSolutionList ;
61
+ private final Map <Object , CountableValueRange <?>[] > fromEntityMap =
63
62
new IdentityHashMap <>();
64
63
private @ Nullable ReachableValues reachableValues = null ;
65
64
@@ -82,7 +81,7 @@ public static <Solution_> ValueRangeManager<Solution_> of(SolutionDescriptor<Sol
82
81
*/
83
82
public ValueRangeManager (SolutionDescriptor <Solution_ > solutionDescriptor ) {
84
83
this .solutionDescriptor = Objects .requireNonNull (solutionDescriptor );
85
- this .fromSolutionList = CollectionUtils . newNullList ( solutionDescriptor .getValueRangeDescriptorCount ()) ;
84
+ this .fromSolutionList = new CountableValueRange [ solutionDescriptor .getValueRangeDescriptorCount ()] ;
86
85
}
87
86
88
87
public SolutionInitializationStatistics getInitializationStatistics () {
@@ -357,7 +356,7 @@ public <T> CountableValueRange<T> getFromSolution(ValueRangeDescriptor<Solution_
357
356
@ SuppressWarnings ("unchecked" )
358
357
public <T > CountableValueRange <T > getFromSolution (ValueRangeDescriptor <Solution_ > valueRangeDescriptor ,
359
358
Solution_ solution ) {
360
- var valueRange = fromSolutionList . get ( valueRangeDescriptor .getOrdinal ()) ;
359
+ var valueRange = fromSolutionList [ valueRangeDescriptor .getOrdinal ()] ;
361
360
if (valueRange == null ) { // Avoid computeIfAbsent on the hot path; creates capturing lambda instances.
362
361
var extractedValueRange = valueRangeDescriptor .<T > extractAllValues (Objects .requireNonNull (solution ));
363
362
if (!(extractedValueRange instanceof CountableValueRange <T > countableValueRange )) {
@@ -371,7 +370,7 @@ public <T> CountableValueRange<T> getFromSolution(ValueRangeDescriptor<Solution_
371
370
} else {
372
371
valueRange = countableValueRange ;
373
372
}
374
- fromSolutionList . set ( valueRangeDescriptor .getOrdinal (), valueRange ) ;
373
+ fromSolutionList [ valueRangeDescriptor .getOrdinal ()] = valueRange ;
375
374
}
376
375
return (CountableValueRange <T >) valueRange ;
377
376
}
@@ -388,8 +387,8 @@ public <T> CountableValueRange<T> getFromEntity(ValueRangeDescriptor<Solution_>
388
387
}
389
388
var valueRangeList =
390
389
fromEntityMap .computeIfAbsent (entity ,
391
- e -> CollectionUtils . newNullList ( solutionDescriptor .getValueRangeDescriptorCount ()) );
392
- var valueRange = valueRangeList . get ( valueRangeDescriptor .getOrdinal ()) ;
390
+ e -> new CountableValueRange [ solutionDescriptor .getValueRangeDescriptorCount ()] );
391
+ var valueRange = valueRangeList [ valueRangeDescriptor .getOrdinal ()] ;
393
392
if (valueRange == null ) { // Avoid computeIfAbsent on the hot path; creates capturing lambda instances.
394
393
var extractedValueRange =
395
394
valueRangeDescriptor .<T > extractValuesFromEntity (cachedWorkingSolution , Objects .requireNonNull (entity ));
@@ -404,7 +403,7 @@ public <T> CountableValueRange<T> getFromEntity(ValueRangeDescriptor<Solution_>
404
403
} else {
405
404
valueRange = countableValueRange ;
406
405
}
407
- valueRangeList . set ( valueRangeDescriptor .getOrdinal (), valueRange ) ;
406
+ valueRangeList [ valueRangeDescriptor .getOrdinal ()] = valueRange ;
408
407
}
409
408
return (CountableValueRange <T >) valueRange ;
410
409
}
@@ -483,9 +482,7 @@ private static void updateValueMap(Map<Object, Set<Object>> valueMatrix, Countab
483
482
}
484
483
485
484
public void reset (@ Nullable Solution_ workingSolution ) {
486
- var size = fromSolutionList .size ();
487
- fromSolutionList .clear ();
488
- fromSolutionList .addAll (CollectionUtils .newNullList (size ));
485
+ Arrays .fill (fromSolutionList , null );
489
486
fromEntityMap .clear ();
490
487
reachableValues = null ;
491
488
// We only update the cached solution if it is not null; null means to only reset the maps.
0 commit comments