Skip to content

Commit 9ea136a

Browse files
authored
Merge pull request #2745 from EngineHub/ot/perf/clipboard-optimizations
Use a one-dimensional array for BlockArrayClipboard
2 parents 2bfcdf4 + af1ce58 commit 9ea136a

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,25 @@
4040
import static com.google.common.base.Preconditions.checkNotNull;
4141

4242
/**
43-
* Stores block data as a multi-dimensional array of {@link BaseBlock}s and
43+
* Stores block data as an array of {@link BaseBlock}s and
4444
* other data as lists or maps.
4545
*/
4646
public class BlockArrayClipboard implements Clipboard {
4747

4848
private final Region region;
4949
private BlockVector3 origin;
50-
private final BaseBlock[][][] blocks;
51-
private BiomeType[][][] biomes = null;
50+
/**
51+
* Stride for y-index, for faster access to blocks/biomes array.
52+
*/
53+
private final int yStride;
54+
/**
55+
* Stride for z-index, for faster access to blocks/biomes array.
56+
*/
57+
private final int zStride;
58+
// Laid out in x-y-z order, as that's how we currently loop over positions.
59+
private final BaseBlock[] blocks;
60+
// Laid out in x-y-z order, as that's how we currently loop over positions.
61+
private BiomeType[] biomes = null;
5262
private final List<ClipboardEntity> entities = new ArrayList<>();
5363

5464
/**
@@ -64,7 +74,13 @@ public BlockArrayClipboard(Region region) {
6474
this.origin = region.getMinimumPoint();
6575

6676
BlockVector3 dimensions = getDimensions();
67-
blocks = new BaseBlock[dimensions.x()][dimensions.y()][dimensions.z()];
77+
blocks = new BaseBlock[dimensions.x() * dimensions.y() * dimensions.z()];
78+
yStride = dimensions.x();
79+
zStride = yStride * dimensions.y();
80+
}
81+
82+
private int indexBlockVecBasedArray(BlockVector3 v) {
83+
return v.x() + (v.y() * yStride) + (v.z() * zStride);
6884
}
6985

7086
@Override
@@ -125,7 +141,7 @@ public Entity createEntity(Location location, BaseEntity entity) {
125141
public BlockState getBlock(BlockVector3 position) {
126142
if (region.contains(position)) {
127143
BlockVector3 v = position.subtract(region.getMinimumPoint());
128-
BaseBlock block = blocks[v.x()][v.y()][v.z()];
144+
BaseBlock block = blocks[indexBlockVecBasedArray(v)];
129145
if (block != null) {
130146
return block.toImmutableState();
131147
}
@@ -138,7 +154,7 @@ public BlockState getBlock(BlockVector3 position) {
138154
public BaseBlock getFullBlock(BlockVector3 position) {
139155
if (region.contains(position)) {
140156
BlockVector3 v = position.subtract(region.getMinimumPoint());
141-
BaseBlock block = blocks[v.x()][v.y()][v.z()];
157+
BaseBlock block = blocks[indexBlockVecBasedArray(v)];
142158
if (block != null) {
143159
return block;
144160
}
@@ -151,7 +167,7 @@ public BaseBlock getFullBlock(BlockVector3 position) {
151167
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block) {
152168
if (region.contains(position)) {
153169
BlockVector3 v = position.subtract(region.getMinimumPoint());
154-
blocks[v.x()][v.y()][v.z()] = block.toBaseBlock();
170+
blocks[indexBlockVecBasedArray(v)] = block.toBaseBlock();
155171
return true;
156172
} else {
157173
return false;
@@ -168,7 +184,7 @@ public BiomeType getBiome(BlockVector3 position) {
168184
if (biomes != null
169185
&& position.containedWithin(getMinimumPoint(), getMaximumPoint())) {
170186
BlockVector3 v = position.subtract(region.getMinimumPoint());
171-
BiomeType biomeType = biomes[v.x()][v.y()][v.z()];
187+
BiomeType biomeType = biomes[indexBlockVecBasedArray(v)];
172188
if (biomeType != null) {
173189
return biomeType;
174190
}
@@ -182,9 +198,10 @@ public boolean setBiome(BlockVector3 position, BiomeType biome) {
182198
if (position.containedWithin(getMinimumPoint(), getMaximumPoint())) {
183199
BlockVector3 v = position.subtract(region.getMinimumPoint());
184200
if (biomes == null) {
185-
biomes = new BiomeType[region.getWidth()][region.getHeight()][region.getLength()];
201+
BlockVector3 dimensions = getDimensions();
202+
biomes = new BiomeType[dimensions.x() * dimensions.y() * dimensions.z()];
186203
}
187-
biomes[v.x()][v.y()][v.z()] = biome;
204+
biomes[indexBlockVecBasedArray(v)] = biome;
188205
return true;
189206
}
190207
return false;

0 commit comments

Comments
 (0)