add launch flag to disable verifying world section access is correct
This commit is contained in:
@@ -12,7 +12,10 @@ import java.util.concurrent.atomic.AtomicLongFieldUpdater;
|
||||
//Represents a loaded world section at a specific detail level
|
||||
// holds a 32x32x32 region of detail
|
||||
public final class WorldSection {
|
||||
private static final int ARRAY_REUSE_CACHE_SIZE = 256;
|
||||
public static final boolean VERIFY_WORLD_SECTION_EXECUTION = System.getProperty("voxy.verifyWorldSectionExecution", "true").equals("true");
|
||||
|
||||
//TODO: should make it dynamically adjust the size allowance based on memory pressure/WorldSection allocation rate (e.g. is it doing a world import)
|
||||
private static final int ARRAY_REUSE_CACHE_SIZE = 300;
|
||||
//TODO: maybe just swap this to a ConcurrentLinkedDeque
|
||||
private static final Deque<long[]> ARRAY_REUSE_CACHE = new ArrayDeque<>(1024);
|
||||
|
||||
@@ -58,12 +61,23 @@ public final class WorldSection {
|
||||
return ((x*1235641+y)*8127451+z)*918267913+lvl;
|
||||
}
|
||||
|
||||
public boolean tryAcquire() {
|
||||
int state = this.atomicState.updateAndGet(val -> {
|
||||
if ((val&1) != 0) {
|
||||
return val+2;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
return (state&1) != 0;
|
||||
}
|
||||
|
||||
public int acquire() {
|
||||
int state = this.atomicState.addAndGet(2);
|
||||
if (VERIFY_WORLD_SECTION_EXECUTION) {
|
||||
if ((state & 1) == 0) {
|
||||
throw new IllegalStateException("Tried to acquire unloaded section");
|
||||
}
|
||||
}
|
||||
return state>>1;
|
||||
}
|
||||
|
||||
@@ -74,25 +88,28 @@ public final class WorldSection {
|
||||
//TODO: add the ability to hint to the tracker that yes the section is unloaded, try to cache it in a secondary cache since it will be reused/needed later
|
||||
public int release() {
|
||||
int state = this.atomicState.addAndGet(-2);
|
||||
if (VERIFY_WORLD_SECTION_EXECUTION) {
|
||||
if (state < 1) {
|
||||
throw new IllegalStateException("Section got into an invalid state");
|
||||
}
|
||||
if ((state & 1) == 0) {
|
||||
throw new IllegalStateException("Tried releasing a freed section");
|
||||
}
|
||||
}
|
||||
if ((state>>1)==0) {
|
||||
this.tracker.tryUnload(this);
|
||||
}
|
||||
|
||||
return state>>1;
|
||||
}
|
||||
|
||||
//Returns true on success, false on failure
|
||||
boolean trySetFreed() {
|
||||
int witness = this.atomicState.compareAndExchange(1, 0);
|
||||
if (VERIFY_WORLD_SECTION_EXECUTION) {
|
||||
if ((witness & 1) == 0 && witness != 0) {
|
||||
throw new IllegalStateException("Section marked as free but has refs");
|
||||
}
|
||||
}
|
||||
boolean isFreed = witness == 1;
|
||||
if (isFreed) {
|
||||
if (ARRAY_REUSE_CACHE.size() < ARRAY_REUSE_CACHE_SIZE) {
|
||||
@@ -106,16 +123,20 @@ public final class WorldSection {
|
||||
}
|
||||
|
||||
public void assertNotFree() {
|
||||
if (VERIFY_WORLD_SECTION_EXECUTION) {
|
||||
if ((this.atomicState.get() & 1) == 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIndex(int x, int y, int z) {
|
||||
int M = (1<<5)-1;
|
||||
if (VERIFY_WORLD_SECTION_EXECUTION) {
|
||||
if (x < 0 || x > M || y < 0 || y > M || z < 0 || z > M) {
|
||||
throw new IllegalArgumentException("Out of bounds: " + x + ", " + y + ", " + z);
|
||||
}
|
||||
}
|
||||
return ((y&M)<<10)|((z&M)<<5)|(x&M);
|
||||
}
|
||||
|
||||
@@ -137,16 +158,6 @@ public final class WorldSection {
|
||||
if (cache.length != this.data.length) throw new IllegalArgumentException();
|
||||
System.arraycopy(this.data, 0, cache, 0, this.data.length);
|
||||
}
|
||||
|
||||
public boolean tryAcquire() {
|
||||
int state = this.atomicState.updateAndGet(val -> {
|
||||
if ((val&1) != 0) {
|
||||
return val+2;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
return (state&1) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: for serialization, make a huffman encoding tree on the integers since that should be very very efficent for compression
|
||||
|
||||
Reference in New Issue
Block a user