85 lines
2.1 KiB
Java
85 lines
2.1 KiB
Java
package de.ph87.data.view.tree;
|
|
|
|
import de.ph87.data.point.Point;
|
|
import de.ph87.data.view.ViewScope;
|
|
import jakarta.persistence.*;
|
|
import lombok.*;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.function.BiFunction;
|
|
|
|
@Entity
|
|
@Getter
|
|
@Setter
|
|
@NoArgsConstructor
|
|
@ToString(callSuper = true)
|
|
@DiscriminatorValue("binary")
|
|
public class ViewBinary extends View {
|
|
|
|
@NonNull
|
|
@Enumerated(EnumType.STRING)
|
|
private Operation operation;
|
|
|
|
@NonNull
|
|
@OneToOne(optional = false, orphanRemoval = true, cascade = CascadeType.ALL)
|
|
private View view0;
|
|
|
|
@NonNull
|
|
@OneToOne(optional = false, orphanRemoval = true, cascade = CascadeType.ALL)
|
|
private View view1;
|
|
|
|
public ViewBinary(@NonNull final Operation operation, @NonNull final View view0, @NonNull final View view1) {
|
|
this.operation = operation;
|
|
this.view0 = view0;
|
|
this.view1 = view1;
|
|
}
|
|
|
|
public enum Operation {
|
|
PLUS(Double::sum),
|
|
MINUS((a, b) -> a - b),
|
|
MULTIPLY((a, b) -> a * b),
|
|
DIVIDE((a, b) -> a / b),
|
|
MODULO((a, b) -> a % b),
|
|
PERCENT((a, b) -> a / b * 100),
|
|
;
|
|
|
|
public final BiFunction<Double, Double, Double> function;
|
|
|
|
Operation(final BiFunction<Double, Double, Double> function) {
|
|
this.function = function;
|
|
}
|
|
|
|
@NonNull
|
|
public Point apply(@NonNull final Point a, @NonNull final Point b) {
|
|
return new Point(a.date, function.apply(a.value, b.value));
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public List<Point> getPoints(final @NonNull ViewScope scope) {
|
|
final List<Point> pointsA = view0.getPoints(scope);
|
|
final List<Point> pointsB = view1.getPoints(scope);
|
|
final List<Point> result = new ArrayList<>(pointsA.size() + pointsB.size());
|
|
int indexA = 0;
|
|
int indexB = 0;
|
|
while (indexA < pointsA.size() && indexB < pointsB.size()) {
|
|
final Point pointA = pointsA.get(indexA);
|
|
final Point pointB = pointsB.get(indexB);
|
|
int cmp = pointA.date.compareTo(pointB.date);
|
|
if (cmp < 0) {
|
|
indexA++;
|
|
} else if (cmp > 0) {
|
|
indexB++;
|
|
} else {
|
|
result.add(operation.apply(pointA, pointB));
|
|
indexA++;
|
|
indexB++;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|