Skip to content

Commit

Permalink
Replace Stream API with for loop in ShrinkingDistance with for loops
Browse files Browse the repository at this point in the history
It makes the stacktraces shorter and easier to reason.

See jqwik-team#431
  • Loading branch information
Vladimir Sitnikov committed Dec 14, 2022
1 parent 3de9ca9 commit 4f6274b
Showing 1 changed file with 56 additions and 11 deletions.
67 changes: 56 additions & 11 deletions api/src/main/java/net/jqwik/api/ShrinkingDistance.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.stream.*;

import org.apiguardian.api.*;
import org.jetbrains.annotations.*;

import static org.apiguardian.api.API.Status.*;

Expand All @@ -13,6 +14,8 @@ public class ShrinkingDistance implements Comparable<ShrinkingDistance> {
@API(status = MAINTAINED, since = "1.2.0")
public static final ShrinkingDistance MAX = ShrinkingDistance.of(Long.MAX_VALUE);

private static final ShrinkingDistance MIN = ShrinkingDistance.of(0);

private final long[] distances;

@API(status = MAINTAINED, since = "1.0")
Expand All @@ -22,20 +25,44 @@ public static ShrinkingDistance of(long... distances) {

@API(status = MAINTAINED, since = "1.0")
public static <T> ShrinkingDistance forCollection(Collection<Shrinkable<T>> elements) {
ShrinkingDistance sumDistanceOfElements = elements
.stream()
.map(Shrinkable::distance)
.reduce(ShrinkingDistance.of(0), ShrinkingDistance::plus);
if (elements.isEmpty()) {
return MIN;
}

return ShrinkingDistance.of(elements.size()).append(sumDistanceOfElements);
long[] data = null;
for (Shrinkable<T> element : elements) {
long[] next = element.distance().distances;
if (data == null) {
data = Arrays.copyOf(next, next.length);
continue;
}
data = sumUpArrays(data, data, next);

}
return new ShrinkingDistance(concatArrays(new long[]{elements.size()}, data));
}

@API(status = MAINTAINED, since = "1.0")
public static <T> ShrinkingDistance combine(List<Shrinkable<T>> shrinkables) {
return shrinkables
.stream()
.map(Shrinkable::distance)
.reduce(new ShrinkingDistance(new long[0]), ShrinkingDistance::append);
if (shrinkables.isEmpty()) {
return MIN;
}
// Compute the total size of the required array
List<long[]> distances = new ArrayList<>(shrinkables.size());
int totalLength = 0;
for (Shrinkable<T> shrinkable : shrinkables) {
long[] next = shrinkable.distance().distances;
totalLength += next.length;
distances.add(next);
}
// Append all the arrays together
long[] data = new long[totalLength];
int index = 0;
for (long[] distance : distances) {
System.arraycopy(distance, 0, data, index, distance.length);
index += distance.length;
}
return new ShrinkingDistance(data);
}

private ShrinkingDistance(long[] distances) {
Expand Down Expand Up @@ -98,7 +125,7 @@ private int compareDimension(ShrinkingDistance other, int i) {
return Long.compare(left, right);
}

private long at(long[] array, int i) {
private static long at(long[] array, int i) {
return array.length > i ? array[i] : 0;
}

Expand All @@ -120,13 +147,31 @@ private long[] sumUpArrays(long[] left, long[] right) {
return sum;
}

private static long[] sumUpArrays(long @Nullable [] sum, long[] left, long[] right) {
if (sum == null || sum.length < left.length || sum.length < right.length) {
sum = new long[Math.max(left.length, right.length)];
}
for (int i = 0; i < sum.length; i++) {
sum[i] = saturatedAdd(at(left, i), at(right, i));
}
return sum;
}

private static long saturatedAdd(long a, long b) {
long sum = a + b;
if (((a ^ sum) & (b ^ sum)) < 0) {
return Long.MAX_VALUE;
}
return sum;
}

@API(status = INTERNAL)
public ShrinkingDistance append(ShrinkingDistance other) {
long[] appendedDistances = concatArrays(distances, other.distances);
return new ShrinkingDistance(appendedDistances);
}

private long[] concatArrays(long[] left, long[] right) {
private static long[] concatArrays(long[] left, long[] right) {
long[] concatenated = Arrays.copyOf(left, left.length + right.length);
System.arraycopy(right, 0, concatenated, left.length, right.length);
return concatenated;
Expand Down

0 comments on commit 4f6274b

Please sign in to comment.