From 2cfee315bb602a71ee8165be61d4961c36f46ebc Mon Sep 17 00:00:00 2001 From: RuleGaed Date: Fri, 15 May 2026 20:12:51 +0300 Subject: [PATCH] optimize warp lookup with map cache Replaced O(n) stream filter in getWarp() with O(1) HashMap lookup. Cache is built on startup and synced on warp add/delete commands. --- .../essentials/ZEssentialsPlugin.java | 20 ++++++++++++++++++- .../commands/warp/CommandDelWarp.java | 2 ++ .../commands/warp/CommandSetWarp.java | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/maxlego08/essentials/ZEssentialsPlugin.java b/src/main/java/fr/maxlego08/essentials/ZEssentialsPlugin.java index b15e5182..24938f0f 100644 --- a/src/main/java/fr/maxlego08/essentials/ZEssentialsPlugin.java +++ b/src/main/java/fr/maxlego08/essentials/ZEssentialsPlugin.java @@ -149,6 +149,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -163,6 +165,7 @@ public final class ZEssentialsPlugin extends ZPlugin implements EssentialsPlugin private final List materials = Arrays.stream(Material.values()).filter(e -> !e.name().startsWith("LEGACY_")).toList(); private final Enchantments enchantments = new ZEnchantments(); private final List permissionCheckers = new ArrayList<>(); + private volatile Map warpsByName = Collections.emptyMap(); private EssentialsUtils essentialsUtils; private ServerStorage serverStorage = new ZServerStorage(this); private InventoryManager inventoryManager; @@ -220,6 +223,7 @@ public void onEnable() { // Load configuration files this.configurationFiles.forEach(ConfigurationFile::load); ConfigStorage.getInstance().load(getPersist()); + rebuildWarpCache(); // Commands this.registerListener(this.commandManager = new ZCommandManager(this)); @@ -523,9 +527,23 @@ public List getWarps() { return ConfigStorage.warps; } + public void rebuildWarpCache() { + Map map = new HashMap<>(); + for (Warp warp : ConfigStorage.warps) { + map.put(warp.name().toLowerCase(), warp); + } + this.warpsByName = Collections.unmodifiableMap(map); + } + @Override public Optional getWarp(String name) { - return getWarps().stream().filter(warp -> warp.name().equalsIgnoreCase(name)).findFirst(); + Warp warp = this.warpsByName.get(name.toLowerCase()); + if (warp != null) return Optional.of(warp); + if (this.warpsByName.size() != ConfigStorage.warps.size()) { + rebuildWarpCache(); + return Optional.ofNullable(this.warpsByName.get(name.toLowerCase())); + } + return Optional.empty(); } @Override diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java index 2ab735ee..b9901f7b 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandDelWarp.java @@ -1,5 +1,6 @@ package fr.maxlego08.essentials.commands.commands.warp; +import fr.maxlego08.essentials.ZEssentialsPlugin; import fr.maxlego08.essentials.api.EssentialsPlugin; import fr.maxlego08.essentials.api.commands.CommandResultType; import fr.maxlego08.essentials.api.commands.Permission; @@ -35,6 +36,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { ConfigStorage.warps.removeIf(warp -> warp.name().equalsIgnoreCase(warpName)); ConfigStorage.getInstance().save(plugin.getPersist()); + ((ZEssentialsPlugin) plugin).rebuildWarpCache(); message(sender, Message.COMMAND_WARP_DELETE, "%name%", warpName); diff --git a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandSetWarp.java b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandSetWarp.java index 55cd3d60..34d462b2 100644 --- a/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandSetWarp.java +++ b/src/main/java/fr/maxlego08/essentials/commands/commands/warp/CommandSetWarp.java @@ -1,5 +1,6 @@ package fr.maxlego08.essentials.commands.commands.warp; +import fr.maxlego08.essentials.ZEssentialsPlugin; import fr.maxlego08.essentials.api.EssentialsPlugin; import fr.maxlego08.essentials.api.commands.CommandResultType; import fr.maxlego08.essentials.api.commands.Permission; @@ -40,6 +41,7 @@ protected CommandResultType perform(EssentialsPlugin plugin) { ConfigStorage.warps.removeIf(warp -> warp.name().equalsIgnoreCase(warpName)); ConfigStorage.warps.add(new Warp(warpName, new SafeLocation(this.player.getLocation()))); ConfigStorage.getInstance().save(plugin.getPersist()); + ((ZEssentialsPlugin) plugin).rebuildWarpCache(); message(sender, Message.COMMAND_WARP_CREATE, "%name%", warpName);