optimise BinaryColumn get

This commit is contained in:
dfsek 2022-02-15 10:55:09 -07:00
parent f13d66d095
commit aa39dc4b81
2 changed files with 26 additions and 7 deletions

View File

@ -7,12 +7,15 @@
package com.dfsek.terra.api.structure.feature; package com.dfsek.terra.api.structure.feature;
import java.util.ArrayList;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.function.IntConsumer; import java.util.function.IntConsumer;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import com.dfsek.terra.api.util.Range; import com.dfsek.terra.api.util.Range;
import com.dfsek.terra.api.util.function.IntToBooleanFunction; import com.dfsek.terra.api.util.function.IntToBooleanFunction;
import com.dfsek.terra.api.util.generic.Lazy;
/** /**
@ -23,6 +26,8 @@ public class BinaryColumn {
private final int minY; private final int minY;
private final int maxY; private final int maxY;
private final Lazy<boolean[]> results;
private static final BinaryColumn NULL = new BinaryColumn(0, 1, y -> false); private static final BinaryColumn NULL = new BinaryColumn(0, 1, y -> false);
/** /**
@ -33,10 +38,25 @@ public class BinaryColumn {
public BinaryColumn(int minY, int maxY, IntToBooleanFunction data) { public BinaryColumn(int minY, int maxY, IntToBooleanFunction data) {
this.minY = minY; this.minY = minY;
this.maxY = maxY; this.maxY = maxY;
this.results = Lazy.lazy(() -> {
boolean[] res = new boolean[maxY - minY];
for(int y = minY; y < maxY; y++) {
res[y - minY] = get(y);
}
return res;
});
if(maxY <= minY) throw new IllegalArgumentException("Max y must be greater than min y"); if(maxY <= minY) throw new IllegalArgumentException("Max y must be greater than min y");
this.data = data; this.data = data;
} }
public BinaryColumn(int minY, int maxY, boolean[] data) {
this.minY = minY;
this.maxY = maxY;
this.results = Lazy.lazy(() -> data);
if(maxY <= minY) throw new IllegalArgumentException("Max y must be greater than min y");
this.data = y -> data[y - minY];
}
public static BinaryColumn getNull() { public static BinaryColumn getNull() {
return NULL; return NULL;
} }
@ -64,15 +84,14 @@ public class BinaryColumn {
* @param consumer Action to perform * @param consumer Action to perform
*/ */
public void forEach(IntConsumer consumer) { public void forEach(IntConsumer consumer) {
for(int y : matching()) { boolean[] results = this.results.value();
consumer.accept(y); for(int y = minY; y < maxY; y++) {
if(results[y - minY]) {
consumer.accept(y);
}
} }
} }
public int[] matching() {
return IntStream.range(minY, maxY).filter(this::get).toArray();
}
/** /**
* Return a {@link BinaryColumn} of equal height with a boolean AND operation applied to each height. * Return a {@link BinaryColumn} of equal height with a boolean AND operation applied to each height.
* @param that Other binary column, must match this column's height. * @param that Other binary column, must match this column's height.

View File

@ -77,7 +77,7 @@ public class Column<T extends WritableWorld> {
} }
public BinaryColumn build() { public BinaryColumn build() {
return new BinaryColumn(column.getMinY(), column.getMaxY(), y -> arr[y - column.getMinY()]); return new BinaryColumn(column.getMinY(), column.getMaxY(), arr);
} }
public BinaryColumnBuilder set(int y) { public BinaryColumnBuilder set(int y) {