Tweak the last access extent cache to provide better caching

This commit is contained in:
Matthew Miller 2018-12-29 19:21:33 +10:00
parent 2f8bdccf65
commit 871541d8c0
2 changed files with 40 additions and 10 deletions

View File

@ -92,9 +92,8 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat
max = max.getMaximum(location);
}
BlockVector3 blockVector = location;
if (mask.test(blockVector)) {
buffer.put(blockVector, block.toBaseBlock());
if (mask.test(location)) {
buffer.put(location, block.toBaseBlock());
return true;
} else {
return getExtent().setBlock(location, block);

View File

@ -19,10 +19,13 @@
package com.sk89q.worldedit.extent.cache;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
/**
* Returns the same cached {@link BlockState} for repeated calls to
@ -30,7 +33,8 @@ import com.sk89q.worldedit.world.block.BlockState;
*/
public class LastAccessExtentCache extends AbstractDelegateExtent {
private CachedBlock lastBlock;
private CachedBlock<BlockState> lastBlock;
private CachedBlock<BaseBlock> lastFullBlock;
/**
* Create a new instance.
@ -43,21 +47,48 @@ public class LastAccessExtentCache extends AbstractDelegateExtent {
@Override
public BlockState getBlock(BlockVector3 position) {
CachedBlock lastBlock = this.lastBlock;
CachedBlock<BlockState> lastBlock = this.lastBlock;
if (lastBlock != null && lastBlock.position.equals(position)) {
return lastBlock.block;
} else {
BlockState block = super.getBlock(position);
this.lastBlock = new CachedBlock(position, block);
this.lastBlock = new CachedBlock<>(position, block);
return block;
}
}
private static class CachedBlock {
private final BlockVector3 position;
private final BlockState block;
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
CachedBlock<BaseBlock> lastFullBlock = this.lastFullBlock;
if (lastFullBlock != null && lastFullBlock.position.equals(position)) {
return lastFullBlock.block;
} else {
BaseBlock block = super.getFullBlock(position);
this.lastFullBlock = new CachedBlock<>(position, block);
return block;
}
}
private CachedBlock(BlockVector3 position, BlockState block) {
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
if (super.setBlock(location, block)) {
if (lastFullBlock != null && lastFullBlock.position.equals(location)) {
this.lastFullBlock = new CachedBlock<>(location, block.toBaseBlock());
}
if (lastBlock != null && lastBlock.position.equals(location)) {
this.lastBlock = new CachedBlock<>(location, block.toImmutableState());
}
return true;
}
return false;
}
private static class CachedBlock<B extends BlockStateHolder<B>> {
private final BlockVector3 position;
private final B block;
private CachedBlock(BlockVector3 position, B block) {
this.position = position;
this.block = block;
}