Improve Structures Checking
Improves performance by keying every chunk thats part of a structure to a hashmap instead of only the first one. This allows us to avoid iterating the entire structures value set to see if a block position is inside of a structure. This should have pretty decent performance improvement to any standard world that has been around for a whilewith lots of structures due to ineffeciencies in how MC stores structures (even unloaded chunks has structured data loaded)
This commit is contained in:
parent
e04bef9785
commit
0f2c274998
|
@ -1,4 +1,4 @@
|
||||||
From 512e126bf403f6ed82dcf54491fe3357a8430464 Mon Sep 17 00:00:00 2001
|
From f12d521a85a8487c53f0c0545a7c1aa6fd2953ed Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Mon, 28 Mar 2016 20:55:47 -0400
|
Date: Mon, 28 Mar 2016 20:55:47 -0400
|
||||||
Subject: [PATCH] MC Utils
|
Subject: [PATCH] MC Utils
|
||||||
|
@ -25,6 +25,19 @@ index 4bbebb25a..c4d9344a7 100644
|
||||||
@Nullable
|
@Nullable
|
||||||
public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
|
public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) {
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||||
|
index 239440888..aafd23beb 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||||
|
@@ -15,6 +15,8 @@ public class ChunkCoordIntPair {
|
||||||
|
this.z = blockposition.getZ() >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public static long asLong(final BlockPosition pos) { return a(pos.getX() >> 4, pos.getZ() >> 4); } // Paper - OBFHELPER
|
||||||
|
+ public static long asLong(int x, int z) { return a(x, z); } // Paper - OBFHELPER
|
||||||
|
public static long a(int i, int j) {
|
||||||
|
return (long) i & 4294967295L | ((long) j & 4294967295L) << 32;
|
||||||
|
}
|
||||||
diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||||
index 1f2fe87b6..2cb462b8e 100644
|
index 1f2fe87b6..2cb462b8e 100644
|
||||||
--- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
--- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||||
|
@ -299,5 +312,5 @@ index 8cede938a..cd2d58bfb 100644
|
||||||
return System.nanoTime() / 1000000L;
|
return System.nanoTime() / 1000000L;
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.14.3
|
2.15.0
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
From e610c7b15e2671e15ed2c59c617dfe5240fb9c13 Mon Sep 17 00:00:00 2001
|
From 456890d91c1d97836f3c67cf40acdfa724ac6745 Mon Sep 17 00:00:00 2001
|
||||||
From: Aikar <aikar@aikar.co>
|
From: Aikar <aikar@aikar.co>
|
||||||
Date: Thu, 3 Mar 2016 04:00:11 -0600
|
Date: Thu, 3 Mar 2016 04:00:11 -0600
|
||||||
Subject: [PATCH] Timings v2
|
Subject: [PATCH] Timings v2
|
||||||
|
@ -1086,7 +1086,7 @@ index c00aee885..b3356b40f 100644
|
||||||
|
|
||||||
public void addWhitelist(GameProfile gameprofile) {
|
public void addWhitelist(GameProfile gameprofile) {
|
||||||
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
|
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
index 74e3f42cd..2580a4cf6 100644
|
index 74e3f42cd..66a80a776 100644
|
||||||
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
|
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
|
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
@@ -1,5 +1,7 @@
|
@@ -1,5 +1,7 @@
|
||||||
|
@ -1906,5 +1906,5 @@ index 2bd690fdf..38be7ed71 100644
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.14.3
|
2.15.0
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,9 @@
|
||||||
From 635b62974365f6ae0b039790b1725092c4508043 Mon Sep 17 00:00:00 2001
|
From 96892dd268a65e7af2375a9ccd7a2286dcbfa162 Mon Sep 17 00:00:00 2001
|
||||||
From: mezz <tehgeek@gmail.com>
|
From: mezz <tehgeek@gmail.com>
|
||||||
Date: Wed, 9 Aug 2017 17:51:22 -0500
|
Date: Wed, 9 Aug 2017 17:51:22 -0500
|
||||||
Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike
|
Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike
|
||||||
|
|
||||||
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
|
||||||
index 239440888..e8d1a1c60 100644
|
|
||||||
--- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
|
||||||
+++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
|
||||||
@@ -15,6 +15,7 @@ public class ChunkCoordIntPair {
|
|
||||||
this.z = blockposition.getZ() >> 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ public static long asLong(int x, int z) { return a(x, z); } // Paper - OBFHELPER
|
|
||||||
public static long a(int i, int j) {
|
|
||||||
return (long) i & 4294967295L | ((long) j & 4294967295L) << 32;
|
|
||||||
}
|
|
||||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||||
index 30cf4a251..f690aaa10 100644
|
index 30cf4a251..f690aaa10 100644
|
||||||
--- a/src/main/java/net/minecraft/server/World.java
|
--- a/src/main/java/net/minecraft/server/World.java
|
||||||
|
@ -34,5 +22,5 @@ index 30cf4a251..f690aaa10 100644
|
||||||
this.tileEntityListUnload.clear();
|
this.tileEntityListUnload.clear();
|
||||||
}
|
}
|
||||||
--
|
--
|
||||||
2.14.2
|
2.15.0
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
From bbe1d20e6fb529ca5dcf54c45f77894badaf5a1b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Aikar <aikar@aikar.co>
|
||||||
|
Date: Sat, 11 Nov 2017 17:57:39 -0500
|
||||||
|
Subject: [PATCH] Improve Structures Checking
|
||||||
|
|
||||||
|
Improves performance by keying every chunk thats part of a structure to a hashmap
|
||||||
|
instead of only the first one.
|
||||||
|
|
||||||
|
This allows us to avoid iterating the entire structures value set to see
|
||||||
|
if a block position is inside of a structure.
|
||||||
|
|
||||||
|
This should have pretty decent performance improvement to any standard world
|
||||||
|
that has been around for a whilewith lots of structures due to ineffeciencies
|
||||||
|
in how MC stores structures (even unloaded chunks has structured data loaded)
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/StructureBoundingBox.java b/src/main/java/net/minecraft/server/StructureBoundingBox.java
|
||||||
|
index db419cd99..d9329bd42 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/StructureBoundingBox.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/StructureBoundingBox.java
|
||||||
|
@@ -4,12 +4,14 @@ import com.google.common.base.MoreObjects;
|
||||||
|
|
||||||
|
public class StructureBoundingBox {
|
||||||
|
|
||||||
|
- public int a;
|
||||||
|
- public int b;
|
||||||
|
- public int c;
|
||||||
|
- public int d;
|
||||||
|
- public int e;
|
||||||
|
- public int f;
|
||||||
|
+ public int a; // Paper - If changes, verify low/high getters
|
||||||
|
+ public int b; // Paper - If changes, verify low/high getters
|
||||||
|
+ public int c; // Paper - If changes, verify low/high getters
|
||||||
|
+ public int d; // Paper - If changes, verify low/high getters
|
||||||
|
+ public int e; // Paper - If changes, verify low/high getters
|
||||||
|
+ public int f; // Paper - If changes, verify low/high getters
|
||||||
|
+ public BaseBlockPosition getLowPosition() { return new BaseBlockPosition(a, b, c); } // Paper
|
||||||
|
+ public BaseBlockPosition getHighPosition() { return new BaseBlockPosition(d, e, f); } // Paper
|
||||||
|
|
||||||
|
public StructureBoundingBox() {}
|
||||||
|
|
||||||
|
@@ -114,6 +116,7 @@ public class StructureBoundingBox {
|
||||||
|
this.f += k;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public boolean contains(BaseBlockPosition baseblockposition) { return b(baseblockposition); } // Paper - OBFHELPER
|
||||||
|
public boolean b(BaseBlockPosition baseblockposition) {
|
||||||
|
return baseblockposition.getX() >= this.a && baseblockposition.getX() <= this.d && baseblockposition.getZ() >= this.c && baseblockposition.getZ() <= this.f && baseblockposition.getY() >= this.b && baseblockposition.getY() <= this.e;
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
|
index e8263baa4..09e49221d 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||||
|
@@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||||
|
import java.util.Iterator;
|
||||||
|
+import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
@@ -14,6 +15,7 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
private final Timing timing = MinecraftTimings.getStructureTiming(this); // Paper
|
||||||
|
private PersistentStructure a;
|
||||||
|
protected Long2ObjectMap<StructureStart> c = new Long2ObjectOpenHashMap(1024);
|
||||||
|
+ protected Long2ObjectMap<StructureStart> allStructures = new Long2ObjectOpenHashMap(1024); // Paper - Holds ref to structures for every chunk its part of, where as the one above this only holds the vanilla oriented ones.
|
||||||
|
|
||||||
|
public StructureGenerator() {}
|
||||||
|
|
||||||
|
@@ -29,6 +31,7 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
if (this.a(i, j)) {
|
||||||
|
StructureStart structurestart = this.b(i, j);
|
||||||
|
|
||||||
|
+ populateStructure(structurestart); // Paper
|
||||||
|
this.c.put(ChunkCoordIntPair.a(i, j), structurestart);
|
||||||
|
if (structurestart.a()) {
|
||||||
|
this.a(i, j, structurestart);
|
||||||
|
@@ -106,6 +109,19 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
protected StructureStart c(BlockPosition blockposition) {
|
||||||
|
+ // Paper start - replace method
|
||||||
|
+ StructureStart structureStart = allStructures.get(ChunkCoordIntPair.asLong(blockposition));
|
||||||
|
+ if (structureStart != null && structureStart.isSizeable() && structureStart.getBoundingBox().contains(blockposition)) {
|
||||||
|
+ List<StructurePiece> structurePieces = structureStart.getStructurePieces();
|
||||||
|
+ for (StructurePiece piece : structurePieces) {
|
||||||
|
+ if (piece.getBoundingBox().contains(blockposition)) {
|
||||||
|
+ return structureStart;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return null;
|
||||||
|
+ /*
|
||||||
|
ObjectIterator objectiterator = this.c.values().iterator();
|
||||||
|
|
||||||
|
while (objectiterator.hasNext()) {
|
||||||
|
@@ -125,11 +141,16 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
+ */
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean a(World world, BlockPosition blockposition) {
|
||||||
|
if (this.g == null) return false; // Paper
|
||||||
|
this.a(world);
|
||||||
|
+ // Paper start - Replace method
|
||||||
|
+ StructureStart structureStart = this.allStructures.get(ChunkCoordIntPair.asLong(blockposition));
|
||||||
|
+ return structureStart != null && structureStart.isSizeable() && structureStart.getBoundingBox().contains(blockposition);
|
||||||
|
+ /* // comment out rest
|
||||||
|
ObjectIterator objectiterator = this.c.values().iterator();
|
||||||
|
|
||||||
|
StructureStart structurestart;
|
||||||
|
@@ -142,7 +163,7 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
structurestart = (StructureStart) objectiterator.next();
|
||||||
|
} while (!structurestart.a() || !structurestart.b().b((BaseBlockPosition) blockposition));
|
||||||
|
|
||||||
|
- return true;
|
||||||
|
+ return true;*/ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@@ -177,6 +198,7 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
StructureStart structurestart = WorldGenFactory.a(nbttagcompound1, world);
|
||||||
|
|
||||||
|
if (structurestart != null) {
|
||||||
|
+ populateStructure(structurestart); // Paper
|
||||||
|
this.c.put(ChunkCoordIntPair.a(i, j), structurestart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -187,6 +209,27 @@ public abstract class StructureGenerator extends WorldGenBase {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ private void populateStructure(StructureStart structurestart) {
|
||||||
|
+ for (StructurePiece piece : structurestart.getStructurePieces()) {
|
||||||
|
+ populateStructure(structurestart, piece.getBoundingBox());
|
||||||
|
+ }
|
||||||
|
+ populateStructure(structurestart, structurestart.getBoundingBox());
|
||||||
|
+ }
|
||||||
|
+ private void populateStructure(StructureStart structurestart, StructureBoundingBox bb) {
|
||||||
|
+ if (bb == null) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ final BaseBlockPosition low = bb.getLowPosition();
|
||||||
|
+ final BaseBlockPosition high = bb.getHighPosition();
|
||||||
|
+ for (int x = low.getX() >> 4, maxX = high.getX() >> 4; x < maxX; x++) {
|
||||||
|
+ for (int z = low.getZ() >> 4, maxZ = high.getZ() >> 4; z < maxZ; z++) {
|
||||||
|
+ allStructures.put(ChunkCoordIntPair.asLong(x, z), structurestart);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
private void a(int i, int j, StructureStart structurestart) {
|
||||||
|
this.a.a(structurestart.a(i, j), i, j);
|
||||||
|
this.a.c();
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/StructurePiece.java b/src/main/java/net/minecraft/server/StructurePiece.java
|
||||||
|
index 93903bc67..fcc13f811 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/StructurePiece.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/StructurePiece.java
|
||||||
|
@@ -53,6 +53,7 @@ public abstract class StructurePiece {
|
||||||
|
|
||||||
|
public abstract boolean a(World world, Random random, StructureBoundingBox structureboundingbox);
|
||||||
|
|
||||||
|
+ public StructureBoundingBox getBoundingBox() { return d(); } // Paper - OBFHELPER
|
||||||
|
public StructureBoundingBox d() {
|
||||||
|
return this.l;
|
||||||
|
}
|
||||||
|
diff --git a/src/main/java/net/minecraft/server/StructureStart.java b/src/main/java/net/minecraft/server/StructureStart.java
|
||||||
|
index b6abc74e0..f9bb953d0 100644
|
||||||
|
--- a/src/main/java/net/minecraft/server/StructureStart.java
|
||||||
|
+++ b/src/main/java/net/minecraft/server/StructureStart.java
|
||||||
|
@@ -19,10 +19,12 @@ public abstract class StructureStart {
|
||||||
|
this.d = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public StructureBoundingBox getBoundingBox() { return b(); } // Paper - OBFHELPER
|
||||||
|
public StructureBoundingBox b() {
|
||||||
|
return this.b;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ public List<StructurePiece> getStructurePieces() { return c(); } // Paper - OBFHELPER
|
||||||
|
public List<StructurePiece> c() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
@@ -137,7 +139,7 @@ public abstract class StructureStart {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- public boolean a() {
|
||||||
|
+ public boolean isSizeable() { return a(); } public boolean a() { // Paper - OBFHELPER
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.15.0
|
||||||
|
|
|
@ -93,6 +93,9 @@ import PlayerConnectionUtils
|
||||||
import RegionFile
|
import RegionFile
|
||||||
import RegistryBlockID
|
import RegistryBlockID
|
||||||
import RemoteControlListener
|
import RemoteControlListener
|
||||||
|
import StructureBoundingBox
|
||||||
|
import StructurePiece
|
||||||
|
import StructureStart
|
||||||
import TileEntityEnderChest
|
import TileEntityEnderChest
|
||||||
import TileEntityLootable
|
import TileEntityLootable
|
||||||
import WorldGenStronghold
|
import WorldGenStronghold
|
||||||
|
|
Loading…
Reference in New Issue