Generify BlockMap

(cherry picked from commit 7384b6973498084f4082d7e1a805b84b13a3ba44)
This commit is contained in:
Octavia Togami 2020-01-30 01:05:31 -08:00 committed by MattBDev
parent d5828861de
commit 38d5506e18
7 changed files with 86 additions and 71 deletions

View File

@ -43,7 +43,7 @@ import java.util.Optional;
*/ */
public class ChunkBatchingExtent extends AbstractBufferingExtent { public class ChunkBatchingExtent extends AbstractBufferingExtent {
private final BlockMap blockMap = BlockMap.create(); private final BlockMap<BaseBlock> blockMap = BlockMap.createForBaseBlock();
private boolean enabled; private boolean enabled;
public ChunkBatchingExtent(Extent extent) { public ChunkBatchingExtent(Extent extent) {

View File

@ -142,7 +142,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL); priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
} }
private Map<PlacementPriority, BlockMap> stages = new HashMap<>(); private Map<PlacementPriority, BlockMap<BaseBlock>> stages = new HashMap<>();
private boolean enabled; private boolean enabled;
@ -176,7 +176,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
this.enabled = enabled; this.enabled = enabled;
for (PlacementPriority priority : PlacementPriority.values()) { for (PlacementPriority priority : PlacementPriority.values()) {
stages.put(priority, BlockMap.create()); stages.put(priority, BlockMap.createForBaseBlock());
} }
} }
@ -261,7 +261,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
} }
List<Operation> operations = new ArrayList<>(); List<Operation> operations = new ArrayList<>();
for (PlacementPriority priority : PlacementPriority.values()) { for (PlacementPriority priority : PlacementPriority.values()) {
BlockMap blocks = stages.get(priority); BlockMap<BaseBlock> blocks = stages.get(priority);
operations.add(new SetBlockMap(getExtent(), blocks) { operations.add(new SetBlockMap(getExtent(), blocks) {
@Override @Override
public Operation resume(RunContext run) throws WorldEditException { public Operation resume(RunContext run) throws WorldEditException {

View File

@ -34,9 +34,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class SetBlockMap implements Operation { public class SetBlockMap implements Operation {
private final Extent extent; private final Extent extent;
private final BlockMap blocks; private final BlockMap<BaseBlock> blocks;
public SetBlockMap(Extent extent, BlockMap blocks) { public SetBlockMap(Extent extent, BlockMap<BaseBlock> blocks) {
this.extent = checkNotNull(extent); this.extent = checkNotNull(extent);
this.blocks = checkNotNull(blocks); this.blocks = checkNotNull(blocks);
} }

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@ -40,6 +41,7 @@ import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import static com.sk89q.worldedit.math.BitMath.fixSign; import static com.sk89q.worldedit.math.BitMath.fixSign;
import static com.sk89q.worldedit.math.BitMath.mask; import static com.sk89q.worldedit.math.BitMath.mask;
@ -47,7 +49,7 @@ import static com.sk89q.worldedit.math.BitMath.mask;
/** /**
* A space-efficient map implementation for block locations. * A space-efficient map implementation for block locations.
*/ */
public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> { public class BlockMap<V> extends AbstractMap<BlockVector3, V> {
/* ========================= /* =========================
IF YOU MAKE CHANGES TO THIS CLASS IF YOU MAKE CHANGES TO THIS CLASS
@ -55,12 +57,20 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
Or just temporarily remove the annotation disabling the related tests. Or just temporarily remove the annotation disabling the related tests.
========================= */ ========================= */
public static BlockMap create() { public static <V> BlockMap<V> create() {
return new BlockMap(); return create(() -> new Int2ObjectOpenHashMap<>(64, 1f));
} }
public static BlockMap copyOf(Map<? extends BlockVector3, ? extends BaseBlock> source) { public static BlockMap<BaseBlock> createForBaseBlock() {
return new BlockMap(source); return create(Int2BaseBlockMap::new);
}
private static <V> BlockMap<V> create(Supplier<Int2ObjectMap<V>> subMapSupplier) {
return new BlockMap<>(subMapSupplier);
}
public static <V> BlockMap<V> copyOf(Map<? extends BlockVector3, ? extends V> source) {
return new BlockMap<>(Int2ObjectOpenHashMap::new, source);
} }
/* /*
@ -108,31 +118,34 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
return BlockVector3.at(x, y, z); return BlockVector3.at(x, y, z);
} }
private final Long2ObjectMap<SubBlockMap> maps = new Long2ObjectOpenHashMap<>(4, 1f); private final Long2ObjectMap<Int2ObjectMap<V>> maps = new Long2ObjectOpenHashMap<>(4, 1f);
private Set<Entry<BlockVector3, BaseBlock>> entrySet; private final Supplier<Int2ObjectMap<V>> subMapSupplier;
private Collection<BaseBlock> values; private Set<Entry<BlockVector3, V>> entrySet;
private Collection<V> values;
private BlockMap() { private BlockMap(Supplier<Int2ObjectMap<V>> subMapSupplier) {
this.subMapSupplier = subMapSupplier;
} }
private BlockMap(Map<? extends BlockVector3, ? extends BaseBlock> source) { private BlockMap(Supplier<Int2ObjectMap<V>> subMapSupplier, Map<? extends BlockVector3, ? extends V> source) {
this.subMapSupplier = subMapSupplier;
putAll(source); putAll(source);
} }
private SubBlockMap getOrCreateMap(long groupKey) { private Int2ObjectMap<V> getOrCreateMap(long groupKey) {
return maps.computeIfAbsent(groupKey, k -> new SubBlockMap()); return maps.computeIfAbsent(groupKey, k -> subMapSupplier.get());
} }
private SubBlockMap getOrEmptyMap(long groupKey) { private Int2ObjectMap<V> getOrEmptyMap(long groupKey) {
return maps.getOrDefault(groupKey, SubBlockMap.EMPTY); return maps.getOrDefault(groupKey, Int2ObjectMaps.emptyMap());
} }
/** /**
* Apply the function the the map at {@code groupKey}, and if the function empties the map, * Apply the function the the map at {@code groupKey}, and if the function empties the map,
* delete it from {@code maps}. * delete it from {@code maps}.
*/ */
private <R> R cleanlyModifyMap(long groupKey, Function<Int2ObjectMap<BaseBlock>, R> func) { private <R> R cleanlyModifyMap(long groupKey, Function<Int2ObjectMap<V>, R> func) {
SubBlockMap map = maps.get(groupKey); Int2ObjectMap<V> map = maps.get(groupKey);
if (map != null) { if (map != null) {
R result = func.apply(map); R result = func.apply(map);
if (map.isEmpty()) { if (map.isEmpty()) {
@ -140,7 +153,7 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
return result; return result;
} }
map = new SubBlockMap(); map = subMapSupplier.get();
R result = func.apply(map); R result = func.apply(map);
if (!map.isEmpty()) { if (!map.isEmpty()) {
maps.put(groupKey, map); maps.put(groupKey, map);
@ -149,19 +162,19 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public BaseBlock put(BlockVector3 key, BaseBlock value) { public V put(BlockVector3 key, V value) {
return getOrCreateMap(toGroupKey(key)).put(toInnerKey(key), value); return getOrCreateMap(toGroupKey(key)).put(toInnerKey(key), value);
} }
@Override @Override
public BaseBlock getOrDefault(Object key, BaseBlock defaultValue) { public V getOrDefault(Object key, V defaultValue) {
BlockVector3 vec = (BlockVector3) key; BlockVector3 vec = (BlockVector3) key;
return getOrEmptyMap(toGroupKey(vec)) return getOrEmptyMap(toGroupKey(vec))
.getOrDefault(toInnerKey(vec), defaultValue); .getOrDefault(toInnerKey(vec), defaultValue);
} }
@Override @Override
public void forEach(BiConsumer<? super BlockVector3, ? super BaseBlock> action) { public void forEach(BiConsumer<? super BlockVector3, ? super V> action) {
maps.forEach((groupKey, m) -> maps.forEach((groupKey, m) ->
m.forEach((innerKey, block) -> m.forEach((innerKey, block) ->
action.accept(reconstructLocation(groupKey, innerKey), block) action.accept(reconstructLocation(groupKey, innerKey), block)
@ -170,7 +183,7 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public void replaceAll(BiFunction<? super BlockVector3, ? super BaseBlock, ? extends BaseBlock> function) { public void replaceAll(BiFunction<? super BlockVector3, ? super V, ? extends V> function) {
maps.forEach((groupKey, m) -> maps.forEach((groupKey, m) ->
m.replaceAll((innerKey, block) -> m.replaceAll((innerKey, block) ->
function.apply(reconstructLocation(groupKey, innerKey), block) function.apply(reconstructLocation(groupKey, innerKey), block)
@ -179,7 +192,7 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public BaseBlock putIfAbsent(BlockVector3 key, BaseBlock value) { public V putIfAbsent(BlockVector3 key, V value) {
return getOrCreateMap(toGroupKey(key)).putIfAbsent(toInnerKey(key), value); return getOrCreateMap(toGroupKey(key)).putIfAbsent(toInnerKey(key), value);
} }
@ -191,66 +204,66 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public boolean replace(BlockVector3 key, BaseBlock oldValue, BaseBlock newValue) { public boolean replace(BlockVector3 key, V oldValue, V newValue) {
return cleanlyModifyMap(toGroupKey(key), return cleanlyModifyMap(toGroupKey(key),
map -> map.replace(toInnerKey(key), oldValue, newValue)); map -> map.replace(toInnerKey(key), oldValue, newValue));
} }
@Override @Override
public BaseBlock replace(BlockVector3 key, BaseBlock value) { public V replace(BlockVector3 key, V value) {
return getOrCreateMap(toGroupKey(key)).replace(toInnerKey(key), value); return getOrCreateMap(toGroupKey(key)).replace(toInnerKey(key), value);
} }
@Override @Override
public BaseBlock computeIfAbsent(BlockVector3 key, Function<? super BlockVector3, ? extends BaseBlock> mappingFunction) { public V computeIfAbsent(BlockVector3 key, Function<? super BlockVector3, ? extends V> mappingFunction) {
return cleanlyModifyMap(toGroupKey(key), return cleanlyModifyMap(toGroupKey(key),
map -> map.computeIfAbsent(toInnerKey(key), ik -> mappingFunction.apply(key))); map -> map.computeIfAbsent(toInnerKey(key), ik -> mappingFunction.apply(key)));
} }
@Override @Override
public BaseBlock computeIfPresent(BlockVector3 key, BiFunction<? super BlockVector3, ? super BaseBlock, ? extends BaseBlock> remappingFunction) { public V computeIfPresent(BlockVector3 key, BiFunction<? super BlockVector3, ? super V, ? extends V> remappingFunction) {
return cleanlyModifyMap(toGroupKey(key), return cleanlyModifyMap(toGroupKey(key),
map -> map.computeIfPresent(toInnerKey(key), (ik, block) -> remappingFunction.apply(key, block))); map -> map.computeIfPresent(toInnerKey(key), (ik, block) -> remappingFunction.apply(key, block)));
} }
@Override @Override
public BaseBlock compute(BlockVector3 key, BiFunction<? super BlockVector3, ? super BaseBlock, ? extends BaseBlock> remappingFunction) { public V compute(BlockVector3 key, BiFunction<? super BlockVector3, ? super V, ? extends V> remappingFunction) {
return cleanlyModifyMap(toGroupKey(key), return cleanlyModifyMap(toGroupKey(key),
map -> map.compute(toInnerKey(key), (ik, block) -> remappingFunction.apply(key, block))); map -> map.compute(toInnerKey(key), (ik, block) -> remappingFunction.apply(key, block)));
} }
@Override @Override
public BaseBlock merge(BlockVector3 key, BaseBlock value, BiFunction<? super BaseBlock, ? super BaseBlock, ? extends BaseBlock> remappingFunction) { public V merge(BlockVector3 key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
return cleanlyModifyMap(toGroupKey(key), return cleanlyModifyMap(toGroupKey(key),
map -> map.merge(toInnerKey(key), value, remappingFunction)); map -> map.merge(toInnerKey(key), value, remappingFunction));
} }
@Override @Override
public Set<Entry<BlockVector3, BaseBlock>> entrySet() { public Set<Entry<BlockVector3, V>> entrySet() {
Set<Entry<BlockVector3, BaseBlock>> es = entrySet; Set<Entry<BlockVector3, V>> es = entrySet;
if (es == null) { if (es == null) {
entrySet = es = new AbstractSet<Entry<BlockVector3, BaseBlock>>() { entrySet = es = new AbstractSet<Entry<BlockVector3, V>>() {
@Override @Override
public Iterator<Entry<BlockVector3, BaseBlock>> iterator() { public Iterator<Entry<BlockVector3, V>> iterator() {
return new AbstractIterator<Entry<BlockVector3, BaseBlock>>() { return new AbstractIterator<Entry<BlockVector3, V>>() {
private final ObjectIterator<Long2ObjectMap.Entry<SubBlockMap>> primaryIterator private final ObjectIterator<Long2ObjectMap.Entry<Int2ObjectMap<V>>> primaryIterator
= Long2ObjectMaps.fastIterator(maps); = Long2ObjectMaps.fastIterator(maps);
private long currentGroupKey; private long currentGroupKey;
private ObjectIterator<Int2ObjectMap.Entry<BaseBlock>> secondaryIterator; private ObjectIterator<Int2ObjectMap.Entry<V>> secondaryIterator;
@Override @Override
protected Entry<BlockVector3, BaseBlock> computeNext() { protected Entry<BlockVector3, V> computeNext() {
if (secondaryIterator == null || !secondaryIterator.hasNext()) { if (secondaryIterator == null || !secondaryIterator.hasNext()) {
if (!primaryIterator.hasNext()) { if (!primaryIterator.hasNext()) {
return endOfData(); return endOfData();
} }
Long2ObjectMap.Entry<SubBlockMap> next = primaryIterator.next(); Long2ObjectMap.Entry<Int2ObjectMap<V>> next = primaryIterator.next();
currentGroupKey = next.getLongKey(); currentGroupKey = next.getLongKey();
secondaryIterator = Int2ObjectMaps.fastIterator(next.getValue()); secondaryIterator = Int2ObjectMaps.fastIterator(next.getValue());
} }
Int2ObjectMap.Entry<BaseBlock> next = secondaryIterator.next(); Int2ObjectMap.Entry<V> next = secondaryIterator.next();
return new LazyEntry(currentGroupKey, next.getIntKey(), next.getValue()); return new LazyEntry(currentGroupKey, next.getIntKey(), next.getValue());
} }
}; };
@ -265,14 +278,14 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
return es; return es;
} }
private final class LazyEntry implements Map.Entry<BlockVector3, BaseBlock> { private final class LazyEntry implements Entry<BlockVector3, V> {
private final long groupKey; private final long groupKey;
private final int innerKey; private final int innerKey;
private BlockVector3 lazyKey; private BlockVector3 lazyKey;
private BaseBlock value; private V value;
private LazyEntry(long groupKey, int innerKey, BaseBlock value) { private LazyEntry(long groupKey, int innerKey, V value) {
this.groupKey = groupKey; this.groupKey = groupKey;
this.innerKey = innerKey; this.innerKey = innerKey;
this.value = value; this.value = value;
@ -288,12 +301,12 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public BaseBlock getValue() { public V getValue() {
return value; return value;
} }
@Override @Override
public BaseBlock setValue(BaseBlock value) { public V setValue(V value) {
this.value = value; this.value = value;
return getOrCreateMap(groupKey).put(innerKey, value); return getOrCreateMap(groupKey).put(innerKey, value);
} }
@ -301,8 +314,9 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
public boolean equals(Object o) { public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) if (!(o instanceof Map.Entry))
return false; return false;
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o; Entry<?, ?> e = (Entry<?, ?>) o;
if (o instanceof LazyEntry) { if (o instanceof BlockMap.LazyEntry) {
@SuppressWarnings("unchecked")
LazyEntry otherE = (LazyEntry) o; LazyEntry otherE = (LazyEntry) o;
return otherE.groupKey == groupKey return otherE.groupKey == groupKey
&& otherE.innerKey == innerKey && otherE.innerKey == innerKey
@ -330,7 +344,7 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
@Override @Override
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
BlockVector3 vec = (BlockVector3) key; BlockVector3 vec = (BlockVector3) key;
Map<Integer, BaseBlock> activeMap = maps.get(toGroupKey(vec)); Int2ObjectMap<V> activeMap = maps.get(toGroupKey(vec));
if (activeMap == null) { if (activeMap == null) {
return false; return false;
} }
@ -338,9 +352,9 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public BaseBlock get(Object key) { public V get(Object key) {
BlockVector3 vec = (BlockVector3) key; BlockVector3 vec = (BlockVector3) key;
Map<Integer, BaseBlock> activeMap = maps.get(toGroupKey(vec)); Int2ObjectMap<V> activeMap = maps.get(toGroupKey(vec));
if (activeMap == null) { if (activeMap == null) {
return null; return null;
} }
@ -348,24 +362,25 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
} }
@Override @Override
public BaseBlock remove(Object key) { public V remove(Object key) {
BlockVector3 vec = (BlockVector3) key; BlockVector3 vec = (BlockVector3) key;
Map<Integer, BaseBlock> activeMap = maps.get(toGroupKey(vec)); Int2ObjectMap<V> activeMap = maps.get(toGroupKey(vec));
if (activeMap == null) { if (activeMap == null) {
return null; return null;
} }
BaseBlock removed = activeMap.remove(toInnerKey(vec)); V removed = activeMap.remove(toInnerKey(vec));
if (activeMap.isEmpty()) { if (activeMap.isEmpty()) {
maps.remove(toGroupKey(vec)); maps.remove(toGroupKey(vec));
} }
return removed; return removed;
} }
@SuppressWarnings("unchecked")
@Override @Override
public void putAll(Map<? extends BlockVector3, ? extends BaseBlock> m) { public void putAll(Map<? extends BlockVector3, ? extends V> m) {
if (m instanceof BlockMap) { if (m instanceof BlockMap) {
// optimize insertions: // optimize insertions:
((BlockMap) m).maps.forEach((groupKey, map) -> ((BlockMap<V>) m).maps.forEach((groupKey, map) ->
getOrCreateMap(groupKey).putAll(map) getOrCreateMap(groupKey).putAll(map)
); );
} else { } else {
@ -387,12 +402,12 @@ public class BlockMap extends AbstractMap<BlockVector3, BaseBlock> {
// we can optimize values access though, by skipping BV construction. // we can optimize values access though, by skipping BV construction.
@Override @Override
public Collection<BaseBlock> values() { public Collection<V> values() {
Collection<BaseBlock> vs = values; Collection<V> vs = values;
if (vs == null) { if (vs == null) {
values = vs = new AbstractCollection<BaseBlock>() { values = vs = new AbstractCollection<V>() {
@Override @Override
public Iterator<BaseBlock> iterator() { public Iterator<V> iterator() {
return maps.values().stream() return maps.values().stream()
.flatMap(m -> m.values().stream()) .flatMap(m -> m.values().stream())
.iterator(); .iterator();

View File

@ -39,7 +39,7 @@ import java.util.function.BiFunction;
/** /**
* Int-to-BaseBlock map, but with optimizations for common cases. * Int-to-BaseBlock map, but with optimizations for common cases.
*/ */
class SubBlockMap extends AbstractInt2ObjectMap<BaseBlock> { class Int2BaseBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
private static boolean hasInt(BlockState b) { private static boolean hasInt(BlockState b) {
return BlockStateIdAccess.getBlockStateId(b).isPresent(); return BlockStateIdAccess.getBlockStateId(b).isPresent();
@ -65,7 +65,7 @@ class SubBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
return state.toBaseBlock(); return state.toBaseBlock();
} }
static final SubBlockMap EMPTY = new SubBlockMap(); static final Int2BaseBlockMap EMPTY = new Int2BaseBlockMap();
private final Int2IntMap commonMap = new Int2IntOpenHashMap(64, 1f); private final Int2IntMap commonMap = new Int2IntOpenHashMap(64, 1f);
private final Int2ObjectMap<BaseBlock> uncommonMap = new Int2ObjectOpenHashMap<>(1, 1f); private final Int2ObjectMap<BaseBlock> uncommonMap = new Int2ObjectOpenHashMap<>(1, 1f);
@ -88,7 +88,7 @@ class SubBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
private final ObjectIterator<Int2IntMap.Entry> commonIter private final ObjectIterator<Int2IntMap.Entry> commonIter
= Int2IntMaps.fastIterator(commonMap); = Int2IntMaps.fastIterator(commonMap);
private final ObjectIterator<Int2ObjectMap.Entry<BaseBlock>> uncommonIter private final ObjectIterator<Entry<BaseBlock>> uncommonIter
= Int2ObjectMaps.fastIterator(uncommonMap); = Int2ObjectMaps.fastIterator(uncommonMap);
@Override @Override
@ -114,7 +114,7 @@ class SubBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
@Override @Override
public int size() { public int size() {
return SubBlockMap.this.size(); return Int2BaseBlockMap.this.size();
} }
}; };
} }
@ -179,9 +179,9 @@ class SubBlockMap extends AbstractInt2ObjectMap<BaseBlock> {
next.setValue(assumeAsInt(value.toImmutableState())); next.setValue(assumeAsInt(value.toImmutableState()));
} }
} }
for (ObjectIterator<Int2ObjectMap.Entry<BaseBlock>> iter = Int2ObjectMaps.fastIterator(uncommonMap); for (ObjectIterator<Entry<BaseBlock>> iter = Int2ObjectMaps.fastIterator(uncommonMap);
iter.hasNext(); ) { iter.hasNext(); ) {
Int2ObjectMap.Entry<BaseBlock> next = iter.next(); Entry<BaseBlock> next = iter.next();
BaseBlock value = function.apply(next.getIntKey(), next.getValue()); BaseBlock value = function.apply(next.getIntKey(), next.getValue());
if (isUncommon(value)) { if (isUncommon(value)) {
next.setValue(value); next.setValue(value);

View File

@ -37,7 +37,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class LocatedBlockList implements Iterable<LocatedBlock> { public class LocatedBlockList implements Iterable<LocatedBlock> {
private final BlockMap blocks = BlockMap.create(); private final BlockMap<BaseBlock> blocks = BlockMap.createForBaseBlock();
private final PositionList order = PositionList.create( private final PositionList order = PositionList.create(
WorldEdit.getInstance().getConfiguration().extendedYLimit WorldEdit.getInstance().getConfiguration().extendedYLimit
); );

View File

@ -110,7 +110,7 @@ class BlockMapTest {
private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock(); private final BaseBlock air = checkNotNull(BlockTypes.AIR).getDefaultState().toBaseBlock();
private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock(); private final BaseBlock oakWood = checkNotNull(BlockTypes.OAK_WOOD).getDefaultState().toBaseBlock();
private BlockMap map = BlockMap.create(); private BlockMap<BaseBlock> map = BlockMap.createForBaseBlock();
@BeforeEach @BeforeEach
void setUp() { void setUp() {