From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Hugo Planque Date: Thu, 21 Jan 2021 17:56:03 +0100 Subject: [PATCH] New NBT cache Original code by YatopiaMC, licensed under MIT You can find the original code on https://github.com/YatopiaMC/Yatopia diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java index b470da69f271d1a5ebb9727c0c34944e85ce3a51..5e80825c0e98c0eb5c4309a9234e7b03d2d383db 100644 --- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java @@ -24,6 +24,7 @@ public class PlayerDataStorage { private static final Logger LOGGER = LogManager.getLogger(); private final File playerDir; protected final DataFixer fixerUpper; + private final wtf.etil.mirai.server.cache.NBTCache dataCache = new wtf.etil.mirai.server.cache.NBTCache(); // Mirai - NBT Cache system public PlayerDataStorage(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer) { this.fixerUpper = dataFixer; @@ -37,11 +38,24 @@ public class PlayerDataStorage { CompoundTag nbttagcompound = player.saveWithoutId(new CompoundTag()); File file = File.createTempFile(player.getStringUUID() + "-", ".dat", this.playerDir); - NbtIo.writeCompressed(nbttagcompound, file); - File file1 = new File(this.playerDir, player.getStringUUID() + ".dat"); - File file2 = new File(this.playerDir, player.getStringUUID() + ".dat_old"); + // Mirai start - NBT Cache system + Runnable task = () -> { + try { + NbtIo.writeCompressed(nbttagcompound, file); + File file1 = new File(this.playerDir, player.getStringUUID() + ".dat"); + File file2 = new File(this.playerDir, player.getStringUUID() + ".dat_old"); + + Util.safeReplaceFile(file1, file, file2); + } catch (Exception exception) { + PlayerDataStorage.LOGGER.error("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper + } + }; + synchronized (this.dataCache){ + this.dataCache.put(file, nbttagcompound); + } + net.minecraft.server.MCUtil.asyncExecutor.execute(task); + // Mirai end - Util.safeReplaceFile(file1, file, file2); } catch (Exception exception) { PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper } @@ -56,9 +70,18 @@ public class PlayerDataStorage { File file = new File(this.playerDir, player.getStringUUID() + ".dat"); // Spigot Start boolean usingWrongFile = false; - if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // Paper - Check online mode first + // Mirai start - NBT Cache system + boolean normalFile = file.exists() && file.isFile(); + CompoundTag playerData; + synchronized (this.dataCache){ + playerData = this.dataCache.get(file); + } + if (playerData == null && org.bukkit.Bukkit.getOnlineMode() && !normalFile ) // Paper - Check online mode first { file = new File( this.playerDir, java.util.UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + player.getScoreboardName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); + synchronized (this.dataCache){ + playerData = this.dataCache.get(file); + } if ( file.exists() ) { usingWrongFile = true; @@ -67,9 +90,12 @@ public class PlayerDataStorage { } // Spigot End - if (file.exists() && file.isFile()) { + if (playerData != null) { + nbttagcompound = playerData; + } else if (normalFile) { nbttagcompound = NbtIo.readCompressed(file); } + // Mirai end // Spigot Start if ( usingWrongFile ) { diff --git a/src/main/java/wtf/etil/mirai/server/cache/NBTCache.java b/src/main/java/wtf/etil/mirai/server/cache/NBTCache.java new file mode 100644 index 0000000000000000000000000000000000000000..10be297ed6e7aaa963d5bdcd40a589e877884cf7 --- /dev/null +++ b/src/main/java/wtf/etil/mirai/server/cache/NBTCache.java @@ -0,0 +1,32 @@ +package wtf.etil.mirai.server.cache; + +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenCustomHashMap; +import net.minecraft.server.MinecraftServer; +import net.minecraft.nbt.CompoundTag; + +import java.io.File; + +public class NBTCache extends Object2ObjectLinkedOpenCustomHashMap { + + public NBTCache() { + super(100, 0.75F, new Strategy() { + @Override + public int hashCode(File k) { + return k.hashCode(); + } + + @Override + public boolean equals(File k, File k1) { + return k.equals(k1); + } + }); + } + + @Override + public CompoundTag put(File k, CompoundTag v) { + if (this.size() > MinecraftServer.getServer().getPlayerCount()) { + this.removeLast(); + } + return super.putAndMoveToFirst(k, v); + } +} \ No newline at end of file