From 415de752a6af7bb9833980ee1ec26d2bc4054bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Petrovick=C3=BD?= Date: Tue, 17 Dec 2024 09:53:59 +0100 Subject: [PATCH] perf: reduce the LocationInList allocation rate (#1277) Although the actual move evaluation speed increase is small (~ 3 %), the allocation rate drops substantially. --- .../domain/variable/ListVariableState.java | 130 +++++++++++++----- .../placer/entity/PooledEntityPlacerTest.java | 2 +- .../heuristic/selector/SelectorTestUtils.java | 2 +- .../move/MoveSelectorFactoryTest.java | 30 ++-- .../CartesianProductMoveSelectorTest.java | 42 +++--- .../move/composite/UnionMoveSelectorTest.java | 24 ++-- .../decorator/CachingMoveSelectorTest.java | 4 +- .../decorator/FilteringMoveSelectorTest.java | 2 +- .../ProbabilityMoveSelectorTest.java | 2 +- .../SelectedCountLimitMoveSelectorTest.java | 4 +- .../decorator/ShufflingMoveSelectorTest.java | 2 +- .../decorator/SortingMoveSelectorTest.java | 2 +- .../domain/list/TestdataListUtils.java | 6 - 13 files changed, 150 insertions(+), 102 deletions(-) diff --git a/core/src/main/java/ai/timefold/solver/core/impl/domain/variable/ListVariableState.java b/core/src/main/java/ai/timefold/solver/core/impl/domain/variable/ListVariableState.java index 9708dea8a1..fa3687e085 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/domain/variable/ListVariableState.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/domain/variable/ListVariableState.java @@ -2,7 +2,6 @@ import java.util.List; import java.util.Map; -import java.util.Objects; import ai.timefold.solver.core.impl.domain.variable.descriptor.ListVariableDescriptor; import ai.timefold.solver.core.impl.domain.variable.index.IndexShadowVariableDescriptor; @@ -26,7 +25,7 @@ final class ListVariableState { private boolean requiresLocationMap = true; private InnerScoreDirector scoreDirector; private int unassignedCount = 0; - private Map elementLocationMap; + private Map elementLocationMap; public ListVariableState(ListVariableDescriptor sourceVariableDescriptor) { this.sourceVariableDescriptor = sourceVariableDescriptor; @@ -69,8 +68,7 @@ public void initialize(InnerScoreDirector scoreDirector, int initi public void addElement(Object entity, List elements, Object element, int index) { if (requiresLocationMap) { - var location = ElementLocation.of(entity, index); - var oldLocation = elementLocationMap.put(element, location); + var oldLocation = elementLocationMap.put(element, new MutableLocationInList(entity, index)); if (oldLocation != null) { throw new IllegalStateException( "The supply for list variable (%s) is corrupted, because the element (%s) at index (%d) already exists (%s)." @@ -100,7 +98,7 @@ public void removeElement(Object entity, Object element, int index) { "The supply for list variable (%s) is corrupted, because the element (%s) at index (%d) was already unassigned (%s)." .formatted(sourceVariableDescriptor, element, index, oldElementLocation)); } - var oldIndex = oldElementLocation.index(); + var oldIndex = oldElementLocation.getIndex(); if (oldIndex != index) { throw new IllegalStateException( "The supply for list variable (%s) is corrupted, because the element (%s) at index (%d) had an old index (%d) which is not the current index (%d)." @@ -168,13 +166,22 @@ public boolean changeElement(Object entity, List elements, int index) { private ChangeType processElementLocation(Object entity, Object element, int index) { if (requiresLocationMap) { // Update the location and figure out if it is different from previous. - var newLocation = ElementLocation.of(entity, index); - var oldLocation = elementLocationMap.put(element, newLocation); + var oldLocation = elementLocationMap.get(element); if (oldLocation == null) { + elementLocationMap.put(element, new MutableLocationInList(entity, index)); unassignedCount--; return ChangeType.BOTH; } - return compareLocations(entity, oldLocation.entity(), index, oldLocation.index()); + var changeType = compareLocations(entity, oldLocation.getEntity(), index, oldLocation.getIndex()); + if (changeType.anythingChanged) { // Replace the map value in-place, to avoid a put() on the hot path. + if (changeType.entityChanged) { + oldLocation.setEntity(entity); + } + if (changeType.indexChanged) { + oldLocation.setIndex(index); + } + } + return changeType; } else { // Read the location and figure out if it is different from previous. var oldEntity = getInverseSingleton(element); if (oldEntity == null) { @@ -199,27 +206,13 @@ private static ChangeType compareLocations(Object entity, Object otherEntity, in } } - private enum ChangeType { - - BOTH(true, true), - INDEX(false, true), - NEITHER(false, false); - - final boolean anythingChanged; - final boolean entityChanged; - final boolean indexChanged; - - ChangeType(boolean entityChanged, boolean indexChanged) { - this.anythingChanged = entityChanged || indexChanged; - this.entityChanged = entityChanged; - this.indexChanged = indexChanged; - } - - } - public ElementLocation getLocationInList(Object planningValue) { if (requiresLocationMap) { - return Objects.requireNonNullElse(elementLocationMap.get(planningValue), ElementLocation.unassigned()); + var mutableLocationInList = elementLocationMap.get(planningValue); + if (mutableLocationInList == null) { + return ElementLocation.unassigned(); + } + return mutableLocationInList.getLocationInList(); } else { // At this point, both inverse and index are externalized. var inverse = externalizedInverseProcessor.getInverseSingleton(planningValue); if (inverse == null) { @@ -235,7 +228,7 @@ public Integer getIndex(Object planningValue) { if (elementLocation == null) { return null; } - return elementLocation.index(); + return elementLocation.getIndex(); } return externalizedIndexProcessor.getIndex(planningValue); } @@ -246,34 +239,35 @@ public Object getInverseSingleton(Object planningValue) { if (elementLocation == null) { return null; } - return elementLocation.entity(); + return elementLocation.getEntity(); } return externalizedInverseProcessor.getInverseSingleton(planningValue); } public Object getPreviousElement(Object element) { if (externalizedPreviousElementProcessor == null) { - var elementLocation = getLocationInList(element); - if (!(elementLocation instanceof LocationInList locationInList)) { + var mutableLocationInList = elementLocationMap.get(element); + if (mutableLocationInList == null) { return null; } - var index = locationInList.index(); + var index = mutableLocationInList.getIndex(); if (index == 0) { return null; } - return sourceVariableDescriptor.getValue(locationInList.entity()).get(index - 1); + return sourceVariableDescriptor.getValue(mutableLocationInList.getEntity()) + .get(index - 1); } return externalizedPreviousElementProcessor.getElement(element); } public Object getNextElement(Object element) { if (externalizedNextElementProcessor == null) { - var elementLocation = getLocationInList(element); - if (!(elementLocation instanceof LocationInList locationInList)) { + var mutableLocationInList = elementLocationMap.get(element); + if (mutableLocationInList == null) { return null; } - var list = sourceVariableDescriptor.getValue(locationInList.entity()); - var index = locationInList.index(); + var list = sourceVariableDescriptor.getValue(mutableLocationInList.getEntity()); + var index = mutableLocationInList.getIndex(); if (index == list.size() - 1) { return null; } @@ -286,4 +280,66 @@ public int getUnassignedCount() { return unassignedCount; } + private enum ChangeType { + + BOTH(true, true), + INDEX(false, true), + NEITHER(false, false); + + final boolean anythingChanged; + final boolean entityChanged; + final boolean indexChanged; + + ChangeType(boolean entityChanged, boolean indexChanged) { + this.anythingChanged = entityChanged || indexChanged; + this.entityChanged = entityChanged; + this.indexChanged = indexChanged; + } + + } + + /** + * This class is used to avoid creating a new {@link LocationInList} object every time we need to return a location. + * The actual value is held in a map and can be updated without doing a put() operation, which is more efficient. + * The {@link LocationInList} object is only created when it is actually requested, + * and stored until the next time the mutable state is updated and therefore the cache invalidated. + */ + private static final class MutableLocationInList { + + private Object entity; + private int index; + private LocationInList locationInList; + + public MutableLocationInList(Object entity, int index) { + this.entity = entity; + this.index = index; + } + + public Object getEntity() { + return entity; + } + + public void setEntity(Object entity) { + this.entity = entity; + this.locationInList = null; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + this.locationInList = null; + } + + public LocationInList getLocationInList() { + if (locationInList == null) { + locationInList = ElementLocation.of(entity, index); + } + return locationInList; + } + + } + } diff --git a/core/src/test/java/ai/timefold/solver/core/impl/constructionheuristic/placer/entity/PooledEntityPlacerTest.java b/core/src/test/java/ai/timefold/solver/core/impl/constructionheuristic/placer/entity/PooledEntityPlacerTest.java index e36e4a1d4a..ca997bb7dc 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/constructionheuristic/placer/entity/PooledEntityPlacerTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/constructionheuristic/placer/entity/PooledEntityPlacerTest.java @@ -24,7 +24,7 @@ class PooledEntityPlacerTest { @Test void oneMoveSelector() { - MoveSelector moveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector moveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("b1")); PooledEntityPlacer placer = new PooledEntityPlacer<>(moveSelector); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java index 1ce5bda653..137577c52a 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java @@ -187,7 +187,7 @@ public static MimicReplayingSubListSelector mockReplaying } @SafeVarargs - public static MoveSelector mockMoveSelector(Class moveClass, Move... moves) { + public static MoveSelector mockMoveSelector(Move... moves) { MoveSelector moveSelector = mock(MoveSelector.class); final List> moveList = Arrays.asList(moves); when(moveSelector.iterator()).thenAnswer(invocation -> moveList.iterator()); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/MoveSelectorFactoryTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/MoveSelectorFactoryTest.java index c24415394d..bdea9b99cf 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/MoveSelectorFactoryTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/MoveSelectorFactoryTest.java @@ -1,7 +1,6 @@ package ai.timefold.solver.core.impl.heuristic.selector.move; import static ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicyTestUtils.buildHeuristicConfigPolicy; -import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; @@ -14,7 +13,6 @@ import ai.timefold.solver.core.config.heuristic.selector.common.decorator.SelectionSorterOrder; import ai.timefold.solver.core.config.heuristic.selector.move.MoveSelectorConfig; import ai.timefold.solver.core.impl.heuristic.HeuristicConfigPolicy; -import ai.timefold.solver.core.impl.heuristic.move.DummyMove; import ai.timefold.solver.core.impl.heuristic.move.Move; import ai.timefold.solver.core.impl.heuristic.selector.SelectorTestUtils; import ai.timefold.solver.core.impl.heuristic.selector.common.decorator.SelectionProbabilityWeightFactory; @@ -32,7 +30,7 @@ class MoveSelectorFactoryTest { @Test void phaseOriginal() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setCacheType(SelectionCacheType.PHASE); moveSelectorConfig.setSelectionOrder(SelectionOrder.ORIGINAL); @@ -50,7 +48,7 @@ void phaseOriginal() { @Test void stepOriginal() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setCacheType(SelectionCacheType.STEP); moveSelectorConfig.setSelectionOrder(SelectionOrder.ORIGINAL); @@ -68,7 +66,7 @@ void stepOriginal() { @Test void justInTimeOriginal() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.JUST_IN_TIME, false); @@ -82,7 +80,7 @@ void justInTimeOriginal() { @Test void phaseRandom() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.PHASE, false); @@ -100,7 +98,7 @@ void phaseRandom() { @Test void stepRandom() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.STEP, false); @@ -118,7 +116,7 @@ void stepRandom() { @Test void justInTimeRandom() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.JUST_IN_TIME, true); @@ -132,7 +130,7 @@ void justInTimeRandom() { @Test void phaseShuffled() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.PHASE, false); @@ -149,7 +147,7 @@ void phaseShuffled() { @Test void stepShuffled() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new AssertingMoveSelectorFactory(moveSelectorConfig, baseMoveSelector, SelectionCacheType.STEP, false); @@ -165,7 +163,7 @@ void stepShuffled() { @Test void justInTimeShuffled() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setCacheType(SelectionCacheType.JUST_IN_TIME); moveSelectorConfig.setSelectionOrder(SelectionOrder.SHUFFLED); @@ -179,7 +177,7 @@ void justInTimeShuffled() { @Test void validateSorting_incompatibleSelectionOrder() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setSorterOrder(SelectionSorterOrder.ASCENDING); @@ -190,7 +188,7 @@ void validateSorting_incompatibleSelectionOrder() { @Test void applySorting_withoutAnySortingClass() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setSorterOrder(SelectionSorterOrder.ASCENDING); @@ -203,7 +201,7 @@ void applySorting_withoutAnySortingClass() { @Test void applySorting_withSorterComparatorClass() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setSorterOrder(SelectionSorterOrder.ASCENDING); moveSelectorConfig.setSorterComparatorClass(DummyComparator.class); @@ -216,7 +214,7 @@ void applySorting_withSorterComparatorClass() { @Test void applyProbability_withProbabilityWeightFactoryClass() { - final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class); + final MoveSelector baseMoveSelector = SelectorTestUtils.mockMoveSelector(); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); moveSelectorConfig.setCacheType(SelectionCacheType.PHASE); moveSelectorConfig.setProbabilityWeightFactoryClass(DummySelectionProbabilityWeightFactory.class); @@ -241,7 +239,7 @@ public Move doMove(ScoreDirector scoreDirect } }; final MoveSelector baseMoveSelector = - SelectorTestUtils.mockMoveSelector(DummyMove.class, notDoableMove); + SelectorTestUtils.mockMoveSelector(notDoableMove); DummyMoveSelectorConfig moveSelectorConfig = new DummyMoveSelectorConfig(); MoveSelectorFactory moveSelectorFactory = new DummyMoveSelectorFactory(moveSelectorConfig, baseMoveSelector); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/CartesianProductMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/CartesianProductMoveSelectorTest.java index 7d0cf112e8..093b5d0274 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/CartesianProductMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/CartesianProductMoveSelectorTest.java @@ -42,9 +42,9 @@ void originSelectionIgnoringEmpty() { public void originSelection(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, false); @@ -103,14 +103,14 @@ void emptyAllOriginSelectionIgnoringEmpty() { public void emptyOriginSelection(boolean ignoreEmptyChildIterators, boolean emptyFirst, boolean emptySecond) { assertThat(emptyFirst || emptySecond).isTrue(); - MoveSelector nonEmptyChildMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector nonEmptyChildMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")); // One side is not empty ArrayList childMoveSelectorList = new ArrayList<>(); childMoveSelectorList.add(emptyFirst - ? SelectorTestUtils.mockMoveSelector(DummyMove.class) + ? SelectorTestUtils.mockMoveSelector() : nonEmptyChildMoveSelector); childMoveSelectorList.add(emptySecond - ? SelectorTestUtils.mockMoveSelector(DummyMove.class) + ? SelectorTestUtils.mockMoveSelector() : nonEmptyChildMoveSelector); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, false); @@ -150,11 +150,11 @@ void originSelection3ChildMoveSelectorsIgnoringEmpty() { public void originSelection3ChildMoveSelectors(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("c1"), new DummyMove("c2"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, false); @@ -192,10 +192,10 @@ void emptyOriginSelection3ChildMoveSelectorsIgnoringEmpty() { public void emptyOriginSelection3ChildMoveSelectors(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("c1"), new DummyMove("c2"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, false); @@ -236,9 +236,9 @@ void classicRandomSelectionIgnoringEmpty() { public void classicRandomSelection(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, true); @@ -274,8 +274,8 @@ void emptyRandomSelectionIgnoringEmpty() { public void emptyRandomSelection(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); // One side is not empty CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, true); @@ -315,11 +315,11 @@ void randomSelection3ChildMoveSelectorsIgnoringEmpty() { public void randomSelection3ChildMoveSelectors(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("c1"), new DummyMove("c2"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, true); @@ -355,10 +355,10 @@ void emptyRandomSelection3ChildMoveSelectorsIgnoringEmpty() { public void emptyRandomSelection3ChildMoveSelectors(boolean ignoreEmptyChildIterators) { ArrayList childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("c1"), new DummyMove("c2"), new DummyMove("c3"))); CartesianProductMoveSelector moveSelector = new CartesianProductMoveSelector(childMoveSelectorList, ignoreEmptyChildIterators, true); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java index 9ab1503d9c..ab24b5f229 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java @@ -28,9 +28,9 @@ class UnionMoveSelectorTest { @Test void originSelection() { ArrayList> childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"))); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); UnionMoveSelector moveSelector = new UnionMoveSelector<>(childMoveSelectorList, false); @@ -57,8 +57,8 @@ void originSelection() { @Test void emptyOriginSelection() { ArrayList> childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); UnionMoveSelector moveSelector = new UnionMoveSelector<>(childMoveSelectorList, false); @@ -85,10 +85,10 @@ void emptyOriginSelection() { void biasedRandomSelection() { ArrayList> childMoveSelectorList = new ArrayList<>(); Map, Double> fixedProbabilityWeightMap = new HashMap<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"))); fixedProbabilityWeightMap.put(childMoveSelectorList.get(0), 1000.0); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class, + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector( new DummyMove("b1"), new DummyMove("b2"))); fixedProbabilityWeightMap.put(childMoveSelectorList.get(1), 20.0); UnionMoveSelector moveSelector = @@ -123,9 +123,9 @@ void biasedRandomSelection() { @Test void uniformRandomSelection() { List> childMoveSelectorList = List.of( - SelectorTestUtils.mockMoveSelector(DummyMove.class, new DummyMove("a1"), new DummyMove("a2"), + SelectorTestUtils.mockMoveSelector(new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")), - SelectorTestUtils.mockMoveSelector(DummyMove.class, new DummyMove("b1"), new DummyMove("b2"))); + SelectorTestUtils.mockMoveSelector(new DummyMove("b1"), new DummyMove("b2"))); UnionMoveSelector moveSelector = new UnionMoveSelector<>(childMoveSelectorList, true, null); @@ -152,8 +152,8 @@ void uniformRandomSelection() { @Test void emptyUniformRandomSelection() { ArrayList> childMoveSelectorList = new ArrayList<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); UnionMoveSelector moveSelector = new UnionMoveSelector<>(childMoveSelectorList, true, null); @@ -182,9 +182,9 @@ void emptyUniformRandomSelection() { void emptyBiasedRandomSelection() { ArrayList> childMoveSelectorList = new ArrayList<>(); Map, Double> fixedProbabilityWeightMap = new HashMap<>(); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); fixedProbabilityWeightMap.put(childMoveSelectorList.get(0), 1000.0); - childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector(DummyMove.class)); + childMoveSelectorList.add(SelectorTestUtils.mockMoveSelector()); fixedProbabilityWeightMap.put(childMoveSelectorList.get(1), 20.0); UnionMoveSelector moveSelector = new UnionMoveSelector<>(childMoveSelectorList, true, diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java index 74085f2b0a..75a4a7b4d9 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java @@ -38,7 +38,7 @@ void originalSelectionCacheTypeStep() { } public void runOriginalSelection(SelectionCacheType cacheType, int timesCalled) { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")); CachingMoveSelector moveSelector = new CachingMoveSelector(childMoveSelector, cacheType, false); @@ -112,7 +112,7 @@ void randomSelectionCacheTypeStep() { } public void runRandomSelection(SelectionCacheType cacheType, int timesCalled) { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")); CachingMoveSelector moveSelector = new CachingMoveSelector(childMoveSelector, cacheType, true); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/FilteringMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/FilteringMoveSelectorTest.java index 5e8a7806c2..51d926186d 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/FilteringMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/FilteringMoveSelectorTest.java @@ -42,7 +42,7 @@ void filterCacheTypeJustInTime() { } public void filter(SelectionCacheType cacheType, int timesCalled) { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"), new DummyMove("a4")); SelectionFilter filter = (scoreDirector, move) -> !move.getCode().equals("a3"); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java index fa842065c7..191404a66a 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java @@ -27,7 +27,7 @@ class ProbabilityMoveSelectorTest { @Test void randomSelection() { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("e1"), new DummyMove("e2"), new DummyMove("e3"), new DummyMove("e4")); SelectionProbabilityWeightFactory probabilityWeightFactory = diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SelectedCountLimitMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SelectedCountLimitMoveSelectorTest.java index 10e5b78e8a..6f75f37a1d 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SelectedCountLimitMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SelectedCountLimitMoveSelectorTest.java @@ -20,7 +20,7 @@ class SelectedCountLimitMoveSelectorTest { @Test void selectSizeLimitLowerThanSelectorSize() { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"), new DummyMove("a4"), new DummyMove("a5")); MoveSelector moveSelector = new SelectedCountLimitMoveSelector(childMoveSelector, 3L); @@ -78,7 +78,7 @@ void selectSizeLimitLowerThanSelectorSize() { @Test void selectSizeLimitHigherThanSelectorSize() { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")); MoveSelector moveSelector = new SelectedCountLimitMoveSelector(childMoveSelector, 5L); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java index d3e4141522..3d5d12bff1 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java @@ -37,7 +37,7 @@ void cacheTypeStep() { } public void run(SelectionCacheType cacheType, int timesCalled) { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3")); ShufflingMoveSelector moveSelector = new ShufflingMoveSelector(childMoveSelector, cacheType); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SortingMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SortingMoveSelectorTest.java index 6f9c79599f..44210475ab 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SortingMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/SortingMoveSelectorTest.java @@ -45,7 +45,7 @@ void cacheTypeJustInTime() { } public void runCacheType(SelectionCacheType cacheType, int timesCalled) { - MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector(DummyMove.class, + MoveSelector childMoveSelector = SelectorTestUtils.mockMoveSelector( new DummyMove("jan"), new DummyMove("feb"), new DummyMove("mar"), new DummyMove("apr"), new DummyMove("may"), new DummyMove("jun")); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/testdata/domain/list/TestdataListUtils.java b/core/src/test/java/ai/timefold/solver/core/impl/testdata/domain/list/TestdataListUtils.java index 8166c1985d..4a02a29ebf 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/testdata/domain/list/TestdataListUtils.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/testdata/domain/list/TestdataListUtils.java @@ -59,12 +59,6 @@ public static EntitySelector mockEntitySelector(TestdataLi (Object[]) entities); } - public static EntitySelector - mockNeverEndingEntitySelector(TestdataPinnedUnassignedValuesListEntity... entities) { - return SelectorTestUtils.mockEntitySelector(TestdataPinnedUnassignedValuesListEntity.buildEntityDescriptor(), - (Object[]) entities); - } - public static EntityIndependentValueSelector mockEntityIndependentValueSelector( ListVariableDescriptor listVariableDescriptor, Object... values) { return SelectorTestUtils.mockEntityIndependentValueSelector(listVariableDescriptor, values);