mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-29 19:52:55 +01:00
c97ce029e9
PaperMC believes that 1.16.2 is now ready for general release as we fixed the main issue plagueing the 1.16.x release, the MapLike data conversion issues. Until now, it was not safe for a server to convert a world to 1.16.2 without data conversion issues around villages and potentially other things. If you did, those MapLike errors meant something went wrong. This is now resolved. Big thanks to all those that helped, notably @BillyGalbreath and @Proximyst who did large parts of the update process with me. Please as always, backup your worlds and test before updating to 1.16.2! If you update to 1.16.2, there is no going back to an older build than this. --------------------------------- Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com> Co-authored-by: Mariell Hoversholm <proximyst@proximyst.com> Co-authored-by: krolik-exe <69214078+krolik-exe@users.noreply.github.com> Co-authored-by: BillyGalbreath <BillyGalbreath@users.noreply.github.com> Co-authored-by: stonar96 <minecraft.stonar96@gmail.com> Co-authored-by: Shane Freeder <theboyetronic@gmail.com> Co-authored-by: Jason <jasonpenilla2@me.com> Co-authored-by: kashike <kashike@vq.lc> Co-authored-by: Aurora <21148213+aurorasmiles@users.noreply.github.com> Co-authored-by: KennyTV <kennytv@t-online.de> Co-authored-by: commandblockguy <commandblockguy1@gmail.com> Co-authored-by: DigitalRegent <misterwener@gmail.com> Co-authored-by: ishland <ishlandmc@yeah.net>
319 lines
16 KiB
Diff
319 lines
16 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
|
Date: Mon, 27 Apr 2020 04:05:38 -0700
|
|
Subject: [PATCH] Stop copy-on-write operations for updating light data
|
|
|
|
Causes huge memory allocations + gc issues
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/LightEngineStorage.java b/src/main/java/net/minecraft/server/LightEngineStorage.java
|
|
index 916d38cebcbe912153d54a21acbf60bc26db7401..6c7c4e75670a7e08ba10c0231a2510bf985dab6b 100644
|
|
--- a/src/main/java/net/minecraft/server/LightEngineStorage.java
|
|
+++ b/src/main/java/net/minecraft/server/LightEngineStorage.java
|
|
@@ -19,8 +19,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
|
protected final LongSet b = new LongOpenHashSet();
|
|
protected final LongSet c = new LongOpenHashSet();
|
|
protected final LongSet d = new LongOpenHashSet();
|
|
- protected volatile M e;
|
|
- protected final M f;
|
|
+ protected volatile M e_visible; protected final Object visibleUpdateLock = new Object(); // Paper - diff on change, should be "visible" - force compile fail on usage change
|
|
+ protected final M f; // Paper - diff on change, should be "updating"
|
|
protected final LongSet g = new LongOpenHashSet();
|
|
protected final LongSet h = new LongOpenHashSet();
|
|
protected final Long2ObjectMap<NibbleArray> i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap());
|
|
@@ -34,8 +34,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
|
this.l = enumskyblock;
|
|
this.m = ilightaccess;
|
|
this.f = m0;
|
|
- this.e = m0.b();
|
|
- this.e.d();
|
|
+ this.e_visible = m0.b(); // Paper - avoid copying light data
|
|
+ this.e_visible.d(); // Paper - avoid copying light data
|
|
}
|
|
|
|
protected boolean g(long i) {
|
|
@@ -44,7 +44,15 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
|
|
|
@Nullable
|
|
protected NibbleArray a(long i, boolean flag) {
|
|
- return this.a(flag ? this.f : this.e, i);
|
|
+ // Paper start - avoid copying light data
|
|
+ if (flag) {
|
|
+ return this.a(this.f, i);
|
|
+ } else {
|
|
+ synchronized (this.visibleUpdateLock) {
|
|
+ return this.a(this.e_visible, i);
|
|
+ }
|
|
+ }
|
|
+ // Paper end - avoid copying light data
|
|
}
|
|
|
|
@Nullable
|
|
@@ -357,10 +365,12 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
|
|
|
protected void e() {
|
|
if (!this.g.isEmpty()) {
|
|
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
|
|
M m0 = this.f.b();
|
|
|
|
m0.d();
|
|
- this.e = m0;
|
|
+ this.e_visible = m0; // Paper - avoid copying light data
|
|
+ } // Paper - avoid copying light data
|
|
this.g.clear();
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
|
index b978723a66d001f70325df0c7521025e079d7cfa..53199595da71a25710bd1ff8ee2868ee63edc0e1 100644
|
|
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
|
+++ b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
|
@@ -8,10 +8,23 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
|
private final long[] b = new long[2];
|
|
private final NibbleArray[] c = new NibbleArray[2];
|
|
private boolean d;
|
|
- protected final Long2ObjectOpenHashMap<NibbleArray> a;
|
|
-
|
|
- protected LightEngineStorageArray(Long2ObjectOpenHashMap<NibbleArray> long2objectopenhashmap) {
|
|
- this.a = long2objectopenhashmap;
|
|
+ protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> data; // Paper - avoid copying light data
|
|
+ protected final boolean isVisible; // Paper - avoid copying light data
|
|
+ java.util.function.Function<Long, NibbleArray> lookup; // Paper - faster branchless lookup
|
|
+
|
|
+ // Paper start - avoid copying light data
|
|
+ protected LightEngineStorageArray(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> data, boolean isVisible) {
|
|
+ if (isVisible) {
|
|
+ data.performUpdatesLockMap();
|
|
+ }
|
|
+ this.data = data;
|
|
+ this.isVisible = isVisible;
|
|
+ if (isVisible) {
|
|
+ lookup = data::getVisibleAsync;
|
|
+ } else {
|
|
+ lookup = data::getUpdating;
|
|
+ }
|
|
+ // Paper end - avoid copying light data
|
|
this.c();
|
|
this.d = true;
|
|
}
|
|
@@ -19,16 +32,17 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
|
public abstract M b();
|
|
|
|
public void a(long i) {
|
|
- this.a.put(i, ((NibbleArray) this.a.get(i)).b());
|
|
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
|
+ this.data.queueUpdate(i, ((NibbleArray) this.data.getUpdating(i)).b()); // Paper - avoid copying light data
|
|
this.c();
|
|
}
|
|
|
|
public boolean b(long i) {
|
|
- return this.a.containsKey(i);
|
|
+ return lookup.apply(i) != null; // Paper - avoid copying light data
|
|
}
|
|
|
|
@Nullable
|
|
- public NibbleArray c(long i) {
|
|
+ public final NibbleArray c(long i) { // Paper - final
|
|
if (this.d) {
|
|
for (int j = 0; j < 2; ++j) {
|
|
if (i == this.b[j]) {
|
|
@@ -37,7 +51,7 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
|
}
|
|
}
|
|
|
|
- NibbleArray nibblearray = (NibbleArray) this.a.get(i);
|
|
+ NibbleArray nibblearray = lookup.apply(i); // Paper - avoid copying light data
|
|
|
|
if (nibblearray == null) {
|
|
return null;
|
|
@@ -58,11 +72,13 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
|
|
|
@Nullable
|
|
public NibbleArray d(long i) {
|
|
- return (NibbleArray) this.a.remove(i);
|
|
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
|
+ return (NibbleArray) this.data.queueRemove(i); // Paper - avoid copying light data
|
|
}
|
|
|
|
public void a(long i, NibbleArray nibblearray) {
|
|
- this.a.put(i, nibblearray);
|
|
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
|
+ this.data.queueUpdate(i, nibblearray); // Paper - avoid copying light data
|
|
}
|
|
|
|
public void c() {
|
|
@@ -70,7 +86,6 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
|
this.b[i] = Long.MAX_VALUE;
|
|
this.c[i] = null;
|
|
}
|
|
-
|
|
}
|
|
|
|
public void d() {
|
|
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageBlock.java b/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
|
index 0f7f4744d9f9e5174fb38ccc72248397a4b064ea..292d8c742d3be41ba8ad7fb7f1251dc7f790b62b 100644
|
|
--- a/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
|
+++ b/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
|
@@ -5,7 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
public class LightEngineStorageBlock extends LightEngineStorage<LightEngineStorageBlock.a> {
|
|
|
|
protected LightEngineStorageBlock(ILightAccess ilightaccess) {
|
|
- super(EnumSkyBlock.BLOCK, ilightaccess, new LightEngineStorageBlock.a(new Long2ObjectOpenHashMap()));
|
|
+ super(EnumSkyBlock.BLOCK, ilightaccess, new LightEngineStorageBlock.a(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), false)); // Paper - avoid copying light data
|
|
}
|
|
|
|
@Override
|
|
@@ -18,13 +18,13 @@ public class LightEngineStorageBlock extends LightEngineStorage<LightEngineStora
|
|
|
|
public static final class a extends LightEngineStorageArray<LightEngineStorageBlock.a> {
|
|
|
|
- public a(Long2ObjectOpenHashMap<NibbleArray> long2objectopenhashmap) {
|
|
- super(long2objectopenhashmap);
|
|
+ public a(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> long2objectopenhashmap, boolean isVisible) { // Paper - avoid copying light data
|
|
+ super(long2objectopenhashmap, isVisible); // Paper - avoid copying light data
|
|
}
|
|
|
|
@Override
|
|
public LightEngineStorageBlock.a b() {
|
|
- return new LightEngineStorageBlock.a(this.a.clone());
|
|
+ return new a(this.data, true); // Paper - avoid copying light data
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageSky.java b/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
|
index 75d9065b32731dc635d9d09c48fb9643172381a9..7cec18fcfc311d20beca244c0affe5d6c1849e46 100644
|
|
--- a/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
|
+++ b/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
|
@@ -17,15 +17,16 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
private volatile boolean p;
|
|
|
|
protected LightEngineStorageSky(ILightAccess ilightaccess) {
|
|
- super(EnumSkyBlock.SKY, ilightaccess, new LightEngineStorageSky.a(new Long2ObjectOpenHashMap(), new Long2IntOpenHashMap(), Integer.MAX_VALUE));
|
|
+ super(EnumSkyBlock.SKY, ilightaccess, new LightEngineStorageSky.a(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int(), Integer.MAX_VALUE, false)); // Paper - avoid copying light data
|
|
}
|
|
|
|
@Override
|
|
protected int d(long i) {
|
|
long j = SectionPosition.e(i);
|
|
int k = SectionPosition.c(j);
|
|
- LightEngineStorageSky.a lightenginestoragesky_a = (LightEngineStorageSky.a) this.e;
|
|
- int l = lightenginestoragesky_a.c.get(SectionPosition.f(j));
|
|
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
|
|
+ LightEngineStorageSky.a lightenginestoragesky_a = (LightEngineStorageSky.a) this.e_visible; // Paper - avoid copying light data - must be after lock acquire
|
|
+ int l = lightenginestoragesky_a.otherData.getVisibleAsync(SectionPosition.f(j)); // Paper - avoid copying light data
|
|
|
|
if (l != lightenginestoragesky_a.b && k < l) {
|
|
NibbleArray nibblearray = this.a(lightenginestoragesky_a, j); // Paper - decompile fix
|
|
@@ -46,6 +47,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
} else {
|
|
return 15;
|
|
}
|
|
+ } // Paper - avoid copying light data
|
|
}
|
|
|
|
@Override
|
|
@@ -54,14 +56,14 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
|
|
if (((LightEngineStorageSky.a) this.f).b > j) {
|
|
((LightEngineStorageSky.a) this.f).b = j;
|
|
- ((LightEngineStorageSky.a) this.f).c.defaultReturnValue(((LightEngineStorageSky.a) this.f).b);
|
|
+ ((LightEngineStorageSky.a) this.f).otherData.queueDefaultReturnValue(((LightEngineStorageSky.a) this.f).b); // Paper - avoid copying light data
|
|
}
|
|
|
|
long k = SectionPosition.f(i);
|
|
- int l = ((LightEngineStorageSky.a) this.f).c.get(k);
|
|
+ int l = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(k); // Paper - avoid copying light data
|
|
|
|
if (l < j + 1) {
|
|
- ((LightEngineStorageSky.a) this.f).c.put(k, j + 1);
|
|
+ ((LightEngineStorageSky.a) this.f).otherData.queueUpdate(k, j + 1); // Paper - avoid copying light data
|
|
if (this.o.contains(k)) {
|
|
this.q(i);
|
|
if (l > ((LightEngineStorageSky.a) this.f).b) {
|
|
@@ -101,7 +103,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
|
|
int k = SectionPosition.c(i);
|
|
|
|
- if (((LightEngineStorageSky.a) this.f).c.get(j) == k + 1) {
|
|
+ if (((LightEngineStorageSky.a) this.f).otherData.getUpdating(j) == k + 1) { // Paper - avoid copying light data
|
|
long l;
|
|
|
|
for (l = i; !this.g(l) && this.a(k); l = SectionPosition.a(l, EnumDirection.DOWN)) {
|
|
@@ -109,12 +111,12 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
}
|
|
|
|
if (this.g(l)) {
|
|
- ((LightEngineStorageSky.a) this.f).c.put(j, k + 1);
|
|
+ ((LightEngineStorageSky.a) this.f).otherData.queueUpdate(j, k + 1); // Paper - avoid copying light data
|
|
if (flag) {
|
|
this.q(l);
|
|
}
|
|
} else {
|
|
- ((LightEngineStorageSky.a) this.f).c.remove(j);
|
|
+ ((LightEngineStorageSky.a) this.f).otherData.queueRemove(j); // Paper - avoid copying light data
|
|
}
|
|
}
|
|
|
|
@@ -128,7 +130,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
protected void b(long i, boolean flag) {
|
|
this.d();
|
|
if (flag && this.o.add(i)) {
|
|
- int j = ((LightEngineStorageSky.a) this.f).c.get(i);
|
|
+ int j = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(i); // Paper - avoid copying light data
|
|
|
|
if (j != ((LightEngineStorageSky.a) this.f).b) {
|
|
long k = SectionPosition.b(SectionPosition.b(i), j - 1, SectionPosition.d(i));
|
|
@@ -155,7 +157,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
return nibblearray;
|
|
} else {
|
|
long j = SectionPosition.a(i, EnumDirection.UP);
|
|
- int k = ((LightEngineStorageSky.a) this.f).c.get(SectionPosition.f(i));
|
|
+ int k = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(SectionPosition.f(i)); // Paper - avoid copying light data
|
|
|
|
if (k != ((LightEngineStorageSky.a) this.f).b && SectionPosition.c(j) < k) {
|
|
NibbleArray nibblearray1;
|
|
@@ -298,7 +300,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
if (!this.o.contains(l)) {
|
|
return false;
|
|
} else {
|
|
- int i1 = ((LightEngineStorageSky.a) this.f).c.get(l);
|
|
+ int i1 = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(l); // Paper - avoid copying light data
|
|
|
|
return SectionPosition.c(i1) == j + 16;
|
|
}
|
|
@@ -307,7 +309,7 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
|
|
protected boolean n(long i) {
|
|
long j = SectionPosition.f(i);
|
|
- int k = ((LightEngineStorageSky.a) this.f).c.get(j);
|
|
+ int k = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(j); // Paper - avoid copying light data
|
|
|
|
return k == ((LightEngineStorageSky.a) this.f).b || SectionPosition.c(i) >= k;
|
|
}
|
|
@@ -321,18 +323,21 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
|
public static final class a extends LightEngineStorageArray<LightEngineStorageSky.a> {
|
|
|
|
private int b;
|
|
- private final Long2IntOpenHashMap c;
|
|
-
|
|
- public a(Long2ObjectOpenHashMap<NibbleArray> long2objectopenhashmap, Long2IntOpenHashMap long2intopenhashmap, int i) {
|
|
- super(long2objectopenhashmap);
|
|
- this.c = long2intopenhashmap;
|
|
- long2intopenhashmap.defaultReturnValue(i);
|
|
+ private final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData; // Paper - avoid copying light data
|
|
+
|
|
+ // Paper start - avoid copying light data
|
|
+ public a(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> data, com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData, int i, boolean isVisible) {
|
|
+ super(data, isVisible);
|
|
+ this.otherData = otherData;
|
|
+ otherData.queueDefaultReturnValue(i);
|
|
+ // Paper end - avoid copying light data
|
|
this.b = i;
|
|
}
|
|
|
|
@Override
|
|
public LightEngineStorageSky.a b() {
|
|
- return new LightEngineStorageSky.a(this.a.clone(), this.c.clone(), this.b);
|
|
+ this.otherData.performUpdatesLockMap(); // Paper - avoid copying light data
|
|
+ return new LightEngineStorageSky.a(this.data, this.otherData, this.b, true); // Paper - avoid copying light data
|
|
}
|
|
}
|
|
}
|