Skip to content

Commit 6157c98

Browse files
committed
adjustments
1 parent b0d6f46 commit 6157c98

File tree

4 files changed

+49
-31
lines changed

4 files changed

+49
-31
lines changed

worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueChunk.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.util.concurrent.ExecutionException;
99
import java.util.concurrent.Future;
1010

11+
@ApiStatus.Internal
1112
public interface IQueueChunk<T extends Future<T>> extends IChunk, Callable<T> {
1213

1314
/**
@@ -29,8 +30,7 @@ default IQueueChunk<T> reset() {
2930
* @throws IllegalStateException if there is already a wrapper set and a new wrapper instance is attempted to be se
3031
* @since TODO
3132
*/
32-
@ApiStatus.Internal
33-
void setWrapper(WrapperChunk<? extends IChunk> parentWrapper);
33+
void setWrapper(WrapperChunk<?> parentWrapper);
3434

3535
/**
3636
* Invalidate the {@link WrapperChunk} if present.

worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fastasyncworldedit.core.internal.simd.SimdSupport;
66
import com.fastasyncworldedit.core.internal.simd.VectorizedCharFilterBlock;
77
import com.fastasyncworldedit.core.internal.simd.VectorizedFilter;
8+
import com.fastasyncworldedit.core.queue.implementation.chunk.ChunkHolder;
89
import com.fastasyncworldedit.core.queue.implementation.chunk.WrapperChunk;
910
import com.sk89q.worldedit.extent.Extent;
1011
import com.sk89q.worldedit.function.operation.Operation;
@@ -169,12 +170,20 @@ default ChunkFilterBlock apply(
169170
// }
170171
T initial = this.getOrCreateChunk(chunkX, chunkZ);
171172
WrapperChunk<T> chunk = new WrapperChunk<>(initial, () -> this.getOrCreateChunk(chunkX, chunkZ));
173+
if (initial instanceof ChunkHolder<?> holder) {
174+
holder.setWrapper(chunk);
175+
}
172176

173177
IChunk newChunk = filter.applyChunk(chunk, region);
174178
if (newChunk == chunk) {
175179
newChunk = chunk.get();
176180
} else {
177-
chunk.setWrapped((T) newChunk);
181+
T c = (T) newChunk;
182+
chunk.setWrapped(c);
183+
// The IDE lies, it is possible for it to be a ChunkHolder because we're a little loose with our generic types...
184+
if (c instanceof ChunkHolder<?> holder) {
185+
holder.setWrapper(chunk);
186+
}
178187
}
179188
if (newChunk != null) {
180189
if (block == null) {

worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public static ChunkHolder newInstance() {
4646
private volatile IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes)
4747
private volatile IChunkSet chunkSet; // The blocks to be set to the chunkExisting
4848
private IBlockDelegate delegate; // delegate handles the abstraction of the chunk layers
49-
private IQueueExtent<? extends IChunk> extent; // the parent queue extent which has this chunk
49+
private IQueueExtent<?> extent; // the parent queue extent which has this chunk
5050
private int chunkX;
5151
private int chunkZ;
5252
private boolean fastmode;
@@ -55,7 +55,7 @@ public static ChunkHolder newInstance() {
5555
private boolean createCopy = false;
5656
private long initTime = -1L;
5757
private SideEffectSet sideEffectSet;
58-
private WrapperChunk<? extends IChunk> parentWrapper = null;
58+
private WrapperChunk<?> parentWrapper = null;
5959

6060
private ChunkHolder() {
6161
this.delegate = NULL;
@@ -66,7 +66,7 @@ public void init(IBlockDelegate delegate) {
6666
}
6767

6868
@Override
69-
public void setWrapper(WrapperChunk<? extends IChunk> parentWrapper) {
69+
public void setWrapper(WrapperChunk<?> parentWrapper) {
7070
if (parentWrapper == this.parentWrapper) {
7171
return;
7272
}
@@ -79,7 +79,9 @@ public void setWrapper(WrapperChunk<? extends IChunk> parentWrapper) {
7979
@Override
8080
public void invalidateWrapper() {
8181
if (this.parentWrapper != null) {
82-
this.parentWrapper.invalidate(this);
82+
if (!this.parentWrapper.invalidate(this)) {
83+
throw new IllegalStateException("Existing chunk not equal to expected");
84+
}
8385
}
8486
}
8587

@@ -917,6 +919,8 @@ public synchronized void filterBlocks(Filter filter, ChunkFilterBlock block, @Nu
917919
final IChunkSet set = getOrCreateSet();
918920
if (parentWrapper == null) {
919921
parentWrapper = new WrapperChunk<>(this, () -> this.extent.getOrCreateChunk(getX(), getZ()));
922+
} else if (parentWrapper.get() != this) {
923+
throw new IllegalStateException("Parent WrapperChunk is not storing this chunk!?");
920924
}
921925
try {
922926
block.filter(parentWrapper, get, set, filter, region, full);
@@ -1025,9 +1029,8 @@ public synchronized <V extends IChunk> void init(IQueueExtent<V> extent, int chu
10251029
this.chunkX = chunkX;
10261030
this.chunkZ = chunkZ;
10271031
if (this.parentWrapper != null) {
1028-
try {
1029-
this.parentWrapper.invalidate(this);
1030-
} catch (IllegalStateException ignored) {
1032+
if (!this.parentWrapper.invalidate(this)) {
1033+
throw new IllegalStateException("Existing chunk not equal to expected");
10311034
}
10321035
this.parentWrapper = null;
10331036
}
@@ -1060,14 +1063,11 @@ public synchronized T call() {
10601063
*/
10611064

10621065
@Override
1063-
public <U extends Future<U>> U call(IQueueExtent<? extends IChunk> owner, IChunkSet set, Runnable finalize) {
1066+
public <U extends Future<U>> U call(IQueueExtent<?> owner, IChunkSet set, Runnable finalize) {
10641067
if (set != null) {
10651068
if (parentWrapper != null) {
1066-
try {
1067-
parentWrapper.invalidate(this);
1068-
} catch (Exception e) {
1069-
LOGGER.error(this.initTime + " : " + ((ChunkHolder) parentWrapper.get()).initTime);
1070-
throw e;
1069+
if (!parentWrapper.invalidate(this)) {
1070+
throw new IllegalStateException("Existing chunk not equal to expected");
10711071
}
10721072
}
10731073
IChunkGet get = getOrCreateGet();
@@ -1111,7 +1111,7 @@ private void untrackExtent() {
11111111
/**
11121112
* Get the extent this chunk is in.
11131113
*/
1114-
public IQueueExtent<? extends IChunk> getExtent() {
1114+
public IQueueExtent<?> getExtent() {
11151115
return extent;
11161116
}
11171117

worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/WrapperChunk.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,19 @@ public class WrapperChunk<T extends IChunk> implements IChunk {
5959
public WrapperChunk(T initialValue, Supplier<T> supplier) {
6060
this.chunk = initialValue;
6161
this.supplier = supplier;
62-
if (chunk instanceof ChunkHolder<?> holder) {
63-
holder.setWrapper(this);
64-
}
6562
}
6663

6764
private T getWrapped() {
68-
return chunk != null ? chunk : (chunk = supplier.get());
65+
T c = this.chunk;
66+
if (c != null) {
67+
return c;
68+
}
69+
synchronized (this) {
70+
if (this.chunk == null) {
71+
this.chunk = supplier.get();
72+
}
73+
return this.chunk;
74+
}
6975
}
7076

7177
/**
@@ -78,16 +84,20 @@ public T get() {
7884
}
7985

8086
/**
81-
* Invalidate the currently stored chunk (set to null).
87+
* Invalidate the currently stored chunk (set to null) if the existing {@link ChunkHolder} matches the expected.
8288
*
8389
* @param expected The {@link ChunkHolder} instance we expect.
84-
* @throws IllegalStateException if the expected {@link ChunkHolder} is not the currently wrapped chunk
90+
* @return true if the expected {@link ChunkHolder} is the currently wrapped chunk, false otherwise (and does not invalidate).
8591
*/
86-
void invalidate(ChunkHolder<?> expected) {
87-
if (this.chunk != null && expected != this.chunk) {
88-
throw new IllegalStateException("Existing chunk not equal to expected");
92+
boolean invalidate(ChunkHolder<?> expected) {
93+
T c = this.chunk;
94+
if (c != null && expected != c) {
95+
return false;
96+
}
97+
synchronized (this) {
98+
this.chunk = null;
8999
}
90-
this.chunk = null;
100+
return true;
91101
}
92102

93103
/**
@@ -97,9 +107,8 @@ void invalidate(ChunkHolder<?> expected) {
97107
* @param chunk chunk to wrap
98108
*/
99109
public void setWrapped(T chunk) {
100-
this.chunk = Objects.requireNonNull(chunk);
101-
if (chunk instanceof ChunkHolder<?> holder) {
102-
holder.setWrapper(this);
110+
synchronized (this) {
111+
this.chunk = Objects.requireNonNull(chunk);
103112
}
104113
}
105114

@@ -481,7 +490,7 @@ public void optimize() {
481490

482491
@Override
483492
public <T extends Future<T>> T call(
484-
final IQueueExtent<? extends IChunk> owner,
493+
final IQueueExtent<?> owner,
485494
final IChunkSet set,
486495
final Runnable finalize
487496
) {

0 commit comments

Comments
 (0)