Skip to content

Commit a300a8e

Browse files
committed
improve: palette & use fastutil
1 parent 890521f commit a300a8e

15 files changed

Lines changed: 95 additions & 49 deletions

File tree

src/main/java/com/reider745/InnerCoreServer.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,7 @@ public void afterload() {
314314
pluginManager.registerEvents(new SnowfallEverywhere(), plugin);
315315
}
316316

317-
BlockPalette.init();
318317
RuntimeItemsHooks.register();
319-
CustomBlock.init();
320318
CustomItem.init();
321319
CustomItem.addCreativeItemsBuild();
322320
CustomItem.addCreativeItemsWeapons();

src/main/java/com/reider745/api/pointers/PointersStorage.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.reider745.api.pointers;
22

3+
import cn.nukkit.utils.collection.nb.Long2ObjectNonBlockingMap;
34
import com.reider745.api.pointers.pointer_gen.IBasePointerGen;
45
import com.reider745.api.pointers.pointer_gen.PointerGenSlowest;
56
import com.zhekasmirnov.horizon.runtime.logger.Logger;
67

78
import java.lang.ref.WeakReference;
89
import java.util.HashMap;
9-
import java.util.concurrent.ConcurrentHashMap;
1010

1111
public class PointersStorage<T> {
1212
private static final HashMap<String, PointersStorage<?>> storages = new HashMap<>();
1313

14-
private final ConcurrentHashMap<Long, ClassPointer<T>> pointers = new ConcurrentHashMap<>();
15-
private final ConcurrentHashMap<ClassPointer<T>, Long> pointerForInstance = new ConcurrentHashMap<>();
14+
private final Long2ObjectNonBlockingMap<ClassPointer<T>> pointers = new Long2ObjectNonBlockingMap<>();
1615
private final IBasePointerGen pointerGen;
1716

1817
public interface INewPointer<T> {
@@ -54,14 +53,12 @@ public final long addPointer(T pointerClass) {
5453
long ptr = pointerGen.next();
5554
ClassPointer<T> pointer = newPointer.apply(new WeakReference<>(pointerClass));
5655
pointers.put(ptr, pointer);
57-
pointerForInstance.put(pointer, ptr);
5856
return ptr;
5957
}
6058

6159
public final long addPointer(ClassPointer<T> pointer) {
6260
long ptr = pointerGen.next();
6361
pointers.put(ptr, pointer);
64-
pointerForInstance.put(pointer, ptr);
6562
return ptr;
6663
}
6764

@@ -73,11 +70,6 @@ public final ClassPointer<T> getInstance(long ptr) {
7370
return pointers.get(ptr);
7471
}
7572

76-
public final long getPointerForInstance(T value) {
77-
Long ptr = pointerForInstance.get(value);
78-
return ptr == null ? 0 : ptr;
79-
}
80-
8173
public final void removePointer(long pointer) {
8274
pointers.remove(pointer);
8375
pointerGen.remove(pointer);
@@ -89,10 +81,9 @@ public final void replace(long ptr, ClassPointer<T> classPointer) {
8981
return;
9082
}
9183
pointers.put(ptr, classPointer);
92-
pointerForInstance.put(classPointer, ptr);
9384
}
9485

95-
public ConcurrentHashMap<Long, ClassPointer<T>> getPointers() {
86+
public Long2ObjectNonBlockingMap<ClassPointer<T>> getPointers() {
9687
return pointers;
9788
}
9889

src/main/java/com/reider745/api/pointers/ThreadCheckToClear.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.reider745.api.pointers;
22

3+
import cn.nukkit.utils.collection.nb.Long2ObjectNonBlockingMap;
4+
35
import java.util.Iterator;
46
import java.util.concurrent.ConcurrentHashMap;
57

68
public class ThreadCheckToClear<T> extends Thread {
79
private static final long TIME = 100 * 1000;
810
private final PointersStorage<?> storage;
9-
private final ConcurrentHashMap<Long, ClassPointer<T>> pointers;
11+
private final Long2ObjectNonBlockingMap<ClassPointer<T>> pointers;
1012

1113
public ThreadCheckToClear(PointersStorage<T> storage) {
1214
this.storage = storage;

src/main/java/com/reider745/block/BlockNukkitIdConverter.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import cn.nukkit.Server;
44
import cn.nukkit.block.BlockID;
55
import com.google.common.io.ByteStreams;
6+
import it.unimi.dsi.fastutil.ints.Int2IntMap;
7+
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
8+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
69
import org.json.JSONArray;
710
import org.json.JSONObject;
811

@@ -11,8 +14,8 @@
1114
public class BlockNukkitIdConverter {
1215
public static final JSONArray json;
1316

14-
private static final HashMap<Integer, Integer> legacyForNewId = new HashMap<>();
15-
private static final HashMap<Integer, Integer> newIdForLegacyId = new HashMap<>();
17+
private static final Int2IntMap legacyForNewId = new Int2IntOpenHashMap();
18+
private static final Int2IntMap newIdForLegacyId = new Int2IntOpenHashMap();
1619

1720
static {
1821
try{

src/main/java/com/reider745/block/BlockStateStorage.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.reider745.block;
22

33
import com.reider745.hooks.block.BlockPalette;
4+
import it.unimi.dsi.fastutil.ints.Int2IntMap;
5+
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
6+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
7+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
48
import org.json.JSONObject;
59

610
import java.util.HashMap;
@@ -9,12 +13,12 @@
913

1014
// TODO: Убрать использования имен на использование id стейтов
1115
public class BlockStateStorage {
12-
private static final Map<Integer, Map<String, Integer>> statesForRuntimeId = new HashMap<>();
13-
private static final Map<Integer, Map<Map<String, Integer>, Integer>> runtimeIdsForStatesAndId = new HashMap<>();
14-
private static final Map<Integer, Integer> dataForRuntimeId = new HashMap<>();
16+
private static final Int2ObjectMap<Map<String, Integer>> statesForRuntimeId = new Int2ObjectOpenHashMap<>();
17+
private static final Int2ObjectMap<Map<Map<String, Integer>, Integer>> runtimeIdsForStatesAndId = new Int2ObjectOpenHashMap<>();
18+
private static final Int2IntMap dataForRuntimeId = new Int2IntOpenHashMap();
1519

1620
private static final HashMap<String, Integer> runtimeIdForIdAndData = new HashMap<>();
17-
private static final HashMap<Integer, int[]> blockForRuntime = new HashMap<>();
21+
private static final Int2ObjectMap<int[]> blockForRuntime = new Int2ObjectOpenHashMap<>();
1822

1923
public static void addState(JSONObject json, int runtimeId, int legacyId, int data, int newId){
2024
final Map<String, Integer> state = new HashMap<>();

src/main/java/com/reider745/block/CustomBlock.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import com.zhekasmirnov.innercore.api.unlimited.BlockShape;
1919

2020
import it.unimi.dsi.fastutil.bytes.Byte2ObjectOpenHashMap;
21+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
22+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
2123
import org.apache.commons.math3.stat.inference.BinomialTest;
2224
import org.checkerframework.checker.units.qual.A;
2325
import org.jetbrains.annotations.NotNull;
@@ -29,7 +31,7 @@
2931
import java.util.List;
3032

3133
public class CustomBlock extends BlockSolidMeta implements RandomTick {
32-
public static HashMap<Integer, CustomManager> blocks = new HashMap<>();
34+
public static Int2ObjectMap<CustomManager> blocks = new Int2ObjectOpenHashMap<>();
3335

3436
public static void registerBlock(int id, Block block) {
3537
registerBlock(id, 0, block);

src/main/java/com/reider745/hooks/block/BlockPalette.java

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
import com.reider745.InnerCoreServer;
1515
import com.reider745.api.hooks.annotation.Hooks;
1616
import com.reider745.api.hooks.annotation.Inject;
17-
import com.reider745.api.hooks.annotation.ShadowGetField;
1817
import com.reider745.block.BlockNukkitIdConverter;
1918
import com.reider745.block.BlockStateStorage;
2019
import com.reider745.block.CustomBlock;
2120
import com.reider745.block.wall.BlockWall;
2221
import it.unimi.dsi.fastutil.Hash;
2322
import it.unimi.dsi.fastutil.ints.Int2IntMap;
2423
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
24+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
25+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
2526
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
2627
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
2728
import org.cloudburstmc.nbt.NbtMap;
@@ -38,7 +39,7 @@ public class BlockPalette {
3839
private static final Int2IntMap runtimeIdToLegacy = new Int2IntOpenHashMap();
3940
private static final Int2IntMap stateCapacity = new Int2IntOpenHashMap();
4041
private static final Map<String, Integer> stateIdByName = new HashMap<>();
41-
private static final Map<Integer, String> nameByStateId = new HashMap<>();
42+
private static final Int2ObjectMap<String> nameByStateId = new Int2ObjectOpenHashMap<>();
4243
private static final Object2ObjectMap<NbtMap, BlockStateSnapshot> paletteMap = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy<>() {
4344
@Override
4445
public int hashCode(NbtMap nbtMap) {
@@ -61,6 +62,17 @@ public boolean equals(NbtMap nbtMap, NbtMap nbtMap2) {
6162
return Objects.equals(nbtMap, nbtMap2);
6263
}
6364
});
65+
private static final Object2ObjectMap<NbtMap, Integer> levelDbRuntimeIdToData = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy<>() {
66+
@Override
67+
public int hashCode(NbtMap nbtMap) {
68+
return nbtMap.hashCode();
69+
}
70+
71+
@Override
72+
public boolean equals(NbtMap nbtMap, NbtMap nbtMap2) {
73+
return Objects.equals(nbtMap, nbtMap2);
74+
}
75+
});
6476

6577
private static final cn.nukkit.level.BlockPalette blockPalette = new cn.nukkit.level.BlockPalette(LevelDBConstants.PALETTE_VERSION);
6678

@@ -167,9 +179,12 @@ public static List<JSONObject> variantGenerations(List<Integer> states) {
167179
}
168180

169181

170-
public static void init() {
182+
@Inject(className = "cn.nukkit.level.format.leveldb.NukkitLegacyMapper")
183+
public static void registerStates(BlockStateMapping blockStateMapping) {
171184
final long start = System.currentTimeMillis();
172185

186+
CustomBlock.init();
187+
173188
legacyToRuntimeId.defaultReturnValue(-1);
174189
runtimeIdToLegacy.defaultReturnValue(-1);
175190

@@ -215,6 +230,7 @@ public static void init() {
215230
nbt.hashCode();
216231
BlockStateMapping.get().registerState(runtimeId, nbt);
217232

233+
levelDbRuntimeIdToData.put(nbt, data);
218234
paletteMap.put(nbt, BlockStateSnapshot.builder()
219235
.version(BlockStateMapping.get().getVersion())
220236
.vanillaState(nbt)
@@ -312,7 +328,7 @@ public static int get(int id, int meta) {
312328
runtimeId = legacyToRuntimeId.get(id << Block.DATA_BITS);
313329

314330
if (runtimeId == -1 && id != BlockID.INFO_UPDATE) {
315-
logger.error("failed to locate state for id: " + id + ":" + meta);
331+
logger.warning("failed to locate state for id: " + id + ":" + meta);
316332

317333
runtimeId = legacyToRuntimeId.get(BlockID.INFO_UPDATE << Block.DATA_BITS);
318334
if (runtimeId == -1)
@@ -362,27 +378,37 @@ public static int getOrCreateRuntimeId(int legacyId) {
362378
return getOrCreateRuntimeId(ProtocolInfo.CURRENT_PROTOCOL, legacyId >> 4, legacyId & 0xf);
363379
}
364380

365-
@ShadowGetField(className = "cn.nukkit.level.format.leveldb.BlockStateMapping", field = "paletteMap")
366-
private static Object2ObjectMap<NbtMap, BlockStateSnapshot> getPaletteMap(BlockStateMapping self) {throw new RuntimeException();}
367-
368381
@Inject(className = "cn.nukkit.level.format.leveldb.BlockStateMapping")
369382
public static BlockStateSnapshot getStateUnsafe(BlockStateMapping self, NbtMap vanilla) {
370-
if(CustomBlock.customBlocks.containsKey(vanilla.getString("name"))) {
383+
String id = vanilla.getString("name");
384+
if(CustomBlock.customBlocks.containsKey(id)) {
371385
BlockStateSnapshot snapshot = CACHE_PALETTE.get(vanilla);
372386

373387
if(snapshot == null) {
374388
var customVanilla = vanilla.toBuilder();
375389
customVanilla.remove("version");
376-
vanilla = customVanilla.build();
377390

378391
snapshot = paletteMap.get(customVanilla.build());
379392
if(snapshot != null) {
380393
CACHE_PALETTE.put(vanilla, snapshot);
394+
} else {
395+
int damage = self.getState(self.updateVanillaState(vanilla)).getLegacyData();
396+
397+
for (NbtMap key : paletteMap.keySet()) {
398+
if (key.getString("name").equals(id) && damage == levelDbRuntimeIdToData.getOrDefault(key, 0)) {
399+
logger.warning("Replacing a unit with low compatibility: " + id);
400+
snapshot = paletteMap.get(key);
401+
CACHE_PALETTE.put(vanilla, snapshot);
402+
break;
403+
}
404+
}
381405
}
382406
}
383407

384408
if(snapshot != null) {
385409
return snapshot;
410+
} else {
411+
logger.warning("State not found: " + vanilla);
386412
}
387413
}
388414

src/main/java/com/reider745/hooks/item/RuntimeItemsHooks.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import com.reider745.hooks.block.BlockPalette;
1515
import com.reider745.item.CustomItem;
1616
import com.reider745.item.ItemMethod;
17+
import it.unimi.dsi.fastutil.ints.Int2BooleanMap;
18+
import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap;
1719
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
1820
import it.unimi.dsi.fastutil.objects.Object2IntMap;
1921
import org.json.JSONObject;
@@ -24,7 +26,7 @@
2426

2527
@Hooks(className = "cn.nukkit.item.RuntimeItemMapping")
2628
public class RuntimeItemsHooks implements HookClass {
27-
private static HashMap<Integer, Boolean> protocols = new HashMap<>();
29+
private static final Int2BooleanMap protocols = new Int2BooleanOpenHashMap();
2830

2931
@Inject
3032
public static void generatePalette(RuntimeItemMapping self) {

src/main/java/com/reider745/item/CustomItem.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@
1010
import com.reider745.item.ItemMethod.PropertiesNames;
1111
import com.zhekasmirnov.innercore.api.NativeItemInstanceExtra;
1212
import com.zhekasmirnov.innercore.api.unlimited.IDRegistry;
13+
import it.unimi.dsi.fastutil.ints.Int2IntMap;
14+
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
15+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
16+
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
1317

1418
import java.util.*;
1519
import java.util.function.Consumer;
1620

1721
public class CustomItem {
18-
public static HashMap<Integer, CustomManager> items = new HashMap<>();
19-
public static HashMap<Integer, Integer> foods = new HashMap<>();
22+
public static Int2ObjectMap<CustomManager> items = new Int2ObjectOpenHashMap<>();
23+
public static Int2IntMap foods = new Int2IntOpenHashMap();
2024

2125
public static void init() {
2226
items.forEach((key, value) -> Item.list[key] = value.getClazz());
@@ -154,7 +158,7 @@ public static boolean hasData(int id) {
154158
return manager.get(PropertiesNames.MAX_DAMAGE, 0) > 0;
155159
}
156160

157-
private static final HashMap<Integer, ArrayList<ItemCreative>> category_all = new HashMap<>();
161+
private static final Int2ObjectMap<ArrayList<ItemCreative>> category_all = new Int2ObjectOpenHashMap<>();
158162

159163
public static void sortCategory() {
160164
for (ItemCreative item : creative) {

src/main/java/com/reider745/item/ItemMethod.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import com.zhekasmirnov.innercore.api.NativeItemInstanceExtra;
1111
import com.zhekasmirnov.innercore.api.mod.adaptedscript.AdaptedScriptAPI.IDRegistry;
1212
import com.zhekasmirnov.innercore.api.runtime.other.NameTranslation;
13+
import it.unimi.dsi.fastutil.ints.Int2BooleanMap;
14+
import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap;
1315

1416
import java.util.ArrayList;
1517
import java.util.HashMap;
@@ -161,7 +163,7 @@ public static void setArmorDamageable(CustomManager manager, boolean value) {
161163
manager.put(PropertiesNames.ARMOR_DAMAGEABLE, value);
162164
}
163165

164-
public static HashMap<Integer, Boolean> despawn = new HashMap<>();
166+
public static Int2BooleanMap despawn = new Int2BooleanOpenHashMap();
165167

166168
public static void setShouldDespawn(int id, boolean value) {
167169
despawn.put(id, value);

0 commit comments

Comments
 (0)