From 42346b429b7365aaf0c670286a3c40f8a20bd0dd Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 1 Jan 2021 16:48:17 +0000 Subject: [PATCH] Don't synchronise across the entire edit for a single ChunkSection load (speed boost) --- .../mc1_15_2/BukkitGetBlocks_1_15_2.java | 2 +- .../mc1_16_1/BukkitGetBlocks_1_16_1.java | 2 +- .../mc1_16_2/BukkitGetBlocks_1_16_2.java | 2 +- .../mc1_16_4/BukkitGetBlocks_1_16_4.java | 2 +- .../implementation/blocks/CharBlocks.java | 34 +++++++++++++++---- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java index f078eb9a0..b6b2380a2 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_15_2/BukkitGetBlocks_1_15_2.java @@ -825,7 +825,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java index 63ad1dada..3a5a68338 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_1/BukkitGetBlocks_1_16_1.java @@ -827,7 +827,7 @@ public class BukkitGetBlocks_1_16_1 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java index f22000616..5a8873114 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_2/BukkitGetBlocks_1_16_2.java @@ -830,7 +830,7 @@ public class BukkitGetBlocks_1_16_2 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java index 1282a8d45..8fb195641 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/mc1_16_4/BukkitGetBlocks_1_16_4.java @@ -830,7 +830,7 @@ public class BukkitGetBlocks_1_16_4 extends CharGetBlocks { return super.trim(true); } else { for (int i = 0; i < 16; i++) { - if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) { + if (!hasSection(i) || !super.sections[i].isFull()) { continue; } ChunkSection existing = getSections(true)[i]; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java index 52ddbb1e7..d17613e18 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharBlocks.java @@ -9,17 +9,24 @@ import org.jetbrains.annotations.Range; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; + public abstract class CharBlocks implements IBlocks { public static final Logger logger = LoggerFactory.getLogger(CharBlocks.class); - public static final Section FULL = new Section() { + protected final Section FULL = new Section() { @Override public final char[] get(CharBlocks blocks, int layer) { return blocks.blocks[layer]; } + + @Override + public final boolean isFull() { + return true; + } }; - public static final Section EMPTY = new Section() { + protected final Section EMPTY = new Section() { @Override public final synchronized char[] get(CharBlocks blocks, int layer) { char[] arr = blocks.blocks[layer]; @@ -39,15 +46,22 @@ public abstract class CharBlocks implements IBlocks { } return arr; } + + @Override + public final boolean isFull() { + return false; + } }; public final char[][] blocks; public final Section[] sections; + private final Object[] loadLock = new Object[16]; public CharBlocks() { blocks = new char[16][]; sections = new Section[16]; for (int i = 0; i < 16; i++) { sections[i] = EMPTY; + loadLock[i] = new Object(); } } @@ -55,7 +69,7 @@ public abstract class CharBlocks implements IBlocks { public boolean trim(boolean aggressive) { boolean result = true; for (int i = 0; i < 16; i++) { - if (sections[i] == EMPTY && blocks[i] != null) { + if (!sections[i].isFull() && blocks[i] != null) { blocks[i] = null; } else { result = false; @@ -67,7 +81,7 @@ public abstract class CharBlocks implements IBlocks { @Override public boolean trim(boolean aggressive, int layer) { boolean result = true; - if (sections[layer] == EMPTY && blocks[layer] != null) { + if (!sections[layer].isFull() && blocks[layer] != null) { blocks[layer] = null; } else { result = false; @@ -99,12 +113,18 @@ public abstract class CharBlocks implements IBlocks { @Override public boolean hasSection(@Range(from = 0, to = 15) int layer) { - return sections[layer] == FULL; + return sections[layer].isFull(); } @Override public char[] load(@Range(from = 0, to = 15) int layer) { - return sections[layer].get(this, layer); + Section section = sections[layer]; + if (section.isFull()) { + return section.get(this, layer); + } + synchronized (loadLock[layer]) { + return sections[layer].get(this, layer); + } } @Override @@ -149,6 +169,8 @@ public abstract class CharBlocks implements IBlocks { public abstract char[] get(CharBlocks blocks, @Range(from = 0, to = 15) int layer); + public abstract boolean isFull(); + public final char get(CharBlocks blocks, @Range(from = 0, to = 15) int layer, int index) { return get(blocks, layer)[index]; }