Skip to content

Commit fa34809

Browse files
committed
Another wave
1 parent c4eaa81 commit fa34809

163 files changed

Lines changed: 6202 additions & 2313 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

core/src/main/java/ai/timefold/solver/core/api/score/stream/ConstraintCollectors.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,7 @@ public final class ConstraintCollectors {
767767
* For stable iteration order, use {@link #toSortedSet()}.
768768
* <p>
769769
* The default result of the collector (e.g. when never called) is an empty {@link Set}.
770+
* The user must not modify this set.
770771
*
771772
* @param <A> type of the matched fact
772773
*/
@@ -779,6 +780,7 @@ public final class ConstraintCollectors {
779780
* {@link ConstraintStream}.
780781
* <p>
781782
* The default result of the collector (e.g. when never called) is an empty {@link SortedSet}.
783+
* The user must not modify this set.
782784
*
783785
* @param <A> type of the matched fact
784786
*/
@@ -800,6 +802,7 @@ public final class ConstraintCollectors {
800802
* For stable iteration order, use {@link #toSortedSet()}.
801803
* <p>
802804
* The default result of the collector (e.g. when never called) is an empty {@link List}.
805+
* The user must not modify this list.
803806
*
804807
* @param <A> type of the matched fact
805808
*/
@@ -976,6 +979,7 @@ public final class ConstraintCollectors {
976979
* For stable iteration order, use {@link #toSortedMap(Function, Function, IntFunction)}.
977980
* <p>
978981
* The default result of the collector (e.g. when never called) is an empty {@link Map}.
982+
* The user must not modify this map.
979983
*
980984
* @param keyMapper map matched fact to a map key
981985
* @param valueMapper map matched fact to a value
@@ -1103,6 +1107,7 @@ public final class ConstraintCollectors {
11031107
* {@code {20: "Ann and Eric", 25: "Beth", 30: "Cathy and David"}}.
11041108
* <p>
11051109
* The default result of the collector (e.g. when never called) is an empty {@link SortedMap}.
1110+
* The user must not modify this map.
11061111
*
11071112
* @param keyMapper map matched fact to a map key
11081113
* @param valueMapper map matched fact to a value

core/src/main/java/ai/timefold/solver/core/api/score/stream/uni/UniConstraintCollectorAccumulator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public interface UniConstraintCollectorAccumulator<ResultContainer_, A> {
2323
* {@link UniConstraintCollector#supplier()} will be used to supply a fresh instance of the container;
2424
* otherwise a pre-existing container will be used, carrying the accumulated state.
2525
* {@link UniConstraintCollector#finisher()} will be used to extract the final accumulated value from the container.
26-
* The container is the only state that the accumulator may rely on;
27-
* any other state will result in subtle score corruption issues.
26+
* The accumulator factory itself must not hold mutable cross-slot state;
27+
* any mutable state must live in the container or in the returned accumulated value.
2828
* @return the accumulator for the value, which will be used to insert the value to the group,
2929
* to update it while in the group, and to remove it from the group.
3030
*/

core/src/main/java/ai/timefold/solver/core/impl/bavet/common/index/DefaultUniqueRandomIterator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public boolean hasNext() {
5959
if (nextIndex == -1) {
6060
return false;
6161
}
62-
next = source.get(nextIndex).element();
62+
next = source.get(nextIndex);
6363
indexToOptionallyRemove = -1;
6464
return true;
6565
}

core/src/main/java/ai/timefold/solver/core/impl/bavet/common/index/RandomAccessIndexerBackend.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public final class RandomAccessIndexerBackend<T> implements IndexerBackend<T> {
2424

2525
@Override
2626
public ListEntry<T> put(Object compositeKey, T tuple) {
27-
return tupleList.add(tuple);
27+
return tupleList.addEntry(tuple);
2828
}
2929

3030
@Override

core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void insert(Tuple_ tuple) {
3535
.formatted(tuple));
3636
}
3737

38-
tuple.setStore(entryStoreIndex, tupleList.add(tuple));
38+
tuple.setStore(entryStoreIndex, tupleList.addEntry(tuple));
3939
}
4040

4141
@Override

core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/ConnectedRangesCalculator.java renamed to core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/AbstractConnectedRangesSlot.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
import ai.timefold.solver.core.impl.score.stream.collector.connected_ranges.ConnectedRangeTracker;
88
import ai.timefold.solver.core.impl.score.stream.collector.connected_ranges.Range;
99

10-
public final class ConnectedRangesCalculator<Interval_, Point_ extends Comparable<Point_>, Difference_ extends Comparable<Difference_>>
11-
implements ObjectCalculator<Interval_> {
10+
public abstract class AbstractConnectedRangesSlot<Interval_, Point_ extends Comparable<Point_>, Difference_ extends Comparable<Difference_>> {
1211

1312
public static final class State<Interval_, Point_ extends Comparable<Point_>, Difference_ extends Comparable<Difference_>> {
1413
private final ConnectedRangeTracker<Interval_, Point_, Difference_> context;
@@ -27,26 +26,23 @@ public ConnectedRangeChain<Interval_, Point_, Difference_> result() {
2726
private final State<Interval_, Point_, Difference_> state;
2827
private Range<Interval_, Point_> cachedRange;
2928

30-
public ConnectedRangesCalculator(State<Interval_, Point_, Difference_> state) {
29+
public AbstractConnectedRangesSlot(State<Interval_, Point_, Difference_> state) {
3130
this.state = state;
3231
}
3332

34-
@Override
35-
public void insert(Interval_ result) {
33+
protected void addMapped(Interval_ result) {
3634
final var saved = state.context.getRange(result);
3735
cachedRange = saved;
3836
state.context.add(saved);
3937
}
4038

41-
@Override
42-
public void update(Interval_ input) {
39+
protected void updateMapped(Interval_ input) {
4340
state.context.remove(cachedRange);
4441
cachedRange = state.context.getRange(input);
4542
state.context.add(cachedRange);
4643
}
4744

48-
@Override
49-
public void retract() {
45+
protected void removeMapped() {
5046
state.context.remove(cachedRange);
5147
}
5248
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ai.timefold.solver.core.impl.score.stream.collector;
2+
3+
public abstract class AbstractCountSlot {
4+
5+
public static final class State {
6+
long count = 0;
7+
8+
public Long result() {
9+
return count;
10+
}
11+
}
12+
13+
private final State state;
14+
15+
public AbstractCountSlot(State state) {
16+
this.state = state;
17+
}
18+
19+
protected void addMapped() {
20+
state.count++;
21+
}
22+
23+
protected void updateMapped() {
24+
// count unchanged on update
25+
}
26+
27+
protected void removeMapped() {
28+
state.count--;
29+
}
30+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package ai.timefold.solver.core.impl.score.stream.collector;
2+
3+
import java.util.Objects;
4+
5+
import org.jspecify.annotations.Nullable;
6+
7+
public abstract class AbstractLoadBalanceSlot<Balanced_> {
8+
9+
private final DefaultLoadBalance<Balanced_> container;
10+
private @Nullable Balanced_ cachedBalanced;
11+
private long cachedLoad;
12+
13+
public AbstractLoadBalanceSlot(DefaultLoadBalance<Balanced_> container) {
14+
this.container = container;
15+
}
16+
17+
protected void addMapped(Balanced_ balanced, long load, long initialLoad) {
18+
cachedBalanced = balanced;
19+
cachedLoad = load;
20+
container.registerBalanced(balanced, load, initialLoad);
21+
}
22+
23+
protected void updateMapped(Balanced_ balanced, long load, long initialLoad) {
24+
if (Objects.equals(cachedBalanced, balanced) && cachedLoad == load) {
25+
return;
26+
}
27+
removeMapped();
28+
addMapped(balanced, load, initialLoad);
29+
}
30+
31+
protected void removeMapped() {
32+
container.unregisterBalanced(cachedBalanced, cachedLoad);
33+
}
34+
}

core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/LongAverageCalculator.java renamed to core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/AbstractLongAverageSlot.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package ai.timefold.solver.core.impl.score.stream.collector;
22

3-
public final class LongAverageCalculator implements LongCalculator {
3+
public abstract class AbstractLongAverageSlot {
44

55
public static final class State {
66
long count = 0;
@@ -17,25 +17,22 @@ public Double result() {
1717
private final State state;
1818
private long cachedInput;
1919

20-
public LongAverageCalculator(State state) {
20+
public AbstractLongAverageSlot(State state) {
2121
this.state = state;
2222
}
2323

24-
@Override
25-
public void insert(long input) {
24+
protected void addMapped(long input) {
2625
cachedInput = input;
2726
state.count++;
2827
state.sum += input;
2928
}
3029

31-
@Override
32-
public void update(long input) {
30+
protected void updateMapped(long input) {
3331
state.sum += input - cachedInput;
3432
cachedInput = input;
3533
}
3634

37-
@Override
38-
public void retract() {
35+
protected void removeMapped() {
3936
state.count--;
4037
state.sum -= cachedInput;
4138
}

core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/LongDistinctCountCalculator.java renamed to core/src/main/java/ai/timefold/solver/core/impl/score/stream/collector/AbstractLongDistinctSlot.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import org.jspecify.annotations.Nullable;
1010

11-
public final class LongDistinctCountCalculator<Input_> implements ObjectCalculator<Input_> {
11+
public abstract class AbstractLongDistinctSlot<Input_> {
1212

1313
public static final class State<Input_> {
1414
private final Map<Input_, MutableInt> countMap = new HashMap<>();
@@ -22,28 +22,25 @@ public Long result() {
2222
private @Nullable Input_ cachedInput;
2323
private @Nullable MutableInt cachedCounter;
2424

25-
public LongDistinctCountCalculator(State<Input_> state) {
25+
public AbstractLongDistinctSlot(State<Input_> state) {
2626
this.state = state;
2727
}
2828

29-
@Override
30-
public void insert(Input_ input) {
29+
protected void addMapped(Input_ input) {
3130
cachedInput = input;
3231
cachedCounter = state.countMap.computeIfAbsent(input, ignored -> new MutableInt());
3332
cachedCounter.increment();
3433
}
3534

36-
@Override
37-
public void update(Input_ input) {
35+
protected void updateMapped(Input_ input) {
3836
if (Objects.equals(cachedInput, input)) {
3937
return;
4038
}
41-
retract();
42-
insert(input);
39+
removeMapped();
40+
addMapped(input);
4341
}
4442

45-
@Override
46-
public void retract() {
43+
protected void removeMapped() {
4744
if (cachedCounter.decrement() == 0) {
4845
state.countMap.remove(cachedInput);
4946
}

0 commit comments

Comments
 (0)