From cf45253c71946caca199f1f88fd87922f5f1e17f Mon Sep 17 00:00:00 2001 From: Auxilor Date: Sun, 6 Mar 2022 15:28:18 +0000 Subject: [PATCH] Fixed talisman fetching performance --- eco-core/core-plugin/build.gradle | 1 + .../talismans/util/TalismanChecks.kt | 173 ++++++++---------- 2 files changed, 74 insertions(+), 100 deletions(-) diff --git a/eco-core/core-plugin/build.gradle b/eco-core/core-plugin/build.gradle index 32e7dac..19596e7 100644 --- a/eco-core/core-plugin/build.gradle +++ b/eco-core/core-plugin/build.gradle @@ -3,6 +3,7 @@ version rootProject.version dependencies { compileOnly 'org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT' + compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.5' } build.dependsOn publishToMavenLocal diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/talismans/talismans/util/TalismanChecks.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/talismans/talismans/util/TalismanChecks.kt index 17a94d2..6d2dfb2 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/talismans/talismans/util/TalismanChecks.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/talismans/talismans/util/TalismanChecks.kt @@ -1,5 +1,7 @@ package com.willfp.talismans.talismans.util +import com.github.benmanes.caffeine.cache.Cache +import com.github.benmanes.caffeine.cache.Caffeine import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.config.updating.ConfigUpdater import com.willfp.talismans.TalismansPlugin.Companion.instance @@ -15,11 +17,18 @@ import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.BlockStateMeta import org.bukkit.persistence.PersistentDataType import java.util.* +import java.util.concurrent.TimeUnit import java.util.function.Function object TalismanChecks { - private val CACHED_TALISMANS = Collections.synchronizedMap(HashMap>()) - private val CACHED_TALISMAN_ITEMS = Collections.synchronizedMap(WeakHashMap>()) + private val CACHED_TALISMANS: Cache> = Caffeine.newBuilder() + .expireAfterWrite(2, TimeUnit.SECONDS) + .build() + + private val CACHED_TALISMAN_ITEMS: Cache> = Caffeine.newBuilder() + .expireAfterWrite(2, TimeUnit.SECONDS) + .build() + private val PROVIDERS: MutableSet>> = HashSet() private var readEnderChest = true @@ -76,17 +85,6 @@ object TalismanChecks { return getByID(id) } - /** - * Get all talismans that a player has active. - * - * @param player The player to query. - * @return A set of all found talismans. - */ - @JvmStatic - fun getTalismansOnPlayer(player: Player): Set { - return getTalismansOnPlayer(player, true) - } - /** * Get all talismans ItemStacks that a player has active. * @@ -98,117 +96,92 @@ object TalismanChecks { @JvmStatic fun getTalismanItemsOnPlayer( player: Player, - useCache: Boolean, vararg extra: ItemStack? ): Set { - if (useCache) { - val cached = CACHED_TALISMAN_ITEMS[player.uniqueId] - if (cached != null) { - return cached + return CACHED_TALISMAN_ITEMS.get(player) { + val contents = mutableListOf() + val rawContents = it.inventory.contents.toMutableList() + + if (readEnderChest) { + val enderChest = it.enderChest as Inventory? + + // Not always true, bug reported where it was null. + if (enderChest != null) { + rawContents.addAll(enderChest.contents) + } } - } - val contents = mutableListOf() - val rawContents = player.inventory.contents.toMutableList() - - if (readEnderChest) { - val enderChest = player.enderChest as Inventory? - - // Not always true, bug reported where it was null. - if (enderChest != null) { - rawContents.addAll(enderChest.contents) + if (offhandOnly) { + rawContents.clear() + rawContents.add(it.inventory.itemInOffHand) } - } - if (offhandOnly) { - rawContents.clear() - rawContents.add(player.inventory.itemInOffHand) - } - - rawContents.addAll(extra) - for (provider in PROVIDERS) { - rawContents.addAll(provider.apply(player)) - } - - for (rawContent in rawContents) { - if (rawContent == null) { - continue + rawContents.addAll(extra) + for (provider in PROVIDERS) { + rawContents.addAll(provider.apply(it)) } - if (readShulkerBoxes) { - val meta = rawContent.itemMeta - if (meta is BlockStateMeta) { - val shulkerMeta = meta - if (!shulkerMeta.hasBlockState()) { - continue + + for (rawContent in rawContents) { + if (rawContent == null) { + continue + } + if (readShulkerBoxes) { + val meta = rawContent.itemMeta + if (meta is BlockStateMeta) { + val shulkerMeta = meta + if (!shulkerMeta.hasBlockState()) { + continue + } + val state = shulkerMeta.blockState + if (state is ShulkerBox) { + contents.addAll(state.inventory.contents) + continue + } } - val state = shulkerMeta.blockState - if (state is ShulkerBox) { - contents.addAll(state.inventory.contents) - continue + } + contents.add(rawContent) + } + + val items = mutableMapOf() + + for (itemStack in contents) { + convert(itemStack) + val talis = getTalismanOnItem(itemStack) ?: continue + if (items.size >= getLimit(it)) { + break + } + items[talis] = itemStack + } + + if (PLUGIN.configYml.getBool("top-level-only")) { + for ((talisman, _) in items.toMap()) { + var lowerLevel = talisman.lowerLevel + while (lowerLevel != null) { + items.remove(lowerLevel) + lowerLevel = lowerLevel.lowerLevel } } } - contents.add(rawContent) + + items.values.toSet() } - - val items = mutableMapOf() - - for (itemStack in contents) { - convert(itemStack) - val talis = getTalismanOnItem(itemStack) ?: continue - if (items.size >= getLimit(player)) { - break - } - items[talis] = itemStack - } - - if (PLUGIN.configYml.getBool("top-level-only")) { - for ((talisman, _) in items.toMap()) { - var lowerLevel = talisman.lowerLevel - while (lowerLevel != null) { - items.remove(lowerLevel) - lowerLevel = lowerLevel.lowerLevel - } - } - } - - if (useCache) { - CACHED_TALISMAN_ITEMS[player.uniqueId] = items.values.toSet() - PLUGIN.scheduler.runLater({ CACHED_TALISMAN_ITEMS.remove(player.uniqueId) }, 40) - } - - return items.values.toSet() } /** * Get all talismans that a player has active. * * @param player The player to query. - * @param useCache If the cache should be checked. * @param extra Bonus items. * @return A set of all found talismans. */ @JvmStatic fun getTalismansOnPlayer( player: Player, - useCache: Boolean, vararg extra: ItemStack? ): Set { - if (useCache) { - val cached = CACHED_TALISMANS[player.uniqueId] - if (cached != null) { - return cached - } + return CACHED_TALISMANS.get(player) { + getTalismanItemsOnPlayer(it, *extra).mapNotNull { itemStack -> getTalismanOnItem(itemStack) }.toSet() } - - val found = getTalismanItemsOnPlayer(player, useCache, *extra).mapNotNull { getTalismanOnItem(it) }.toSet() - - if (useCache) { - CACHED_TALISMANS[player.uniqueId] = found - PLUGIN.scheduler.runLater({ CACHED_TALISMANS.remove(player.uniqueId) }, 40) - } - - return found } /** @@ -218,12 +191,12 @@ object TalismanChecks { */ @JvmStatic fun clearCache(player: Player) { - CACHED_TALISMAN_ITEMS.remove(player.uniqueId) - CACHED_TALISMANS.remove(player.uniqueId) + CACHED_TALISMAN_ITEMS.invalidate(player) + CACHED_TALISMANS.invalidate(player) } /** - * Register ItemStack provider (inventory extension, eg talisman bag). + * Register ItemStack provider (inventory extension, e.g. talisman bag). * * @param provider The provider. */