Performance improvement based on case study by @me4502

This commit is contained in:
MattBDev
2020-03-19 13:08:25 -04:00
parent 2e1c0c83f5
commit 9f07894f28
14 changed files with 106 additions and 65 deletions

View File

@ -26,6 +26,7 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.Optional;
import javax.annotation.Nullable;
/**
* Base extent class for buffering changes between {@link #setBlock(BlockVector3, BlockStateHolder)}
@ -51,17 +52,38 @@ public abstract class AbstractBufferingExtent extends AbstractDelegateExtent {
@Override
public BlockState getBlock(BlockVector3 position) {
return getBufferedBlock(position)
.map(BaseBlock::toImmutableState)
.orElseGet(() -> super.getBlock(position));
BaseBlock block = getBufferedFullBlock(position);
if (block == null) {
return super.getBlock(position);
}
return block.toImmutableState();
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
return getBufferedBlock(position)
.orElseGet(() -> super.getFullBlock(position));
BaseBlock block = getBufferedFullBlock(position);
if (block == null) {
return super.getFullBlock(position);
}
return block;
}
protected abstract Optional<BaseBlock> getBufferedBlock(BlockVector3 position);
@Deprecated
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
throw new IllegalStateException("Invalid BufferingExtent provided. Must override `getBufferedFullBlock(BlockVector3)`.");
}
//TODO make below abstract
/**
* Gets a block from the buffer, or null if not buffered.
*
* This **must** be overridden, and will be abstract in WorldEdit 8.
*
* @param position The position
* @return The buffered block, or null
*/
@Nullable
protected BaseBlock getBufferedFullBlock(BlockVector3 position) {
return getBufferedBlock(position).orElse(null);
}
}

View File

@ -66,11 +66,11 @@ public class ExtentBuffer extends AbstractBufferingExtent {
}
@Override
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
if (mask.test(getExtent(), position)) {
return Optional.of(buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos))));
protected BaseBlock getBufferedFullBlock(BlockVector3 position) {
if (mask.test(position)) {
return buffer.computeIfAbsent(position, (pos -> getExtent().getFullBlock(pos)));
}
return Optional.empty();
return null;
}
@Override

View File

@ -77,8 +77,8 @@ public class ChunkBatchingExtent extends AbstractBufferingExtent {
}
@Override
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
return Optional.ofNullable(blockMap.get(position));
protected BaseBlock getBufferedFullBlock(BlockVector3 position) {
return blockMap.get(position);
}
@Override
@ -94,8 +94,7 @@ public class ChunkBatchingExtent extends AbstractBufferingExtent {
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (iterator == null) {
iterator = ImmutableSortedSet.copyOf(RegionOptimizedComparator.INSTANCE,
blockMap.keySet()).iterator();
iterator = blockMap.keySet().parallelStream().sorted(RegionOptimizedComparator.INSTANCE).iterator();
}
while (iterator.hasNext()) {
BlockVector3 position = iterator.next();

View File

@ -247,11 +247,14 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
}
@Override
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
return stages.values().stream()
.map(blocks -> blocks.get(position))
.filter(Objects::nonNull)
.findAny();
protected BaseBlock getBufferedFullBlock(BlockVector3 position) {
for (BlockMap<BaseBlock> blocks : stages.values()) {
BaseBlock baseBlock = blocks.get(position);
if (baseBlock != null) {
return baseBlock;
}
}
return null;
}
@Override