Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public interface Sequence<Value_, Difference_ extends Comparable<Difference_>> {
Break<Value_, Difference_> getNextBreak();

/**
* @return items in this sequence
* @return items in this sequence;
* must not be modified by the caller.
*/
@NonNull
Collection<Value_> getItems();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
public interface SequenceChain<Value_, Difference_ extends Comparable<Difference_>> {

/**
* @return the sequences contained in the collection in ascending order.
* @return the sequences contained in the collection in ascending order;
* must not be modified by the caller.
*/
@NonNull
Collection<Sequence<Value_, Difference_>> getConsecutiveSequences();

/**
* @return the breaks contained in the collection in ascending order.
* @return the breaks contained in the collection in ascending order;
* must not be modified by the caller.
*/
@NonNull
Collection<Break<Value_, Difference_>> getBreaks();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ai.timefold.solver.core.impl.score.stream.collector;

import java.util.Objects;
import java.util.function.BinaryOperator;
import java.util.function.ToIntFunction;

import ai.timefold.solver.core.api.score.stream.common.SequenceChain;
Expand All @@ -9,19 +10,19 @@
public final class SequenceCalculator<Result_>
implements ObjectCalculator<Result_, SequenceChain<Result_, Integer>, Result_> {

private final ConsecutiveSetTree<Result_, Integer, Integer> context = new ConsecutiveSetTree<>(
(Integer a, Integer b) -> b - a,
Integer::sum, 1, 0);
private final static BinaryOperator<Integer> DIFFERENCE = (a, b) -> b - a;

private final ToIntFunction<Result_> indexMap;
private final ConsecutiveSetTree<Result_, Integer, Integer> context =
new ConsecutiveSetTree<>(DIFFERENCE, Integer::sum, 1, 0);
private final ToIntFunction<Result_> toIndexFunction;

public SequenceCalculator(ToIntFunction<Result_> indexMap) {
this.indexMap = Objects.requireNonNull(indexMap);
public SequenceCalculator(ToIntFunction<Result_> toIndexFunction) {
this.toIndexFunction = Objects.requireNonNull(toIndexFunction);
}

@Override
public Result_ insert(Result_ result) {
var value = indexMap.applyAsInt(result);
var value = toIndexFunction.applyAsInt(result);
context.add(result, value);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.TreeMap;
import java.util.TreeSet;

import org.jspecify.annotations.NullMarked;

/**
* Each {@link #value()} is associated with a point ({@link #index()}) on the number line.
* Comparisons are made using the points on the number line, not the actual values.
Expand All @@ -18,6 +20,7 @@
* @param <Value_> generic type of the value
* @param <Point_> generic type of the point on the number line
*/
@NullMarked
record ComparableValue<Value_, Point_ extends Comparable<Point_>>(Value_ value, Point_ index)
implements
Comparable<ComparableValue<Value_, Point_>> {
Expand All @@ -27,15 +30,12 @@ public int compareTo(ComparableValue<Value_, Point_> other) {
if (this == other) {
return 0;
}
Point_ point1 = this.index;
Point_ point2 = other.index;
if (point1 != point2) {
int comparison = point1.compareTo(point2);
if (comparison != 0) {
return comparison;
}
var point1 = index;
var point2 = other.index;
if (point1 == point2) {
return compareWithIdentityHashCode(value, other.value);
}
return compareWithIdentityHashCode(this.value, other.value);
return point1.compareTo(point2);
}

private int compareWithIdentityHashCode(Value_ o1, Value_ o2) {
Expand All @@ -44,8 +44,8 @@ private int compareWithIdentityHashCode(Value_ o1, Value_ o2) {
}
// Identity Hashcode for duplicate protection; we must always include duplicates.
// Ex: two different games on the same time slot
int identityHashCode1 = System.identityHashCode(o1);
int identityHashCode2 = System.identityHashCode(o2);
var identityHashCode1 = System.identityHashCode(o1);
var identityHashCode2 = System.identityHashCode(o2);
return Integer.compare(identityHashCode1, identityHashCode2);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ai.timefold.solver.core.impl.score.stream.collector.consecutive;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NavigableMap;
Expand Down Expand Up @@ -55,14 +54,16 @@ public ConsecutiveSetTree(BiFunction<Point_, Point_, Difference_> differenceFunc
this.zeroDifference = zeroDifference;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public @NonNull Collection<Sequence<Value_, Difference_>> getConsecutiveSequences() {
return Collections.unmodifiableCollection(startItemToSequence.values());
return (Collection) startItemToSequence.values();
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public @NonNull Collection<Break<Value_, Difference_>> getBreaks() {
return Collections.unmodifiableCollection(startItemToPreviousBreak.values());
return (Collection) startItemToPreviousBreak.values();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ai.timefold.solver.core.impl.score.stream.collector.consecutive;

import java.util.Collection;
import java.util.Collections;
import java.util.NavigableMap;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -79,8 +78,7 @@ public boolean isLast() {
if (items == null) {
return items = getComparableItems().values();
}
return Collections.unmodifiableCollection(items);

return items;
}

NavigableMap<ComparableValue<Value_, Point_>, Value_> getComparableItems() {
Expand Down
17 changes: 17 additions & 0 deletions core/src/main/java/ai/timefold/solver/core/impl/util/Pair.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ai.timefold.solver.core.impl.util;

import java.util.Objects;

/**
* An immutable key-value tuple.
* Two instances {@link Object#equals(Object) are equal} if both values in the first instance
Expand All @@ -10,4 +12,19 @@
*/
public record Pair<Key_, Value_>(Key_ key, Value_ value) {

@Override
public boolean equals(Object o) {
return o instanceof Pair<?, ?> other
&& Objects.equals(key, other.key)
&& Objects.equals(value, other.value);
}

@Override
public int hashCode() { // Often used in hash-based collections; the JDK-generated default is too slow.
var hash = 7;
hash = 31 * hash + Objects.hashCode(key);
hash = 31 * hash + Objects.hashCode(value);
return hash;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ai.timefold.solver.core.impl.util;

import java.util.Objects;

/**
* An immutable tuple of four values.
* Two instances {@link Object#equals(Object) are equal} if all four values in the first instance
Expand All @@ -12,4 +14,23 @@
*/
public record Quadruple<A, B, C, D>(A a, B b, C c, D d) {

@Override
public boolean equals(Object o) {
return o instanceof Quadruple<?, ?, ?, ?> other
&& Objects.equals(a, other.a)
&& Objects.equals(b, other.b)
&& Objects.equals(c, other.c)
&& Objects.equals(d, other.d);
}

@Override
public int hashCode() { // Often used in hash-based collections; the JDK-generated default is too slow.
var hash = 7;
hash = 31 * hash + Objects.hashCode(a);
hash = 31 * hash + Objects.hashCode(b);
hash = 31 * hash + Objects.hashCode(c);
hash = 31 * hash + Objects.hashCode(d);
return hash;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ai.timefold.solver.core.impl.util;

import java.util.Objects;

/**
* An immutable tuple of three values.
* Two instances {@link Object#equals(Object) are equal} if all three values in the first instance
Expand All @@ -11,4 +13,21 @@
*/
public record Triple<A, B, C>(A a, B b, C c) {

@Override
public boolean equals(Object o) {
return o instanceof Triple<?, ?, ?> other
&& Objects.equals(a, other.a)
&& Objects.equals(b, other.b)
&& Objects.equals(c, other.c);
}

@Override
public int hashCode() { // Often used in hash-based collections; the JDK-generated default is too slow.
var hash = 7;
hash = 31 * hash + Objects.hashCode(a);
hash = 31 * hash + Objects.hashCode(b);
hash = 31 * hash + Objects.hashCode(c);
return hash;
}

}
Loading