Skip to content

Commit

Permalink
Further reduce memory footprint of CompoundTag (#140)
Browse files Browse the repository at this point in the history
* Further reduce memory footprint of CompoundTag

* Optimize deepcopy
  • Loading branch information
HaHaWTH authored Oct 28, 2024
1 parent f75d4f1 commit d3b1401
Showing 1 changed file with 106 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: HaHaWTH <[email protected]>
Date: Sat, 26 Oct 2024 22:38:30 +0800
Subject: [PATCH] Further reduce memory footprint of CompoundTag

Ported from project: https://github.com/embeddedt/ModernFix

diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java
index ea48637234fdb1e5f54342590def30e11b6a5df0..a7a5e1c70d1e4f7df6533d0531a200fe50b38b7a 100644
--- a/src/main/java/net/minecraft/nbt/CompoundTag.java
+++ b/src/main/java/net/minecraft/nbt/CompoundTag.java
@@ -49,7 +49,7 @@ public class CompoundTag implements Tag {

private static CompoundTag loadCompound(DataInput input, NbtAccounter tracker) throws IOException {
tracker.accountBytes(48L);
- it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> map = new org.dreeam.leaf.util.map.StringCanonizingOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag // Leaf - Further reduce memory footprint of CompoundTag

byte b;
while ((b = input.readByte()) != 0) {
@@ -166,7 +166,7 @@ public class CompoundTag implements Tag {
}

public CompoundTag() {
- this(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag
+ this(new org.dreeam.leaf.util.map.StringCanonizingOpenHashMap<>(8, 0.8f)); // Paper - Reduce memory footprint of CompoundTag // Leaf - Further reduce memory footprint of CompoundTag
}

@Override
@@ -497,6 +497,11 @@ public class CompoundTag implements Tag {

@Override
public CompoundTag copy() {
+ // Leaf start - Further reduce memory footprint of CompoundTag
+ if (this.tags instanceof org.dreeam.leaf.util.map.StringCanonizingOpenHashMap<Tag> stringCanonizingTags) {
+ return new CompoundTag(org.dreeam.leaf.util.map.StringCanonizingOpenHashMap.deepCopy(stringCanonizingTags, Tag::copy));
+ }
+ // Leaf end - Further reduce memory footprint of CompoundTag
// Paper start - Reduce memory footprint of CompoundTag
it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f);
java.util.Iterator<java.util.Map.Entry<String, Tag>> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator();
diff --git a/src/main/java/org/dreeam/leaf/util/map/StringCanonizingOpenHashMap.java b/src/main/java/org/dreeam/leaf/util/map/StringCanonizingOpenHashMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..72538e772102e4ce9fca36eaaba44de1b35afe30
--- /dev/null
+++ b/src/main/java/org/dreeam/leaf/util/map/StringCanonizingOpenHashMap.java
@@ -0,0 +1,58 @@
+package org.dreeam.leaf.util.map;
+
+import com.github.benmanes.caffeine.cache.Interner;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ObjectIterator;
+
+import java.util.Map;
+import java.util.function.Function;
+
+/**
+ * Backed by an {@link Object2ObjectOpenHashMap}, with string keys interned to save memory.
+ */
+public class StringCanonizingOpenHashMap<T> extends Object2ObjectOpenHashMap<String, T> {
+ private static final Interner<String> KEY_INTERNER = Interner.newWeakInterner();
+
+ private static String intern(String key) {
+ return key != null ? KEY_INTERNER.intern(key) : null;
+ }
+
+ public StringCanonizingOpenHashMap() {
+ super();
+ }
+
+ public StringCanonizingOpenHashMap(int expectedSize) {
+ super(expectedSize);
+ }
+
+ public StringCanonizingOpenHashMap(int expectedSize, float loadFactor) {
+ super(expectedSize, loadFactor);
+ }
+
+ @Override
+ public T put(String key, T value) {
+ return super.put(intern(key), value);
+ }
+
+ @Override
+ public void putAll(Map<? extends String, ? extends T> m) {
+ if (m.isEmpty()) return;
+ Map<String, T> tmp = new Object2ObjectOpenHashMap<>(m.size());
+ m.forEach((k, v) -> tmp.put(intern(k), v));
+ super.putAll(tmp);
+ }
+
+ private void putWithoutInterning(String key, T value) {
+ super.put(key, value);
+ }
+
+ public static <T> StringCanonizingOpenHashMap<T> deepCopy(StringCanonizingOpenHashMap<T> incomingMap, Function<T, T> deepCopier) {
+ StringCanonizingOpenHashMap<T> newMap = new StringCanonizingOpenHashMap<>(incomingMap.size(), 0.8f);
+ ObjectIterator<Entry<String, T>> iterator = incomingMap.object2ObjectEntrySet().fastIterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String, T> entry = iterator.next();
+ newMap.putWithoutInterning(entry.getKey(), deepCopier.apply(entry.getValue()));
+ }
+ return newMap;
+ }
+}
\ No newline at end of file

0 comments on commit d3b1401

Please sign in to comment.