Skip to content

Commit

Permalink
Move terminal operation optimizations to modifier, add tests, work #31
Browse files Browse the repository at this point in the history
  • Loading branch information
julgus committed May 26, 2023
1 parent 53884c4 commit 3519795
Show file tree
Hide file tree
Showing 21 changed files with 205 additions and 183 deletions.
6 changes: 6 additions & 0 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@
<version>${jpa-streamer.version}</version>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>termopmodifier-standard</artifactId>
<version>${jpa-streamer.version}</version>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>announcer</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,19 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
return false;
}

roundEnv.getElementsAnnotatedWith(Entity.class).stream()
Set<? extends Element> entities = roundEnv.getElementsAnnotatedWith(Entity.class);

if (entities.isEmpty()) {
System.out.format("[JPAStreamer Field Generator Processor] Found no classes annotated with jakarta.persistence.Entity.\n");
return true;
}

entities.stream()
.filter(ae -> ae.getKind() == ElementKind.CLASS)
.forEach(ae -> {
try {
final String entityName = ae.asType().toString();
System.out.format("[JPAStreamer Field Generator Processor] Generating class for: %s\n", entityName);
final String shortEntityName = shortName(entityName);

final String prefix = processingEnv.getOptions().getOrDefault("jpaStreamerPrefix", "");
Expand Down
12 changes: 6 additions & 6 deletions provider/renderer-standard/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,22 @@
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>interopoptimizer</artifactId>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>rootfactory</artifactId>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>termopmodifier</artifactId>
</dependency>

<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>${jakarta.version}</version>
</dependency>
<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>termopoptimizer</artifactId>
</dependency>


</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
import com.speedment.jpastreamer.rootfactory.RootFactory;
import com.speedment.jpastreamer.streamconfiguration.StreamConfiguration;

import com.speedment.jpastreamer.termopoptimizer.TerminalOperationOptimizerFactory;
import com.speedment.jpastreamer.termopmodifier.TerminalOperationModifierFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.TypedQuery;
Expand All @@ -49,7 +49,7 @@ final class StandardRenderer implements Renderer {
private final CriteriaFactory criteriaFactory;

private final IntermediateOperationOptimizerFactory intermediateOperationOptimizerFactory;
private final TerminalOperationOptimizerFactory terminalOperationOptimizerFactory;
private final TerminalOperationModifierFactory terminalOperationModifierFactory;

private final MergerFactory mergerFactory;

Expand All @@ -61,21 +61,22 @@ final class StandardRenderer implements Renderer {
this.entityManager = requireNonNull(entityManagerSupplier).get();
this.criteriaFactory = RootFactory.getOrThrow(CriteriaFactory.class, ServiceLoader::load);
this.intermediateOperationOptimizerFactory = RootFactory.getOrThrow(IntermediateOperationOptimizerFactory.class, ServiceLoader::load);
this.terminalOperationOptimizerFactory = RootFactory.getOrThrow(TerminalOperationOptimizerFactory.class, ServiceLoader::load);
this.terminalOperationModifierFactory = RootFactory.getOrThrow(TerminalOperationModifierFactory.class, ServiceLoader::load);
this.mergerFactory = RootFactory.getOrThrow(MergerFactory.class, ServiceLoader::load);
}

StandardRenderer(final EntityManager entityManager) {
this.entityManager = entityManager;
this.criteriaFactory = RootFactory.getOrThrow(CriteriaFactory.class, ServiceLoader::load);
this.intermediateOperationOptimizerFactory = RootFactory.getOrThrow(IntermediateOperationOptimizerFactory.class, ServiceLoader::load);
this.terminalOperationOptimizerFactory = RootFactory.getOrThrow(TerminalOperationOptimizerFactory.class, ServiceLoader::load);
this.terminalOperationModifierFactory = RootFactory.getOrThrow(TerminalOperationModifierFactory.class, ServiceLoader::load);
this.mergerFactory = RootFactory.getOrThrow(MergerFactory.class, ServiceLoader::load);
}

@Override
@SuppressWarnings("unchecked")
public <E, T, S extends BaseStream<T, S>> RenderResult<E, T, S> render(final Pipeline<E> pipeline, final StreamConfiguration<E> streamConfiguration) {
modifyPipeline(pipeline);
optimizePipeline(pipeline);

final Class<E> entityClass = pipeline.root();
Expand Down Expand Up @@ -182,9 +183,12 @@ private <E, T, S extends BaseStream<T, S>> S replay(final Stream<E> stream, fina
return decorated;
*/
}


private <T> void modifyPipeline(final Pipeline<T> pipeline) {
terminalOperationModifierFactory.get().modify(pipeline);
}

private <T> void optimizePipeline(final Pipeline<T> pipeline) {
terminalOperationOptimizerFactory.get().optimize(pipeline);
intermediateOperationOptimizerFactory.stream().forEach(intermediateOperationOptimizer -> intermediateOperationOptimizer.optimize(pipeline));
}

Expand Down
2 changes: 1 addition & 1 deletion provider/renderer-standard/src/main/java9/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
requires jpastreamer.criteria;
requires jpastreamer.merger;
requires jpastreamer.interopoptimizer;
requires jpastreamer.termopoptimizer;
requires jpastreamer.termopmodifier;

exports com.speedment.jpastreamer.renderer.standard;
// Todo: Enable this
Expand Down
18 changes: 18 additions & 0 deletions provider/termopmodifier-standard/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,28 @@
</description>

<dependencies>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>termopmodifier</artifactId>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>rootfactory</artifactId>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>pipeline-standard</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.speedment.jpastreamer</groupId>
<artifactId>field</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ public final class InternalTerminalOperatorModifierFactory implements TerminalOp
public TerminalOperationModifier get() {
return singleton;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,93 @@
*/
package com.speedment.jpastreamer.termopmodifier.standard.internal;

import com.speedment.jpastreamer.field.predicate.SpeedmentPredicate;
import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.pipeline.intermediate.IntermediateOperationFactory;
import com.speedment.jpastreamer.pipeline.terminal.TerminalOperation;
import com.speedment.jpastreamer.pipeline.terminal.TerminalOperationFactory;
import com.speedment.jpastreamer.pipeline.terminal.TerminalOperationType;
import com.speedment.jpastreamer.rootfactory.RootFactory;
import com.speedment.jpastreamer.termopmodifier.TerminalOperationModifier;

import java.util.Optional;
import java.util.ServiceLoader;

import static java.util.Objects.requireNonNull;

final class StandardTerminalOperatorModifier implements com.speedment.jpastreamer.termopmodifier.TerminalOperationModifier {
final class StandardTerminalOperatorModifier implements TerminalOperationModifier {

private final IntermediateOperationFactory intermediateOperationFactory;
private final TerminalOperationFactory terminalOperationFactory;

StandardTerminalOperatorModifier() {
this.intermediateOperationFactory = RootFactory.getOrThrow(IntermediateOperationFactory.class, ServiceLoader::load);
this.terminalOperationFactory = RootFactory.getOrThrow(TerminalOperationFactory.class, ServiceLoader::load);
}

@Override
public <T> Pipeline<T> modify(Pipeline<T> pipeline) {
requireNonNull(pipeline);
// For now, just return whatever we get.

final TerminalOperationType terminalOperationType = pipeline.terminatingOperation().type();

switch (terminalOperationType) {
case ANY_MATCH:
return modifyAnyMatch(pipeline);
case NONE_MATCH:
return modifyNoneMatch(pipeline);
case FIND_FIRST:
return modifyFindFirst(pipeline);
case FIND_ANY:
return modifyFindAny(pipeline);
default:
return pipeline;
}
}

private <T> Pipeline<T> modifyAnyMatch(Pipeline<T> pipeline) {
this.<T>getPredicate(pipeline.terminatingOperation()).ifPresent(speedmentPredicate -> {
pipeline.intermediateOperations().add(intermediateOperationFactory.createFilter(speedmentPredicate));
pipeline.intermediateOperations().add(intermediateOperationFactory.createLimit(1));
pipeline.terminatingOperation(terminalOperationFactory.createAnyMatch(p -> true));
});
return pipeline;
}

private <T> Pipeline<T> modifyNoneMatch(Pipeline<T> pipeline) {
this.<T>getPredicate(pipeline.terminatingOperation()).ifPresent(speedmentPredicate -> {
pipeline.intermediateOperations().add(intermediateOperationFactory.createFilter(speedmentPredicate));
pipeline.intermediateOperations().add(intermediateOperationFactory.createLimit(1));
// NoneMatch() - If the stream is empty then true is returned and the predicate is not evaluated.
// If the expression is evaluated => There is a match and the expression is always false.
pipeline.terminatingOperation(terminalOperationFactory.createNoneMatch(e -> true));
});
return pipeline;
}

private <T> Pipeline<T> modifyFindFirst(Pipeline<T> pipeline) {
pipeline.intermediateOperations().add(intermediateOperationFactory.createLimit(1));
return pipeline;
}

private <T> Pipeline<T> modifyFindAny(Pipeline<T> pipeline) {
pipeline.ordered(false);
pipeline.intermediateOperations().add(intermediateOperationFactory.createLimit(1));
return pipeline;
}

private <T> Optional<SpeedmentPredicate<T>> getPredicate(final TerminalOperation<?, ?> operation) {
final Object[] arguments = operation.arguments();

if (arguments.length != 1) {
return Optional.empty();
}

if (arguments[0] instanceof SpeedmentPredicate) {
return Optional.of((SpeedmentPredicate<T>) arguments[0]);
}

return Optional.empty();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
module jpastreamer.termopmodifier.standard {
requires transitive jpastreamer.termopmodifier;
requires jpastreamer.rootfactory;

exports com.speedment.jpastreamer.termopmodifier.standard;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.speedment.jpastreamer.termopmodifier.standard;

import com.speedment.jpastreamer.termopmodifier.TerminalOperationModifierFactory;
import org.junit.jupiter.api.Test;

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

public class StandardTerminalOperationModifierFactoryTest {

@Test
void get() {
final TerminalOperationModifierFactory terminalOperationModifierFactory = new StandardTerminalOperatorModifierFactory();
assertNotNull(terminalOperationModifierFactory.get());
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package com.speedment.jpastreamer.termopoptimizer.standard.internal;
package com.speedment.jpastreamer.termopmodifier.standard.internal;

import com.speedment.jpastreamer.field.ComparableField;
import com.speedment.jpastreamer.field.ShortField;
import com.speedment.jpastreamer.field.predicate.SpeedmentPredicate;
import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film$;

import java.math.BigDecimal;
import java.util.function.Predicate;
import java.util.stream.Stream;

final class AnyMatchTest extends StandardTerminalOperationOptimizerTest<Film> {
public class AnyMatchTest extends StandardTerminalOperationModifierTest<Film> {

@Override
Class<Film> getEntityClass() {
Expand All @@ -24,7 +23,7 @@ protected Stream<PipelineTestCase<Film>> pipelines() {
anyMatchSpeedmentPredicate()
);
}

private PipelineTestCase<Film> noAnyMatch() {
final Pipeline<Film> noAnyMatch = createPipeline(
tof.createAllMatch(s -> s.equals("test")),
Expand Down Expand Up @@ -66,8 +65,8 @@ private PipelineTestCase<Film> anyMatchSpeedmentPredicate() {
final Pipeline<Film> anyMatchExpected = createPipeline(
tof.createAnyMatch(s -> true),
iof.createLimit(100),
iof.createLimit(1),
iof.createFilter(predicate)
iof.createFilter(predicate),
iof.createLimit(1)
);

return new PipelineTestCase<>("Any Match Speedment Predicate", anyMatch, anyMatchExpected);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.speedment.jpastreamer.termopoptimizer.standard.internal;
package com.speedment.jpastreamer.termopmodifier.standard.internal;

import com.speedment.jpastreamer.field.predicate.SpeedmentPredicate;
import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film$;

import java.util.function.Predicate;
import java.util.stream.Stream;

public class FindAnyTest extends StandardTerminalOperationOptimizerTest<Film> {

public class FindAnyTest extends StandardTerminalOperationModifierTest<Film> {
@Override
Class<Film> getEntityClass() {
return Film.class;
Expand Down Expand Up @@ -53,5 +54,4 @@ private PipelineTestCase<Film> findAny() {

return new PipelineTestCase<>("Find Any", findAny, findAnyExpected);
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.speedment.jpastreamer.termopoptimizer.standard.internal;
package com.speedment.jpastreamer.termopmodifier.standard.internal;

import com.speedment.jpastreamer.pipeline.Pipeline;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film;
import com.speedment.jpastreamer.termopmodifier.standard.internal.model.Film$;

import java.util.function.Predicate;
import java.util.stream.Stream;

public class FindFirstTest extends StandardTerminalOperationOptimizerTest<Film> {
public class FindFirstTest extends StandardTerminalOperationModifierTest<Film> {

@Override
Class<Film> getEntityClass() {
Expand Down Expand Up @@ -52,5 +54,5 @@ private PipelineTestCase<Film> findFirst() {

return new PipelineTestCase<>("Find First", findFirst, findFirstExpected);
}

}
Loading

0 comments on commit 3519795

Please sign in to comment.