Skip to content

Commit

Permalink
fix: fix the bug that access light data in multi-thread environment m…
Browse files Browse the repository at this point in the history
…ay cause `IndexOutOfBoundsException`
  • Loading branch information
smartcmd committed Jan 7, 2025
1 parent d31ce21 commit afd3afe
Showing 1 changed file with 13 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import com.google.common.base.Preconditions;
import io.netty.util.internal.PlatformDependent;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import org.allaymc.api.block.data.BlockFace;
Expand All @@ -16,6 +14,7 @@
import org.allaymc.api.world.chunk.Chunk;
import org.allaymc.api.world.service.LightService;
import org.allaymc.server.datastruct.ChunkSectionNibbleArray;
import org.allaymc.server.datastruct.collections.nb.Long2ObjectNonBlockingMap;
import org.allaymc.server.datastruct.collections.queue.BlockingQueueWrapper;
import org.allaymc.server.world.HeightMap;
import org.allaymc.server.world.chunk.AllayUnsafeChunk;
Expand All @@ -41,11 +40,11 @@ public class AllayLightService implements LightService {
// TODO(memory): use a more memory-efficient queue, for example a long queue
protected final BlockingQueueWrapper<Runnable> queue;
protected final LongSet chunks;
protected final Long2ObjectMap<ChunkSectionNibbleArray[]> lightDampening;
protected final Long2ObjectMap<ChunkSectionNibbleArray[]> blockLight;
protected final Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> lightDampening;
protected final Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> blockLight;
protected final LightPropagator blockLightPropagator;
protected Long2ObjectMap<HeightMap> lightHeightMap;
protected Long2ObjectMap<ChunkSectionNibbleArray[]> skyLight;
protected Long2ObjectNonBlockingMap<HeightMap> lightHeightMap;
protected Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> skyLight;
protected LightPropagator skyLightPropagator;

public AllayLightService(Dimension dimension) {
Expand All @@ -62,12 +61,12 @@ public AllayLightService(DimensionInfo dimensionInfo, Supplier<Integer> timeSupp
this.hasSkyLight = dimensionInfo.hasSkyLight();
this.queue = BlockingQueueWrapper.wrap(PlatformDependent.newMpscQueue());
this.chunks = new LongOpenHashSet();
this.lightDampening = new Long2ObjectOpenHashMap<>();
this.blockLight = new Long2ObjectOpenHashMap<>();
this.lightDampening = new Long2ObjectNonBlockingMap<>();
this.blockLight = new Long2ObjectNonBlockingMap<>();
this.blockLightPropagator = new LightPropagator(new BlockLightAccessor());
if (hasSkyLight) {
this.lightHeightMap = new Long2ObjectOpenHashMap<>();
this.skyLight = new Long2ObjectOpenHashMap<>();
this.lightHeightMap = new Long2ObjectNonBlockingMap<>();
this.skyLight = new Long2ObjectNonBlockingMap<>();
this.skyLightPropagator = new LightPropagator(new SkyLightAccessor());
}
}
Expand Down Expand Up @@ -275,13 +274,13 @@ protected int getLightDampening(int x, int y, int z) {
return get(lightDampening, x, y, z, 0);
}

protected int getWithoutCheck(Long2ObjectMap<ChunkSectionNibbleArray[]> target, int x, int y, int z) {
protected int getWithoutCheck(Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> target, int x, int y, int z) {
var hash = HashUtils.hashXZ(x >> 4, z >> 4);
var array = target.get(hash);
return array[(y - minHeight) >> 4].get(x & 15, y & 15, z & 15);
}

protected int get(Long2ObjectMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int defaultValue) {
protected int get(Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int defaultValue) {
var hash = HashUtils.hashXZ(x >> 4, z >> 4);
if (!chunks.contains(hash)) {
return defaultValue;
Expand Down Expand Up @@ -313,7 +312,7 @@ protected void setLightDampening(int x, int y, int z, int value) {
}
}

protected void set(Long2ObjectMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int value) {
protected void set(Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int value) {
var hash = HashUtils.hashXZ(x >> 4, z >> 4);
if (!chunks.contains(hash)) {
return;
Expand All @@ -322,7 +321,7 @@ protected void set(Long2ObjectMap<ChunkSectionNibbleArray[]> target, int x, int
array[(y - minHeight) >> 4].set(x & 15, y & 15, z & 15, value);
}

protected void setWithoutCheck(Long2ObjectMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int value) {
protected void setWithoutCheck(Long2ObjectNonBlockingMap<ChunkSectionNibbleArray[]> target, int x, int y, int z, int value) {
var hash = HashUtils.hashXZ(x >> 4, z >> 4);
var array = target.get(hash);
array[(y - minHeight) >> 4].set(x & 15, y & 15, z & 15, value);
Expand Down

0 comments on commit afd3afe

Please sign in to comment.