Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-09-06 16:12:51 +02:00
Trim performance (#451)
* Increase performance slightly when trimming. If the chunk section is all one blocks (common in plotworlds) it'll be a nice little boost. * Cache whether blocks are ticking or not. Greatly reduces the time required to create a palette * collapse 5 lines to 2. * Also apply to 14 and 15 for the numpties * Cleanup Actually ignore the exception - remove my debug print. Remove double semi-colon * Apparently 1.14/15 matter too still.
Dieser Commit ist enthalten in:
Ursprung
a2b0a5e622
Commit
56972ee40b
@ -4,6 +4,7 @@ import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.block.BlockID;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
@ -49,6 +50,8 @@ public class NMSAdapter {
|
||||
int air = 0;
|
||||
int num_palette = 0;
|
||||
char[] getArr = null;
|
||||
char lastOrdinal = BlockID.__RESERVED__;
|
||||
boolean lastticking = false;
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
char ordinal = set[i];
|
||||
switch (ordinal) {
|
||||
@ -75,8 +78,16 @@ public class NMSAdapter {
|
||||
air++;
|
||||
break;
|
||||
}
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
if (state.getMaterial().isTicksRandomly()) {
|
||||
boolean ticking;
|
||||
if (ordinal != lastOrdinal) {
|
||||
ticking = BlockTypesCache.ticking[ordinal];
|
||||
lastOrdinal = ordinal;
|
||||
lastticking = ticking;
|
||||
} else {
|
||||
ticking = lastticking;
|
||||
}
|
||||
if (ticking) {
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
ticking_blocks.put(BlockVector3.at(i & 15, (i >> 8) & 15, (i >> 4) & 15),
|
||||
WorldEditPlugin.getInstance().getBukkitImplAdapter()
|
||||
.getInternalBlockStateId(state).orElse(0));
|
||||
|
@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||
@ -620,7 +621,37 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
|
||||
if (aggressive) {
|
||||
sections = null;
|
||||
nmsChunk = null;
|
||||
return super.trim(true);
|
||||
} else {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||
continue;
|
||||
}
|
||||
ChunkSection existing = getSections()[i];
|
||||
try {
|
||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||
|
||||
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_14.fieldPalette.get(blocksExisting);
|
||||
int paletteSize;
|
||||
|
||||
if (palette instanceof DataPaletteLinear) {
|
||||
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||
} else if (palette instanceof DataPaletteHash) {
|
||||
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||
} else {
|
||||
super.trim(false, i);
|
||||
continue;
|
||||
}
|
||||
if (paletteSize == 1) {
|
||||
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||
continue;
|
||||
}
|
||||
super.trim(false, i);
|
||||
} catch (IllegalAccessException ignored) {
|
||||
super.trim(false, i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.trim(aggressive);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||
@ -640,7 +641,37 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
|
||||
if (aggressive) {
|
||||
sections = null;
|
||||
nmsChunk = null;
|
||||
return super.trim(true);
|
||||
} else {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||
continue;
|
||||
}
|
||||
ChunkSection existing = getSections()[i];
|
||||
try {
|
||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||
|
||||
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_15.fieldPalette.get(blocksExisting);
|
||||
int paletteSize;
|
||||
|
||||
if (palette instanceof DataPaletteLinear) {
|
||||
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||
} else if (palette instanceof DataPaletteHash) {
|
||||
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||
} else {
|
||||
super.trim(false, i);
|
||||
continue;
|
||||
}
|
||||
if (paletteSize == 1) {
|
||||
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||
continue;
|
||||
}
|
||||
super.trim(false, i);
|
||||
} catch (IllegalAccessException ignored) {
|
||||
super.trim(false, i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.trim(aggressive);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.bukkit.adapter.mc1_15_2;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharBlocks;
|
||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
||||
import com.boydti.fawe.bukkit.adapter.DelegateLock;
|
||||
@ -644,7 +645,37 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
|
||||
if (aggressive) {
|
||||
sections = null;
|
||||
nmsChunk = null;
|
||||
return super.trim(true);
|
||||
} else {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (!hasSection(i) || super.sections[i] == CharBlocks.EMPTY) {
|
||||
continue;
|
||||
}
|
||||
ChunkSection existing = getSections()[i];
|
||||
try {
|
||||
final DataPaletteBlock<IBlockData> blocksExisting = existing.getBlocks();
|
||||
|
||||
final DataPalette<IBlockData> palette = (DataPalette<IBlockData>) BukkitAdapter_1_15_2.fieldPalette.get(blocksExisting);
|
||||
int paletteSize;
|
||||
|
||||
if (palette instanceof DataPaletteLinear) {
|
||||
paletteSize = ((DataPaletteLinear<IBlockData>) palette).b();
|
||||
} else if (palette instanceof DataPaletteHash) {
|
||||
paletteSize = ((DataPaletteHash<IBlockData>) palette).b();
|
||||
} else {
|
||||
super.trim(false, i);
|
||||
continue;
|
||||
}
|
||||
if (paletteSize == 1) {
|
||||
//If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks.
|
||||
continue;
|
||||
}
|
||||
super.trim(false, i);
|
||||
} catch (IllegalAccessException ignored) {
|
||||
super.trim(false, i);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return super.trim(aggressive);
|
||||
}
|
||||
}
|
||||
|
@ -145,4 +145,9 @@ public class CombinedBlocks implements IBlocks {
|
||||
public boolean trim(boolean aggressive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ public interface IBlocks extends Trimable {
|
||||
.map(layer -> (1 << layer)).sum();
|
||||
}
|
||||
|
||||
boolean trim(boolean aggressive, int layer);
|
||||
|
||||
IBlocks reset();
|
||||
|
||||
default byte[] toByteArray(boolean full) {
|
||||
|
@ -153,4 +153,9 @@ public class BitSetBlocks implements IChunkSet {
|
||||
public boolean trim(boolean aggressive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,17 @@ public abstract class CharBlocks implements IBlocks {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
boolean result = true;
|
||||
if (sections[layer] == EMPTY && blocks[layer] != null) {
|
||||
blocks[layer] = null;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkSet reset() {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
|
@ -25,6 +25,13 @@ public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
sections[layer] = EMPTY;
|
||||
blocks[layer] = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IChunkSet reset() {
|
||||
super.reset();
|
||||
|
@ -85,6 +85,11 @@ public class FallbackChunkGet implements IChunkGet {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Future<T>> T call(IChunkSet set, Runnable finalize) {
|
||||
for (int layer = 0; layer < 16; layer++) {
|
||||
|
@ -50,6 +50,10 @@ object NullChunkGet : IChunkGet {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun trim(aggressive: Boolean, layer: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun <T : Future<T>> call(set: IChunkSet, finalize: Runnable): T? {
|
||||
return null
|
||||
}
|
||||
|
@ -344,6 +344,11 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
return this.trim(aggressive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return chunkSet == null || chunkSet.isEmpty();
|
||||
|
@ -117,5 +117,9 @@ object NullChunk : IQueueChunk<Nothing> {
|
||||
override fun trim(aggressive: Boolean): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun trim(aggressive: Boolean, layer: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import com.boydti.fawe.beta.IBatchProcessor;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IChunkGet;
|
||||
import com.boydti.fawe.beta.IChunkSet;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
|
||||
public class BatchProcessorHolder implements IBatchProcessorHolder {
|
||||
private IBatchProcessor processor = EmptyBatchProcessor.INSTANCE;
|
||||
|
@ -549,6 +549,11 @@ public class MCAChunk implements IChunk {
|
||||
return isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
return hasSection(layer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
return this.entities.get(uuid);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.google.common.primitives.Booleans;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
@ -166,12 +167,14 @@ public class BlockTypesCache {
|
||||
|
||||
public static final BlockType[] values;
|
||||
public static final BlockState[] states;
|
||||
public static final boolean[] ticking;
|
||||
|
||||
protected static final Set<String> $NAMESPACES = new LinkedHashSet<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
ArrayList<BlockState> stateList = new ArrayList<>();
|
||||
ArrayList<Boolean> tickList = new ArrayList<>();
|
||||
|
||||
Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS);
|
||||
Registries registries = platform.getRegistries();
|
||||
@ -202,7 +205,7 @@ public class BlockTypesCache {
|
||||
if (values[internalId] != null) {
|
||||
throw new IllegalStateException("Invalid duplicate id for " + field.getName());
|
||||
}
|
||||
BlockType type = register(defaultState, internalId, stateList);
|
||||
BlockType type = register(defaultState, internalId, stateList, tickList);
|
||||
// Note: Throws IndexOutOfBoundsError if nothing is registered and blocksMap is empty
|
||||
values[internalId] = type;
|
||||
}
|
||||
@ -214,7 +217,7 @@ public class BlockTypesCache {
|
||||
String defaultState = entry.getValue();
|
||||
// Skip already registered ids
|
||||
for (; values[internalId] != null; internalId++);
|
||||
BlockType type = register(defaultState, internalId, stateList);
|
||||
BlockType type = register(defaultState, internalId, stateList, tickList);
|
||||
values[internalId] = type;
|
||||
}
|
||||
}
|
||||
@ -223,7 +226,7 @@ public class BlockTypesCache {
|
||||
}
|
||||
|
||||
states = stateList.toArray(new BlockState[stateList.size()]);
|
||||
|
||||
ticking = Booleans.toArray(tickList);
|
||||
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -231,12 +234,14 @@ public class BlockTypesCache {
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockType register(final String id, int internalId, List<BlockState> states) {
|
||||
private static BlockType register(final String id, int internalId, List<BlockState> states, List<Boolean> tickList) {
|
||||
// Get the enum name (remove namespace if minecraft:)
|
||||
int propStart = id.indexOf('[');
|
||||
String typeName = id.substring(0, propStart == -1 ? id.length() : propStart);
|
||||
String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(Locale.ROOT);
|
||||
int oldsize = states.size();
|
||||
BlockType existing = new BlockType(id, internalId, states);
|
||||
tickList.addAll(Collections.nCopies(states.size() - oldsize, existing.getMaterial().isTicksRandomly()));
|
||||
// register states
|
||||
BlockType.REGISTRY.register(typeName, existing);
|
||||
String nameSpace = typeName.substring(0, typeName.indexOf(':'));
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren