Skip to content

Commit

Permalink
Squash adjacent JPAStreamer operations, fix #355
Browse files Browse the repository at this point in the history
  • Loading branch information
julgus committed Jul 10, 2023
1 parent 524aca1 commit bfe91fc
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@
*/
package com.speedment.jpastreamer.interopoptimizer.standard.internal.strategy.squash.abstracts;

import com.speedment.jpastreamer.field.ComparableField;
import com.speedment.jpastreamer.field.predicate.SpeedmentPredicate;
import com.speedment.jpastreamer.interopoptimizer.standard.internal.strategy.squash.SingleValueSquash;
import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperation;
import com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperationType;

import java.util.Comparator;
import java.util.LinkedList;
import java.util.Optional;

import static com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperationType.FILTER;
import static com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperationType.SORTED;

public abstract class AbstractSingleValueSquash<S> implements SingleValueSquash<S> {

Expand All @@ -48,15 +51,16 @@ public <T> Pipeline<T> optimize(final Pipeline<T> pipeline) {
}

if (valueClass().isAssignableFrom(intermediateOperation.arguments()[0].getClass())) {
S value = (S) intermediateOperation.arguments()[0];
if (operationType() != FILTER || value instanceof SpeedmentPredicate) {
S value = (S) intermediateOperation.arguments()[0];
if ((operationType() != FILTER && operationType() != SORTED) ||
value instanceof SpeedmentPredicate ||
value instanceof ComparableField ) {
result = squash().apply(value, result);

intermediateOperations.remove(i);
continue;
}
}

continue;
}

if (result != checkValue()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,29 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.speedment.jpastreamer.interopoptimizer.standard.internal.strategy.model.Film;
import com.speedment.jpastreamer.interopoptimizer.standard.internal.strategy.model.Film$;
import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperation;

import java.util.Comparator;
import java.util.stream.IntStream;
import java.util.stream.Stream;

final class SquashSortedTest extends SquashTest<String, SquashSorted<?>> {
final class SquashSortedTest extends SquashTest<Film, SquashSorted<?>> {

@Override
SquashSorted<?> getSquashInstance() {
return new SquashSorted<>(operationFactory);
}

@Override
Class<String> getEntityClass() {
return String.class;
Class<Film> getEntityClass() {
return Film.class;
}

@Override
protected Stream<PipelineTestCase<String>> pipelines() {
protected Stream<PipelineTestCase<Film>> pipelines() {
return Stream.of(
noSorted(),
sortedN(1), sortedN(2), sortedN(3), sortedN(10), sortedN(100),
Expand All @@ -44,71 +46,71 @@ protected Stream<PipelineTestCase<String>> pipelines() {
);
}

private PipelineTestCase<String> noSorted() {
final Pipeline<String> noSorted = createPipeline(
private PipelineTestCase<Film> noSorted() {
final Pipeline<Film> noSorted = createPipeline(
operationFactory.createSkip(1)
);

final Pipeline<String> noSortedExpected = createPipeline(
final Pipeline<Film> noSortedExpected = createPipeline(
operationFactory.createSkip(1)
);

return new PipelineTestCase<>("No Sorted", noSorted, noSortedExpected);
}

private PipelineTestCase<String> sortedN(int n) {
IntermediateOperation<?, ?>[] operations = IntStream.range(0, n).mapToObj(i -> operationFactory.createSorted((o1, o2) -> 0)).toArray(IntermediateOperation[]::new);
private PipelineTestCase<Film> sortedN(int n) {
IntermediateOperation<?, ?>[] operations = IntStream.range(0, n).mapToObj(i -> operationFactory.createSorted(Film$.length)).toArray(IntermediateOperation[]::new);

final Pipeline<String> sorted = createPipeline(operations);
final Pipeline<Film> sorted = createPipeline(operations);

final Pipeline<String> sortedExpected = createPipeline(operationFactory.createSorted((o1, o2) -> 0));
final Pipeline<Film> sortedExpected = createPipeline(operationFactory.createSorted(Film$.length));

return new PipelineTestCase<>("Sorted " + n, sorted, sortedExpected);
}

private PipelineTestCase<String> sortedOther() {
final Pipeline<String> sortedOther = createPipeline(
operationFactory.createSorted(((o1, o2) -> 0)),
private PipelineTestCase<Film> sortedOther() {
final Pipeline<Film> sortedOther = createPipeline(
operationFactory.createSorted(Film$.length),
operationFactory.createSkip(1)
);

final Pipeline<String> sortedOtherExpected = createPipeline(
operationFactory.createSorted((o1, o2) -> 0),
final Pipeline<Film> sortedOtherExpected = createPipeline(
operationFactory.createSorted(Film$.length),
operationFactory.createSkip(1)
);

return new PipelineTestCase<>("Sorted, Other", sortedOther, sortedOtherExpected);
}

private PipelineTestCase<String> sorted2Other2() {
final Comparator<Object> first = (o1, o2) -> 0;
final Comparator<Object> second = (o1, o2) -> 1;
private PipelineTestCase<Film> sorted2Other2() {
final Comparator<Film> first = Film$.length;
final Comparator<Film> second = Film$.title;

final Pipeline<String> sorted2Other2 = createPipeline(
final Pipeline<Film> sorted2Other2 = createPipeline(
operationFactory.createSorted(first), operationFactory.createSorted(second),
operationFactory.createSkip(1), operationFactory.createSkip(1)
);

final Pipeline<String> sorted2Other2Expected = createPipeline(
final Pipeline<Film> sorted2Other2Expected = createPipeline(
operationFactory.createSorted(first.thenComparing(second)),
operationFactory.createSkip(1), operationFactory.createSkip(1)
);

return new PipelineTestCase<>("Sorted 2, Other 2", sorted2Other2, sorted2Other2Expected);
}

private PipelineTestCase<String> sorted2OtherSorted2() {
final Comparator<Object> first = (o1, o2) -> 0;
final Comparator<Object> second = (o1, o2) -> 1;
private PipelineTestCase<Film> sorted2OtherSorted2() {
final Comparator<Film> first = Film$.length;
final Comparator<Film> second = Film$.title;

final Pipeline<String> sorted2OtherSorted2 = createPipeline(
final Pipeline<Film> sorted2OtherSorted2 = createPipeline(
operationFactory.createSorted(first), operationFactory.createSorted(second),
operationFactory.createLimit(1),
operationFactory.createSorted(second), operationFactory.createSorted(first)
);


final Pipeline<String> sorted2OtherSorted2Expected = createPipeline(
final Pipeline<Film> sorted2OtherSorted2Expected = createPipeline(
operationFactory.createSorted(first.thenComparing(second)),
operationFactory.createLimit(1),
operationFactory.createSorted(second.thenComparing(first))
Expand All @@ -117,14 +119,37 @@ private PipelineTestCase<String> sorted2OtherSorted2() {
return new PipelineTestCase<>("Sorted 2, Other, Sorted 2", sorted2OtherSorted2, sorted2OtherSorted2Expected);
}

private PipelineTestCase<Film> sortedLambdaOtherLambdaSorted() {
final Comparator<Film> first = Film$.length;
final Comparator<Film> second = Comparator.comparing(Film::getTitle);

final Pipeline<Film> sorted2OtherSorted2 = createPipeline(
operationFactory.createSorted(first), operationFactory.createSorted(second),
operationFactory.createLimit(1),
operationFactory.createSorted(second), operationFactory.createSorted(first)
);


final Pipeline<Film> sorted2OtherSorted2Expected = createPipeline(
operationFactory.createSorted(first), operationFactory.createSorted(second),
operationFactory.createLimit(1),
operationFactory.createSorted(second), operationFactory.createSorted(first)
);

return new PipelineTestCase<>("Sorted, Lambda, Other, Lambda, Sorted", sorted2OtherSorted2, sorted2OtherSorted2Expected);
}

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
protected void assertArguments(Object[] expected, Object[] actual) {
if (expected[0] instanceof Comparator && actual[0] instanceof Comparator) {
final Comparator expectedPredicate = (Comparator) expected[0];
final Comparator actualPredicate = (Comparator) actual[0];

assertEquals(expectedPredicate.compare(null, null), actualPredicate.compare(null, null));
final Film film1 = new Film((short) 1, "Titanic", "A film about a boat.");
final Film film2 = new Film((short) 2, "Star Wars", "A film about war in space.");

assertEquals(expectedPredicate.compare(film1, film2), actualPredicate.compare(film1, film2));
} else {
super.assertArguments(expected, actual);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public <ENTITY> void modifyCriteria(
criteria.getQuery().orderBy(previousOrders);

/*
* If a Stream::sorted sequence contains a operation without a specified comparator
* If a Stream::sorted sequence contains an operation without a specified comparator
* we cannot squash that sequence into a single operation. Because of this, we should
* only mark the operation as merged if it's the last one in the sequence.
* */
Expand Down

0 comments on commit bfe91fc

Please sign in to comment.