MySQL Data Changes: Keys are now registered on first read/write

This commit is contained in:
Auxilor
2022-02-16 16:32:38 +00:00
parent 9a51fb8358
commit 5aeeafc041
6 changed files with 51 additions and 73 deletions

View File

@@ -43,4 +43,8 @@ class EcoKeyRegistry: KeyRegistry {
else -> throw NullPointerException("Null value found!")
}
}
}
override fun getKeyFrom(namespacedKey: NamespacedKey): PersistentDataKey<*>? {
return registry[namespacedKey]
}
}

View File

@@ -11,15 +11,11 @@ interface DataHandler {
fun saveAll(uuids: Iterable<UUID>)
fun updateKeys() {
}
fun savePlayer(uuid: UUID) {
saveKeysForPlayer(uuid, PersistentDataKey.values())
saveKeysFor(uuid, PersistentDataKey.values())
}
fun <T> write(uuid: UUID, key: NamespacedKey, value: T)
fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>)
fun saveKeysFor(uuid: UUID, keys: Set<PersistentDataKey<*>>)
fun <T> read(uuid: UUID, key: NamespacedKey): T?
}

View File

@@ -28,6 +28,7 @@ import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import java.util.UUID
import java.util.concurrent.Callable
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors
@Suppress("UNCHECKED_CAST")
@@ -39,13 +40,13 @@ class MySQLDataHandler(
handler,
UUIDTable("eco_players"),
plugin
) { !it.isServerKey }
)
private val serverHandler = ImplementedMySQLHandler(
handler,
UUIDTable("eco_server"),
plugin
) { it.isServerKey }
)
override fun saveAll(uuids: Iterable<UUID>) {
serverHandler.saveAll(uuids.filter { it == serverProfileUUID })
@@ -58,7 +59,7 @@ class MySQLDataHandler(
}
}
override fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
override fun saveKeysFor(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
applyFor(uuid) {
it.saveKeysForRow(uuid, keys)
}
@@ -70,11 +71,6 @@ class MySQLDataHandler(
}
}
override fun updateKeys() {
playerHandler.updateKeys()
serverHandler.updateKeys()
}
private inline fun <R> applyFor(uuid: UUID, function: (ImplementedMySQLHandler) -> R): R {
return if (uuid == serverProfileUUID) {
function(serverHandler)
@@ -88,12 +84,12 @@ class MySQLDataHandler(
private class ImplementedMySQLHandler(
private val handler: EcoProfileHandler,
private val table: UUIDTable,
plugin: EcoPlugin,
private val validator: (PersistentDataKey<*>) -> Boolean
plugin: EcoPlugin
) {
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)
private val registeredKeys = ConcurrentHashMap.newKeySet<NamespacedKey>()
init {
val config = HikariConfig()
@@ -108,7 +104,6 @@ private class ImplementedMySQLHandler(
Database.connect(HikariDataSource(config))
transaction {
SchemaUtils.create(table)
}
@@ -125,25 +120,27 @@ private class ImplementedMySQLHandler(
}
}
fun updateKeys() {
transaction {
for (key in Eco.getHandler().keyRegistry.registeredKeys) {
if (validator(key)) {
registerColumn(key, table)
}
}
fun ensureKeyRegistration(key: NamespacedKey) {
if (registeredKeys.contains(key)) {
return
}
transaction {
val persistentKey = Eco.getHandler().keyRegistry.getKeyFrom(key)!!
registerColumn(persistentKey, table)
SchemaUtils.createMissingTablesAndColumns(table, withLogs = false)
registeredKeys.add(key)
}
}
fun <T> write(uuid: UUID, key: NamespacedKey, value: T) {
getRow(uuid)
writeAsserted(uuid, key, value)
getOrCreateRow(uuid)
doWrite(uuid, key, value)
}
private fun <T> writeAsserted(uuid: UUID, key: NamespacedKey, value: T) {
val column: Column<T> = getColumn(key.toString()) as Column<T>
private fun <T> doWrite(uuid: UUID, key: NamespacedKey, value: T) {
val column: Column<T> = getColumn(key) as Column<T>
executor.submit {
transaction {
@@ -169,12 +166,10 @@ private class ImplementedMySQLHandler(
executor.submit {
transaction {
getRow(uuid)
getOrCreateRow(uuid)
for (key in keys) {
if (validator(key)) {
writeAsserted(uuid, key.key, profile.read(key))
}
doWrite(uuid, key.key, profile.read(key))
}
}
}
@@ -184,8 +179,8 @@ private class ImplementedMySQLHandler(
val doRead = Callable<T?> {
var value: T? = null
transaction {
val player = getRow(uuid)
value = player[getColumn(key.toString())] as T?
val row = getOrCreateRow(uuid)
value = row[getColumn(key)] as T?
}
return@Callable value
@@ -219,28 +214,30 @@ private class ImplementedMySQLHandler(
}
}
private fun getColumn(name: String): Column<*> {
private fun getColumn(key: NamespacedKey): Column<*> {
ensureKeyRegistration(key)
val name = key.toString()
val cached = columns[name]
if (cached != null) {
return cached
}
columns[name] = table.columns.stream().filter { it.name == name }.findFirst().get()
return getColumn(name)
return getColumn(key)
}
private fun getRow(uuid: UUID): ResultRow {
val player = transaction {
private fun getOrCreateRow(uuid: UUID): ResultRow {
val row = transaction {
table.select { table.id eq uuid }.limit(1).singleOrNull()
}
return if (player != null) {
player
return if (row != null) {
row
} else {
transaction {
table.insert { it[id] = uuid }
}
getRow(uuid)
getOrCreateRow(uuid)
}
}
}

View File

@@ -27,7 +27,7 @@ class YamlDataHandler(
save()
}
override fun saveKeysForPlayer(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
override fun saveKeysFor(uuid: UUID, keys: Set<PersistentDataKey<*>>) {
val profile = handler.loadGenericProfile(uuid)
for (key in keys) {