Fixed CustomEnchantLookup performance issues
This commit is contained in:
@@ -10,5 +10,6 @@ dependencies {
|
||||
compileOnly 'io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
|
||||
compileOnly 'io.lumine.xikage:MythicMobs:4.9.1'
|
||||
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.5'
|
||||
compileOnly fileTree(dir: '../../lib', include: ['*.jar'])
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.willfp.ecoenchants.enchantments.custom;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.ecoenchants.EcoEnchantsPlugin;
|
||||
import com.willfp.ecoenchants.enchantments.EcoEnchant;
|
||||
@@ -17,8 +19,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CustomEnchantLookup {
|
||||
@@ -30,12 +31,16 @@ public class CustomEnchantLookup {
|
||||
/**
|
||||
* Cached items.
|
||||
*/
|
||||
private static final Map<UUID, Map<ItemStack, EnchantmentTarget.Slot>> ITEM_CACHE = new WeakHashMap<>();
|
||||
private static final Cache<Player, Map<ItemStack, EnchantmentTarget.Slot>> ITEM_CACHE = Caffeine.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Cached enchant levels.
|
||||
*/
|
||||
private static final Map<UUID, Collection<CustomEcoEnchantLevel>> ENCHANT_LEVELS_CACHE = new WeakHashMap<>();
|
||||
private static final Cache<Player, Collection<CustomEcoEnchantLevel>> ENCHANT_LEVELS_CACHE = Caffeine.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Instance of EcoEnchants.
|
||||
@@ -54,73 +59,62 @@ public class CustomEnchantLookup {
|
||||
/**
|
||||
* Provide ItemStacks.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param p The player.
|
||||
* @return The ItemStacks.
|
||||
*/
|
||||
public static Map<ItemStack, EnchantmentTarget.Slot> provide(@NotNull final Player player) {
|
||||
if (ITEM_CACHE.containsKey(player.getUniqueId())) {
|
||||
return new HashMap<>(ITEM_CACHE.get(player.getUniqueId()));
|
||||
}
|
||||
|
||||
Map<ItemStack, EnchantmentTarget.Slot> found = new HashMap<>();
|
||||
for (Function<Player, Map<ItemStack, EnchantmentTarget.Slot>> provider : PROVIDERS) {
|
||||
found.putAll(provider.apply(player));
|
||||
}
|
||||
found.keySet().removeIf(Objects::isNull);
|
||||
|
||||
ITEM_CACHE.put(player.getUniqueId(), found);
|
||||
PLUGIN.getScheduler().runLater(() -> ITEM_CACHE.remove(player.getUniqueId()), 40);
|
||||
|
||||
return found;
|
||||
public static Map<ItemStack, EnchantmentTarget.Slot> provide(@NotNull final Player p) {
|
||||
return ITEM_CACHE.get(p, player -> {
|
||||
Map<ItemStack, EnchantmentTarget.Slot> found = new HashMap<>();
|
||||
for (Function<Player, Map<ItemStack, EnchantmentTarget.Slot>> provider : PROVIDERS) {
|
||||
found.putAll(provider.apply(player));
|
||||
}
|
||||
found.keySet().removeIf(Objects::isNull);
|
||||
return found;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide levels.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param p The player.
|
||||
* @return The levels.
|
||||
*/
|
||||
public static List<CustomEcoEnchantLevel> provideLevels(@NotNull final Player player) {
|
||||
if (ENCHANT_LEVELS_CACHE.containsKey(player.getUniqueId())) {
|
||||
return new ArrayList<>(ENCHANT_LEVELS_CACHE.get(player.getUniqueId()));
|
||||
}
|
||||
public static List<CustomEcoEnchantLevel> provideLevels(@NotNull final Player p) {
|
||||
return new ArrayList<>(ENCHANT_LEVELS_CACHE.get(p, player -> {
|
||||
List<CustomEcoEnchantLevel> found = new ArrayList<>();
|
||||
|
||||
List<CustomEcoEnchantLevel> found = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<ItemStack, EnchantmentTarget.Slot> entry : provide(player).entrySet()) {
|
||||
ItemStack itemStack = entry.getKey();
|
||||
EnchantmentTarget.Slot slot = entry.getValue();
|
||||
if (itemStack == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Map<EcoEnchant, Integer> enchants = EnchantChecks.getEnchantsOnItem(itemStack);
|
||||
|
||||
if (enchants.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Map.Entry<EcoEnchant, Integer> enchantEntry : enchants.entrySet()) {
|
||||
if (!(enchantEntry.getKey() instanceof CustomEcoEnchant enchant)) {
|
||||
for (Map.Entry<ItemStack, EnchantmentTarget.Slot> entry : provide(player).entrySet()) {
|
||||
ItemStack itemStack = entry.getKey();
|
||||
EnchantmentTarget.Slot slot = entry.getValue();
|
||||
if (itemStack == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slot != EnchantmentTarget.Slot.ANY) {
|
||||
if (!enchant.getTargets().stream()
|
||||
.map(EnchantmentTarget::getSlot).toList()
|
||||
.contains(slot)) {
|
||||
continue;
|
||||
}
|
||||
Map<EcoEnchant, Integer> enchants = EnchantChecks.getEnchantsOnItem(itemStack);
|
||||
|
||||
if (enchants.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
found.add(enchant.getLevel(enchantEntry.getValue()));
|
||||
for (Map.Entry<EcoEnchant, Integer> enchantEntry : enchants.entrySet()) {
|
||||
if (!(enchantEntry.getKey() instanceof CustomEcoEnchant enchant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slot != EnchantmentTarget.Slot.ANY) {
|
||||
if (!enchant.getTargets().stream()
|
||||
.map(EnchantmentTarget::getSlot).toList()
|
||||
.contains(slot)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
found.add(enchant.getLevel(enchantEntry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ENCHANT_LEVELS_CACHE.put(player.getUniqueId(), found);
|
||||
PLUGIN.getScheduler().runLater(() -> ENCHANT_LEVELS_CACHE.remove(player.getUniqueId()), 40);
|
||||
|
||||
return found;
|
||||
return found;
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,8 +123,8 @@ public class CustomEnchantLookup {
|
||||
* @param player The player.
|
||||
*/
|
||||
public static void clearCache(@NotNull final Player player) {
|
||||
ITEM_CACHE.remove(player.getUniqueId());
|
||||
ENCHANT_LEVELS_CACHE.remove(player.getUniqueId());
|
||||
ITEM_CACHE.invalidate(player);
|
||||
ENCHANT_LEVELS_CACHE.invalidate(player);
|
||||
}
|
||||
|
||||
static {
|
||||
|
||||
Reference in New Issue
Block a user