Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 16:12:42 +01:00
trying to optimize blockconnectionstorage
Dieser Commit ist enthalten in:
Ursprung
9ba70424e8
Commit
de11f1f90b
@ -1,39 +1,62 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage;
|
package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage;
|
||||||
|
|
||||||
import lombok.Data;
|
import us.myles.ViaVersion.api.Via;
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
import us.myles.ViaVersion.api.Pair;
|
|
||||||
import us.myles.ViaVersion.api.data.StoredObject;
|
import us.myles.ViaVersion.api.data.StoredObject;
|
||||||
import us.myles.ViaVersion.api.data.UserConnection;
|
import us.myles.ViaVersion.api.data.UserConnection;
|
||||||
import us.myles.ViaVersion.api.minecraft.Position;
|
import us.myles.ViaVersion.api.minecraft.Position;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class BlockConnectionStorage extends StoredObject {
|
public class BlockConnectionStorage extends StoredObject {
|
||||||
private Map<Pair<Integer, Integer>, Map<BlockPositon, Integer>> blockStorage = new HashMap<>();
|
private Map<Long, Map<Long, Short>> blockStorage = createLongObjectMap();
|
||||||
|
|
||||||
|
private static Class<?> fastUtilLongObjectHashMap;
|
||||||
|
private static Class<?> fastUtilLongShortHashMap;
|
||||||
|
private static Class<?> nettyLongObjectHashMap;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
fastUtilLongObjectHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap");
|
||||||
|
Via.getPlatform().getLogger().info("Using FastUtil Long2ObjectOpenHashMap for block connections");
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fastUtilLongShortHashMap = Class.forName("it.unimi.dsi.fastutil.longs.Long2ShortOpenHashMap");
|
||||||
|
Via.getPlatform().getLogger().info("Using FastUtil Long2ShortOpenHashMap for block connections");
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
if (fastUtilLongShortHashMap == null && fastUtilLongObjectHashMap == null) {
|
||||||
|
try {
|
||||||
|
nettyLongObjectHashMap = Class.forName("io.netty.util.collection.LongObjectHashMap");
|
||||||
|
Via.getPlatform().getLogger().info("Using Netty LongObjectHashMap for block connections");
|
||||||
|
} catch (ClassNotFoundException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BlockConnectionStorage(UserConnection user) {
|
public BlockConnectionStorage(UserConnection user) {
|
||||||
super(user);
|
super(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void store(Position position, int blockState) {
|
public void store(Position position, int blockState) {
|
||||||
Pair pair = getPair(position);
|
long pair = getChunkIndex(position);
|
||||||
Map<BlockPositon, Integer> map = getChunkMap(pair);
|
Map<Long, Short> map = getChunkMap(pair);
|
||||||
map.put(new BlockPositon(position), blockState);
|
map.put(encodeBlockPos(position), (short) blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int get(Position position) {
|
public int get(Position position) {
|
||||||
Pair pair = getPair(position);
|
long pair = getChunkIndex(position);
|
||||||
Map<BlockPositon, Integer> map = getChunkMap(pair);
|
Map<Long, Short> map = getChunkMap(pair);
|
||||||
BlockPositon blockPositon = new BlockPositon(position);
|
long blockPositon = encodeBlockPos(position);
|
||||||
return map.containsKey(blockPositon) ? map.get(blockPositon) : 0;
|
return map.containsKey(blockPositon) ? map.get(blockPositon) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(Position position) {
|
public void remove(Position position) {
|
||||||
Pair pair = getPair(position);
|
long pair = getChunkIndex(position);
|
||||||
Map<BlockPositon, Integer> map = getChunkMap(pair);
|
Map<Long, Short> map = getChunkMap(pair);
|
||||||
map.remove(new BlockPositon(position));
|
map.remove(encodeBlockPos(position));
|
||||||
if (map.isEmpty()) {
|
if (map.isEmpty()) {
|
||||||
blockStorage.remove(pair);
|
blockStorage.remove(pair);
|
||||||
}
|
}
|
||||||
@ -44,33 +67,74 @@ public class BlockConnectionStorage extends StoredObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void unloadChunk(int x, int z) {
|
public void unloadChunk(int x, int z) {
|
||||||
blockStorage.remove(new Pair<>(x, z));
|
blockStorage.remove(getChunkIndex(x, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<BlockPositon, Integer> getChunkMap(Pair pair) {
|
private Map<Long, Short> getChunkMap(long index) {
|
||||||
Map<BlockPositon, Integer> map = blockStorage.get(pair);
|
Map<Long, Short> map = blockStorage.get(index);
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = new HashMap<>();
|
map = createLongShortMap();
|
||||||
blockStorage.put(pair, map);
|
blockStorage.put(index, map);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<Integer, Integer> getPair(Position position) {
|
private long getChunkIndex(int x, int z) {
|
||||||
int chunkX = (int) (position.getX() >> 4);
|
return (long) x << 32 | (z & 0xFFFFFFFFL);
|
||||||
int chunkZ = (int) (position.getZ() >> 4);
|
|
||||||
return new Pair<>(chunkX, chunkZ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EqualsAndHashCode
|
private long getChunkIndex(Position position) {
|
||||||
@Data
|
return getChunkIndex(position.getX().intValue(), position.getZ().intValue());
|
||||||
private class BlockPositon {
|
|
||||||
int x, y, z;
|
|
||||||
|
|
||||||
public BlockPositon(Position position) {
|
|
||||||
x = position.getX().intValue();
|
|
||||||
y = position.getY().intValue();
|
|
||||||
z = position.getZ().intValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long encodeBlockPos(int x, int y, int z) {
|
||||||
|
return (((long) x & 0x3FFFFFF) << 38) | ((y & 0xFFF) << 26) | (z & 0x3FFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long encodeBlockPos(Position pos) {
|
||||||
|
return encodeBlockPos(pos.getX().intValue(), pos.getY().intValue(), pos.getZ().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Map<Long, T> createLongObjectMap() {
|
||||||
|
if (fastUtilLongObjectHashMap != null) {
|
||||||
|
try {
|
||||||
|
return (Map<Long, T>) fastUtilLongObjectHashMap.getConstructor().newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nettyLongObjectHashMap != null) {
|
||||||
|
try {
|
||||||
|
return (Map<Long, T>) nettyLongObjectHashMap.getConstructor().newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Long, Short> createLongShortMap() {
|
||||||
|
if (fastUtilLongShortHashMap != null) {
|
||||||
|
try {
|
||||||
|
return (Map<Long, Short>) fastUtilLongShortHashMap.getConstructor().newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fastUtilLongObjectHashMap != null) {
|
||||||
|
try {
|
||||||
|
return (Map<Long, Short>) fastUtilLongObjectHashMap.getConstructor().newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nettyLongObjectHashMap != null) {
|
||||||
|
try {
|
||||||
|
return (Map<Long, Short>) nettyLongObjectHashMap.getConstructor().newInstance();
|
||||||
|
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HashMap<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren