Added ability to manually categorize keys to improve performance
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -9,6 +11,8 @@ import java.util.Set;
|
||||
/**
|
||||
* API to register persistent data keys.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface KeyRegistry {
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
@@ -24,6 +28,15 @@ public interface KeyRegistry {
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
||||
|
||||
/**
|
||||
* Mark key as category.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param category The category.
|
||||
*/
|
||||
void markKeyAs(@NotNull PersistentDataKey<?> key,
|
||||
@NotNull KeyRegistry.KeyCategory category);
|
||||
|
||||
/**
|
||||
* Get persistent data key from namespaced key.
|
||||
*
|
||||
@@ -32,4 +45,19 @@ public interface KeyRegistry {
|
||||
*/
|
||||
@Nullable
|
||||
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
|
||||
|
||||
/**
|
||||
* Locations for key categorization.
|
||||
*/
|
||||
enum KeyCategory {
|
||||
/**
|
||||
* Player keys.
|
||||
*/
|
||||
PLAYER,
|
||||
|
||||
/**
|
||||
* Server keys.
|
||||
*/
|
||||
SERVER
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -14,7 +13,7 @@ import java.util.Set;
|
||||
*
|
||||
* @param <T> The type of the data.
|
||||
*/
|
||||
public class PersistentDataKey<T> {
|
||||
public final class PersistentDataKey<T> {
|
||||
/**
|
||||
* The key of the persistent data value.
|
||||
*/
|
||||
@@ -83,6 +82,32 @@ public class PersistentDataKey<T> {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorize key as a server key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
*/
|
||||
public PersistentDataKey<T> server() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorize key as a player key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
*/
|
||||
public PersistentDataKey<T> player() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all persistent data keys.
|
||||
*
|
||||
|
||||
@@ -187,10 +187,11 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
(Eco.getHandler() as EcoHandler).setAdventure(BukkitAudiences.create(this))
|
||||
}
|
||||
|
||||
this.logger.info("Ignore messages about deprecated events!")
|
||||
|
||||
// Init FIS
|
||||
this.getProxy(FastItemStackFactoryProxy::class.java).create(ItemStack(Material.AIR)).unwrap()
|
||||
|
||||
// Preload categorized persistent data keys
|
||||
(Eco.getHandler().profileHandler as EcoProfileHandler).initialize()
|
||||
}
|
||||
|
||||
override fun handleDisable() {
|
||||
@@ -216,7 +217,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
CustomItemsManager.registerAllItems()
|
||||
CustomEntitiesManager.registerAllEntities()
|
||||
ShopManager.registerEcoProvider()
|
||||
(Eco.getHandler().profileHandler as EcoProfileHandler).runPostInit()
|
||||
}
|
||||
|
||||
override fun loadIntegrationLoaders(): List<IntegrationLoader> {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.willfp.eco.internal.spigot.data
|
||||
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import org.bukkit.NamespacedKey
|
||||
|
||||
class EcoKeyRegistry: KeyRegistry {
|
||||
class EcoKeyRegistry : KeyRegistry {
|
||||
private val registry = mutableMapOf<NamespacedKey, PersistentDataKey<*>>()
|
||||
private val categories = mutableMapOf<NamespacedKey, KeyRegistry.KeyCategory>()
|
||||
|
||||
override fun registerKey(key: PersistentDataKey<*>) {
|
||||
if (this.registry.containsKey(key.key)) {
|
||||
@@ -41,6 +43,11 @@ class EcoKeyRegistry: KeyRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
override fun markKeyAs(key: PersistentDataKey<*>, category: KeyRegistry.KeyCategory) {
|
||||
categories[key.key] = category
|
||||
(Eco.getHandler().profileHandler as EcoProfileHandler).handler.categorize(key, category) // ew
|
||||
}
|
||||
|
||||
override fun getKeyFrom(namespacedKey: NamespacedKey): PersistentDataKey<*>? {
|
||||
return registry[namespacedKey]
|
||||
}
|
||||
|
||||
@@ -65,4 +65,4 @@ class EcoServerProfile(
|
||||
override fun toString(): String {
|
||||
return "EcoServerProfile"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class EcoProfileHandler(
|
||||
plugin: EcoSpigotPlugin
|
||||
) : ProfileHandler {
|
||||
private val loaded = mutableMapOf<UUID, Profile>()
|
||||
private val handler: DataHandler = if (useSql) MySQLDataHandler(plugin, this) else
|
||||
val handler: DataHandler = if (useSql) MySQLDataHandler(plugin, this) else
|
||||
YamlDataHandler(plugin, this)
|
||||
|
||||
fun loadGenericProfile(uuid: UUID): Profile {
|
||||
@@ -64,7 +64,7 @@ class EcoProfileHandler(
|
||||
handler.save()
|
||||
}
|
||||
|
||||
fun runPostInit() {
|
||||
handler.runPostInit()
|
||||
fun initialize() {
|
||||
handler.initialize()
|
||||
}
|
||||
}
|
||||
@@ -15,23 +15,23 @@ object KeyHelpers {
|
||||
|
||||
val key = NamespacedKeyUtils.fromStringOrNull(split[0]) ?: return null
|
||||
val type = PersistentDataKeyType.valueOf(split[1]) ?: return null
|
||||
return when (type.name()) {
|
||||
"STRING" -> PersistentDataKey(
|
||||
return when (type) {
|
||||
PersistentDataKeyType.STRING -> PersistentDataKey(
|
||||
key,
|
||||
type as PersistentDataKeyType<String>,
|
||||
if(split.size >= 3) split.toList().subList(2, split.size).joinToString("") else ""
|
||||
if (split.size >= 3) split.toList().subList(2, split.size).joinToString("") else ""
|
||||
)
|
||||
"INT" -> PersistentDataKey(
|
||||
PersistentDataKeyType.INT -> PersistentDataKey(
|
||||
key,
|
||||
type as PersistentDataKeyType<Int>,
|
||||
split[2].toInt()
|
||||
)
|
||||
"DOUBLE" -> PersistentDataKey(
|
||||
PersistentDataKeyType.DOUBLE -> PersistentDataKey(
|
||||
key,
|
||||
type as PersistentDataKeyType<Double>,
|
||||
split[2].toDouble()
|
||||
)
|
||||
"BOOLEAN" -> PersistentDataKey(
|
||||
PersistentDataKeyType.BOOLEAN -> PersistentDataKey(
|
||||
key,
|
||||
type as PersistentDataKeyType<Boolean>,
|
||||
java.lang.Boolean.parseBoolean(split[2])
|
||||
@@ -43,4 +43,4 @@ object KeyHelpers {
|
||||
fun serializeToString(key: PersistentDataKey<*>): String {
|
||||
return "${key.key};${key.type.name()};${key.defaultValue}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.internal.spigot.data.storage
|
||||
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import org.bukkit.NamespacedKey
|
||||
import java.util.UUID
|
||||
@@ -8,7 +9,11 @@ interface DataHandler {
|
||||
fun save()
|
||||
fun saveAll(uuids: Iterable<UUID>)
|
||||
|
||||
fun runPostInit() {
|
||||
fun categorize(key: PersistentDataKey<*>, category: KeyRegistry.KeyCategory) {
|
||||
|
||||
}
|
||||
|
||||
fun initialize() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot.data.storage
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||
@@ -31,6 +32,7 @@ import java.util.UUID
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.Future
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MySQLDataHandler(
|
||||
@@ -42,7 +44,8 @@ class MySQLDataHandler(
|
||||
UUIDTable("eco_players"),
|
||||
plugin,
|
||||
plugin.dataYml.getStrings("categorized-keys.player")
|
||||
.mapNotNull { KeyHelpers.deserializeFromString(it) }
|
||||
.mapNotNull { KeyHelpers.deserializeFromString(it) },
|
||||
KeyRegistry.KeyCategory.PLAYER
|
||||
)
|
||||
|
||||
private val serverHandler = ImplementedMySQLHandler(
|
||||
@@ -50,7 +53,8 @@ class MySQLDataHandler(
|
||||
UUIDTable("eco_server"),
|
||||
plugin,
|
||||
plugin.dataYml.getStrings("categorized-keys.server")
|
||||
.mapNotNull { KeyHelpers.deserializeFromString(it) }
|
||||
.mapNotNull { KeyHelpers.deserializeFromString(it) },
|
||||
KeyRegistry.KeyCategory.SERVER
|
||||
)
|
||||
|
||||
override fun saveAll(uuids: Iterable<UUID>) {
|
||||
@@ -84,6 +88,14 @@ class MySQLDataHandler(
|
||||
}
|
||||
}
|
||||
|
||||
override fun categorize(key: PersistentDataKey<*>, category: KeyRegistry.KeyCategory) {
|
||||
if (category == KeyRegistry.KeyCategory.SERVER) {
|
||||
serverHandler.ensureKeyRegistration(key.key)
|
||||
} else {
|
||||
playerHandler.ensureKeyRegistration(key.key)
|
||||
}
|
||||
}
|
||||
|
||||
override fun save() {
|
||||
plugin.dataYml.set(
|
||||
"categorized-keys.player",
|
||||
@@ -98,9 +110,9 @@ class MySQLDataHandler(
|
||||
plugin.dataYml.save()
|
||||
}
|
||||
|
||||
override fun runPostInit() {
|
||||
playerHandler.runPostInit()
|
||||
serverHandler.runPostInit()
|
||||
override fun initialize() {
|
||||
playerHandler.initialize()
|
||||
serverHandler.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,12 +121,14 @@ private class ImplementedMySQLHandler(
|
||||
private val handler: EcoProfileHandler,
|
||||
private val table: UUIDTable,
|
||||
private val plugin: EcoPlugin,
|
||||
private val knownKeys: Collection<PersistentDataKey<*>>
|
||||
private val knownKeys: Collection<PersistentDataKey<*>>,
|
||||
private val category: KeyRegistry.KeyCategory
|
||||
) {
|
||||
private val columns = mutableMapOf<String, Column<*>>()
|
||||
private val threadFactory = ThreadFactoryBuilder().setNameFormat("eco-mysql-thread-%d").build()
|
||||
private val executor = Executors.newFixedThreadPool(plugin.configYml.getInt("mysql.threads"), threadFactory)
|
||||
val registeredKeys = ConcurrentHashMap<NamespacedKey, PersistentDataKey<*>>()
|
||||
private val currentlyProcessingRegistration = ConcurrentHashMap<NamespacedKey, Future<*>>()
|
||||
|
||||
init {
|
||||
val config = HikariConfig()
|
||||
@@ -145,7 +159,7 @@ private class ImplementedMySQLHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun runPostInit() {
|
||||
fun initialize() {
|
||||
transaction {
|
||||
for (key in knownKeys) {
|
||||
registerColumn(key, table)
|
||||
@@ -170,12 +184,21 @@ private class ImplementedMySQLHandler(
|
||||
return
|
||||
}
|
||||
|
||||
transaction {
|
||||
registerColumn(persistentKey, table)
|
||||
SchemaUtils.createMissingTablesAndColumns(table, withLogs = false)
|
||||
val future = currentlyProcessingRegistration[key]
|
||||
|
||||
if (future != null) {
|
||||
future.get()
|
||||
return
|
||||
}
|
||||
|
||||
registeredKeys[key] = persistentKey
|
||||
currentlyProcessingRegistration[key] = executor.submit {
|
||||
transaction {
|
||||
registerColumn(persistentKey, table)
|
||||
SchemaUtils.createMissingTablesAndColumns(table, withLogs = false)
|
||||
}
|
||||
registeredKeys[key] = persistentKey
|
||||
currentlyProcessingRegistration.remove(key)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
categorized-keys:
|
||||
# Preloading known keys (as of the release of 6.25.0) for optimal performance.
|
||||
# This is only used when MySQL is enabled as the columns must be added each time a new key is registered.
|
||||
player:
|
||||
- ecoskills:crit_damage;INT;0
|
||||
- ecoskills:strong_impact;INT;0
|
||||
|
||||
Reference in New Issue
Block a user