Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 17:46:31 +02:00
|
|
|
From a13d2700664c3333e72da26c2ea598c4cad882f2 Mon Sep 17 00:00:00 2001
|
2018-07-15 03:53:17 +02:00
|
|
|
From: Aikar <aikar@aikar.co>
|
|
|
|
Date: Thu, 3 Mar 2016 02:07:55 -0600
|
|
|
|
Subject: [PATCH] Optimize isValidLocation, getType and getBlockData for inling
|
|
|
|
|
|
|
|
Hot methods, so reduce # of instructions for the method.
|
|
|
|
|
|
|
|
Move is valid location test to the BlockPosition class so that it can access local variables.
|
|
|
|
|
|
|
|
Replace all calls to the new place to the unnecessary forward.
|
|
|
|
|
|
|
|
Optimize getType and getBlockData to manually inline and optimize the calls
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
|
2018-09-01 00:56:57 +02:00
|
|
|
index 4048937c63..680764b342 100644
|
2018-07-15 03:53:17 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
|
2018-09-01 00:56:57 +02:00
|
|
|
@@ -9,6 +9,14 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
|
2018-07-15 03:53:17 +02:00
|
|
|
private final int a;
|
|
|
|
private final int b;
|
|
|
|
private final int c;
|
|
|
|
+ // Paper start
|
|
|
|
+ public boolean isValidLocation() {
|
|
|
|
+ return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256;
|
|
|
|
+ }
|
|
|
|
+ public boolean isInvalidYLocation() {
|
|
|
|
+ return b < 0 || b >= 256;
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
public BaseBlockPosition(int i, int j, int k) {
|
|
|
|
this.a = i;
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
2018-09-01 00:56:57 +02:00
|
|
|
index 5ed34cf7e3..f4ed98d2d9 100644
|
2018-07-15 03:53:17 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
2018-09-01 00:56:57 +02:00
|
|
|
@@ -239,6 +239,16 @@ public class BlockPosition extends BaseBlockPosition {
|
2018-07-15 03:53:17 +02:00
|
|
|
protected int b;
|
|
|
|
protected int c;
|
|
|
|
protected int d;
|
|
|
|
+ // Paper start
|
|
|
|
+ @Override
|
|
|
|
+ public boolean isValidLocation() {
|
|
|
|
+ return b >= -30000000 && d >= -30000000 && b < 30000000 && d < 30000000 && c >= 0 && c < 256;
|
|
|
|
+ }
|
|
|
|
+ @Override
|
|
|
|
+ public boolean isInvalidYLocation() {
|
|
|
|
+ return c < 0 || c >= 256;
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
public MutableBlockPosition() {
|
|
|
|
this(0, 0, 0);
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 17:46:31 +02:00
|
|
|
index b006282f38..a36034cc52 100644
|
2018-07-15 03:53:17 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 17:46:31 +02:00
|
|
|
@@ -421,12 +421,24 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 03:53:17 +02:00
|
|
|
return this.getBlockData(i, j, k).b(this.world, new BlockPosition(i, j, k));
|
|
|
|
}
|
|
|
|
|
|
|
|
- public IBlockData getBlockData(BlockPosition blockposition) { return getType(blockposition); } // Paper
|
2018-08-26 20:11:49 +02:00
|
|
|
- public IBlockData getType(BlockPosition blockposition) {
|
2018-07-15 03:53:17 +02:00
|
|
|
+ // Paper start - Optimize getBlockData to reduce instructions
|
2018-08-26 20:11:49 +02:00
|
|
|
+ public final IBlockData getBlockData(BlockPosition pos) { return getBlockData(pos.getX(), pos.getY(), pos.getZ()); } // Paper
|
|
|
|
+ public final IBlockData getType(BlockPosition blockposition) {
|
2018-07-15 03:53:17 +02:00
|
|
|
return this.getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
|
|
|
}
|
|
|
|
|
|
|
|
- public IBlockData getBlockData(int i, int j, int k) {
|
|
|
|
+ public final IBlockData getBlockData(final int x, final int y, final int z) {
|
|
|
|
+ // Method body / logic copied from below
|
|
|
|
+ final int i = y >> 4;
|
|
|
|
+ if (y >= 0 && i < this.sections.length && this.sections[i] != null) {
|
|
|
|
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
|
|
|
|
+ return this.sections[i].blockIds.a((y & 15) << 8 | (z & 15) << 4 | x & 15);
|
|
|
|
+ }
|
|
|
|
+ return Blocks.AIR.getBlockData();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public IBlockData getBlockData_unused(int i, int j, int k) {
|
|
|
|
+ // Paper end
|
2018-08-26 20:11:49 +02:00
|
|
|
if (this.world.S() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
2018-07-15 03:53:17 +02:00
|
|
|
IBlockData iblockdata = null;
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
|
2018-09-01 00:56:57 +02:00
|
|
|
index 274c449480..7e4c79a1ce 100644
|
2018-07-15 03:53:17 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/ChunkSection.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
|
2018-09-01 00:56:57 +02:00
|
|
|
@@ -6,7 +6,7 @@ public class ChunkSection {
|
2018-07-15 03:53:17 +02:00
|
|
|
private int nonEmptyBlockCount;
|
|
|
|
private int tickingBlockCount;
|
|
|
|
private int e;
|
|
|
|
- private final DataPaletteBlock<IBlockData> blockIds;
|
|
|
|
+ final DataPaletteBlock<IBlockData> blockIds; // Paper - package
|
|
|
|
private NibbleArray emittedLight;
|
|
|
|
private NibbleArray skyLight;
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
2018-09-18 03:50:02 +02:00
|
|
|
index 275978de83..cad60e4f8b 100644
|
2018-07-15 03:53:17 +02:00
|
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
2018-08-26 20:11:49 +02:00
|
|
|
@@ -263,11 +263,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isValidLocation(BlockPosition blockposition) {
|
|
|
|
- return !k(blockposition) && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000;
|
|
|
|
+ return blockposition.isValidLocation(); // Paper
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean k(BlockPosition blockposition) {
|
|
|
|
- return blockposition.getY() < 0 || blockposition.getY() >= 256;
|
|
|
|
+ return blockposition.isInvalidYLocation(); // Paper
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isEmpty(BlockPosition blockposition) {
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -284,7 +284,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
// test if meets light level, return faster
|
|
|
|
// logic copied from below
|
|
|
|
public boolean isLightLevel(BlockPosition blockposition, int level) {
|
|
|
|
- if (isValidLocation(blockposition)) {
|
|
|
|
+ if (blockposition.isValidLocation()) {
|
|
|
|
if (this.getType(blockposition).c(this, blockposition)) {
|
|
|
|
int sky = getSkylightSubtracted();
|
|
|
|
if (this.getLightLevel(blockposition.up(), sky) >= level) {
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -331,7 +331,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
// CraftBukkit end
|
|
|
|
Chunk chunk = this.getChunkIfLoaded(blockposition);
|
|
|
|
if (chunk != null) {
|
|
|
|
- return isValidLocation(blockposition) ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData();
|
|
|
|
+ return blockposition.isValidLocation() ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); // Paper
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -386,7 +386,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
- if (k(blockposition)) {
|
2018-08-26 20:11:49 +02:00
|
|
|
+ if (blockposition.isInvalidYLocation()) { // Paper
|
2018-07-15 03:53:17 +02:00
|
|
|
return false;
|
|
|
|
} else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
|
|
|
return false;
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -707,11 +707,11 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ());
|
|
|
|
}
|
|
|
|
|
|
|
|
- return !isValidLocation(blockposition) ? enumskyblock.c : (!this.isLoaded(blockposition) ? enumskyblock.c : this.getChunkAtWorldCoords(blockposition).getBrightness(enumskyblock, blockposition));
|
|
|
|
+ return !blockposition.isValidLocation() ? enumskyblock.c : (!this.isLoaded(blockposition) ? enumskyblock.c : this.getChunkAtWorldCoords(blockposition).getBrightness(enumskyblock, blockposition)); // Paper
|
|
|
|
}
|
|
|
|
|
|
|
|
public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) {
|
|
|
|
- if (isValidLocation(blockposition)) {
|
|
|
|
+ if (blockposition.isValidLocation()) { // Paper
|
|
|
|
if (this.isLoaded(blockposition)) {
|
|
|
|
this.getChunkAtWorldCoords(blockposition).a(enumskyblock, blockposition, i);
|
|
|
|
this.m(blockposition);
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -738,7 +738,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// CraftBukkit end
|
|
|
|
- if (k(blockposition)) {
|
|
|
|
+ if (blockposition.isInvalidYLocation()) { // Paper
|
|
|
|
return Blocks.VOID_AIR.getBlockData();
|
|
|
|
} else {
|
|
|
|
Chunk chunk = this.getChunkAtWorldCoords(blockposition);
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -748,7 +748,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public Fluid b(BlockPosition blockposition) {
|
|
|
|
- if (k(blockposition)) {
|
|
|
|
+ if (blockposition.isInvalidYLocation()) { // Paper
|
|
|
|
return FluidTypes.a.i();
|
|
|
|
} else {
|
|
|
|
Chunk chunk = this.getChunkAtWorldCoords(blockposition);
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -1816,7 +1816,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
public Map<BlockPosition, TileEntity> capturedTileEntities = Maps.newHashMap();
|
|
|
|
@Nullable
|
|
|
|
public TileEntity getTileEntity(BlockPosition blockposition) {
|
|
|
|
- if (k(blockposition)) {
|
|
|
|
+ if (blockposition.isInvalidYLocation()) { // Paper
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
// CraftBukkit start
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -1857,7 +1857,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setTileEntity(BlockPosition blockposition, @Nullable TileEntity tileentity) {
|
|
|
|
- if (!k(blockposition)) {
|
|
|
|
+ if (!blockposition.isInvalidYLocation()) { // Paper
|
|
|
|
if (tileentity != null && !tileentity.x()) {
|
|
|
|
// CraftBukkit start
|
|
|
|
if (captureBlockStates) {
|
2018-09-18 03:50:02 +02:00
|
|
|
@@ -1918,7 +1918,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 03:53:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean p(BlockPosition blockposition) {
|
|
|
|
- if (k(blockposition)) {
|
|
|
|
+ if (blockposition.isInvalidYLocation()) { // Paper
|
|
|
|
return false;
|
|
|
|
} else {
|
2018-08-26 20:11:49 +02:00
|
|
|
Chunk chunk = this.chunkProvider.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, false, false);
|
2018-07-15 03:53:17 +02:00
|
|
|
--
|
2018-09-15 18:10:26 +02:00
|
|
|
2.19.0
|
2018-07-15 03:53:17 +02:00
|
|
|
|