Skip to content

Commit

Permalink
Not a lut left
Browse files Browse the repository at this point in the history
- Prune empty layers from the lut to avoid it just getting larger as the
  player explores the world
  • Loading branch information
Jozufozu committed Nov 15, 2024
1 parent 6431a84 commit f3845a1
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public void add(long position, int index) {
.set(z, index + 1);
}

public void prune() {
// Maybe this could be done better incrementally?
indices.prune((middle) -> middle.prune(IntLayer::prune));
}

public void remove(long section) {
final var x = SectionPos.x(section);
final var y = SectionPos.y(section);
Expand All @@ -49,6 +54,11 @@ public IntArrayList flatten() {
return out;
}

@FunctionalInterface
public interface Prune<T> {
boolean prune(T t);
}

public static final class Layer<T> {
private boolean hasBase = false;
private int base = 0;
Expand Down Expand Up @@ -135,6 +145,69 @@ public T computeIfAbsent(int i, Supplier<T> ifAbsent) {
return (T) out;
}

/**
* @return {@code true} if the layer is now empty.
*/
public boolean prune(Prune<T> inner) {
if (!hasBase) {
return true;
}

// Prune the next layer before checking for leading/trailing zeros.
for (var i = 0; i < nextLayer.length; i++) {
var o = nextLayer[i];
if (o != null && inner.prune((T) o)) {
nextLayer[i] = null;
}
}

var leadingZeros = getLeadingZeros();

if (leadingZeros == nextLayer.length) {
return true;
}

var trailingZeros = getTrailingZeros();

if (leadingZeros == 0 && trailingZeros == 0) {
return false;
}

final var newIndices = new Object[nextLayer.length - leadingZeros - trailingZeros];

System.arraycopy(nextLayer, leadingZeros, newIndices, 0, newIndices.length);
nextLayer = newIndices;
base += leadingZeros;

return false;
}

private int getLeadingZeros() {
int out = 0;

for (Object index : nextLayer) {
if (index == null) {
out++;
} else {
break;
}
}
return out;
}

private int getTrailingZeros() {
int out = 0;

for (int i = nextLayer.length - 1; i >= 0; i--) {
if (nextLayer[i] == null) {
out++;
} else {
break;
}
}
return out;
}

private void resize(int length) {
final var newIndices = new Object[length];
System.arraycopy(nextLayer, 0, newIndices, 0, nextLayer.length);
Expand Down Expand Up @@ -214,6 +287,61 @@ public void set(int i, int index) {
indices[offset] = index;
}

/**
* @return {@code true} if the layer is now empty.
*/
public boolean prune() {
if (!hasBase) {
return true;
}

var leadingZeros = getLeadingZeros();

if (leadingZeros == indices.length) {
return true;
}

var trailingZeros = getTrailingZeros();

if (leadingZeros == 0 && trailingZeros == 0) {
return false;
}

final var newIndices = new int[indices.length - leadingZeros - trailingZeros];

System.arraycopy(indices, leadingZeros, newIndices, 0, newIndices.length);
indices = newIndices;
base += leadingZeros;

return false;
}

private int getTrailingZeros() {
int out = 0;

for (int i = indices.length - 1; i >= 0; i--) {
if (indices[i] == 0) {
out++;
} else {
break;
}
}
return out;
}

private int getLeadingZeros() {
int out = 0;

for (int index : indices) {
if (index == 0) {
out++;
} else {
break;
}
}
return out;
}

public void clear(int i) {
if (!hasBase) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ private void removeUnusedSections() {
return;
}

boolean anyRemoved = false;

var entries = section2ArenaIndex.long2IntEntrySet();
var it = entries.iterator();
while (it.hasNext()) {
Expand All @@ -181,8 +183,14 @@ private void removeUnusedSections() {
arena.free(entry.getIntValue());
endTrackingSection(section);
it.remove();
anyRemoved = true;
}
}

if (anyRemoved) {
lut.prune();
needsLutRebuild = true;
}
}

private void beginTrackingSection(long section, int index) {
Expand Down

0 comments on commit f3845a1

Please sign in to comment.