Skip to content

Commit 633ae96

Browse files
authored
Remove lookup joins (#327)
1 parent 536b6b7 commit 633ae96

File tree

2 files changed

+41
-44
lines changed

2 files changed

+41
-44
lines changed
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package com.github.quiltservertools.ledger.database
22

3-
import com.google.common.cache.Cache
4-
import com.google.common.cache.CacheBuilder
3+
import com.google.common.collect.BiMap
4+
import com.google.common.collect.HashBiMap
55
import net.minecraft.util.Identifier
66
import java.util.UUID
77

88
object DatabaseCacheService {
9-
val actionIdentifierKeys: Cache<String, Int> = CacheBuilder.newBuilder().build()
9+
val actionIdentifierKeys: BiMap<String, Int> = HashBiMap.create()
1010

11-
val worldIdentifierKeys: Cache<Identifier, Int> = CacheBuilder.newBuilder().build()
11+
val worldIdentifierKeys: BiMap<Identifier, Int> = HashBiMap.create()
1212

13-
val objectIdentifierKeys: Cache<Identifier, Int> = CacheBuilder.newBuilder().build()
13+
val objectIdentifierKeys: BiMap<Identifier, Int> = HashBiMap.create()
1414

15-
val sourceKeys: Cache<String, Int> = CacheBuilder.newBuilder().build()
15+
val sourceKeys: BiMap<String, Int> = HashBiMap.create()
1616

17-
val playerKeys: Cache<UUID, Int> = CacheBuilder.newBuilder().build()
17+
val playerKeys: BiMap<UUID, Int> = HashBiMap.create()
1818
}

src/main/kotlin/com/github/quiltservertools/ledger/database/DatabaseManager.kt

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import com.github.quiltservertools.ledger.logWarn
1515
import com.github.quiltservertools.ledger.registry.ActionRegistry
1616
import com.github.quiltservertools.ledger.utility.Negatable
1717
import com.github.quiltservertools.ledger.utility.PlayerResult
18-
import com.google.common.cache.Cache
18+
import com.google.common.collect.BiMap
1919
import com.mojang.authlib.GameProfile
2020
import kotlinx.coroutines.CoroutineName
2121
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -41,12 +41,10 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.lessEq
4141
import org.jetbrains.exposed.sql.SqlLogger
4242
import org.jetbrains.exposed.sql.Transaction
4343
import org.jetbrains.exposed.sql.addLogger
44-
import org.jetbrains.exposed.sql.alias
4544
import org.jetbrains.exposed.sql.and
4645
import org.jetbrains.exposed.sql.andWhere
4746
import org.jetbrains.exposed.sql.batchInsert
4847
import org.jetbrains.exposed.sql.deleteWhere
49-
import org.jetbrains.exposed.sql.innerJoin
5048
import org.jetbrains.exposed.sql.insertAndGetId
5149
import org.jetbrains.exposed.sql.insertIgnore
5250
import org.jetbrains.exposed.sql.or
@@ -136,6 +134,9 @@ object DatabaseManager {
136134
Tables.Source.all().forEach {
137135
cache.sourceKeys.put(it.name, it.id.value)
138136
}
137+
Tables.Player.all().forEach {
138+
cache.playerKeys.put(it.playerId, it.id.value)
139+
}
139140
}
140141
}
141142

@@ -182,14 +183,16 @@ object DatabaseManager {
182183
}
183184

184185
suspend fun selectRollback(params: ActionSearchParams): List<ActionType> = execute {
185-
val query = buildQuery()
186+
val query = Tables.Actions
187+
.selectAll()
186188
.where(buildQueryParams(params) and (Tables.Actions.rolledBack eq false))
187189
.orderBy(Tables.Actions.id, SortOrder.DESC)
188190
return@execute getActionsFromQuery(query)
189191
}
190192

191193
suspend fun selectRestore(params: ActionSearchParams): List<ActionType> = execute {
192-
val query = buildQuery()
194+
val query = Tables.Actions
195+
.selectAll()
193196
.where(buildQueryParams(params) and (Tables.Actions.rolledBack eq true))
194197
.orderBy(Tables.Actions.id, SortOrder.ASC)
195198
return@execute getActionsFromQuery(query)
@@ -208,27 +211,33 @@ object DatabaseManager {
208211
private fun getActionsFromQuery(query: Query): List<ActionType> {
209212
val actions = mutableListOf<ActionType>()
210213

214+
val actionIdentifierCache = DatabaseCacheService.actionIdentifierKeys.inverse()
215+
val worldCache = DatabaseCacheService.worldIdentifierKeys.inverse()
216+
val objectIdentifierCache = DatabaseCacheService.objectIdentifierKeys.inverse()
217+
val sourceCache = DatabaseCacheService.sourceKeys.inverse()
218+
val playerCache = DatabaseCacheService.playerKeys.inverse()
219+
211220
for (action in query) {
212-
val typeSupplier = ActionRegistry.getType(action[Tables.ActionIdentifiers.actionIdentifier])
221+
val typeSupplier = ActionRegistry.getType(
222+
actionIdentifierCache[action[Tables.Actions.actionIdentifier].value]!!
223+
)
213224
if (typeSupplier == null) {
214-
logWarn("Unknown action type ${action[Tables.ActionIdentifiers.actionIdentifier]}")
225+
logWarn("Unknown action type ${actionIdentifierCache[action[Tables.Actions.actionIdentifier].value]}")
215226
continue
216227
}
217228

218229
val type = typeSupplier.get()
219230
type.id = action[Tables.Actions.id].value
220231
type.timestamp = action[Tables.Actions.timestamp]
221232
type.pos = BlockPos(action[Tables.Actions.x], action[Tables.Actions.y], action[Tables.Actions.z])
222-
type.world = Identifier.tryParse(action[Tables.Worlds.identifier])
223-
type.objectIdentifier = Identifier.of(action[Tables.ObjectIdentifiers.identifier])
224-
type.oldObjectIdentifier = Identifier.of(
225-
action[Tables.ObjectIdentifiers.alias("oldObjects")[Tables.ObjectIdentifiers.identifier]]
226-
)
233+
type.world = worldCache[action[Tables.Actions.world].value]
234+
type.objectIdentifier = objectIdentifierCache[action[Tables.Actions.objectId].value]!!
235+
type.oldObjectIdentifier = objectIdentifierCache[action[Tables.Actions.oldObjectId].value]!!
227236
type.objectState = action[Tables.Actions.blockState]
228237
type.oldObjectState = action[Tables.Actions.oldBlockState]
229-
type.sourceName = action[Tables.Sources.name]
230-
type.sourceProfile = action.getOrNull(Tables.Players.playerId)?.let {
231-
GameProfile(it, action[Tables.Players.playerName])
238+
type.sourceName = sourceCache[action[Tables.Actions.sourceName].value]!!
239+
type.sourceProfile = action.getOrNull(Tables.Actions.sourcePlayer)?.let {
240+
Ledger.server.userCache?.getByUuid(playerCache[it.value]!!)?.orElse(null)
232241
}
233242
type.extraData = action[Tables.Actions.extraData]
234243
type.rolledBack = action[Tables.Actions.rolledBack]
@@ -489,7 +498,8 @@ object DatabaseManager {
489498
private fun Transaction.selectActionsSearch(params: ActionSearchParams, page: Int): SearchResults {
490499
val actions = mutableListOf<ActionType>()
491500

492-
var query = buildQuery()
501+
var query = Tables.Actions
502+
.selectAll()
493503
.andWhere { buildQueryParams(params) }
494504

495505
val totalActions: Long = countActions(params)
@@ -512,21 +522,6 @@ object DatabaseManager {
512522
.andWhere { buildQueryParams(params) }
513523
.count()
514524

515-
private fun Transaction.buildQuery(): Query {
516-
return Tables.Actions
517-
.innerJoin(Tables.ActionIdentifiers)
518-
.innerJoin(Tables.Worlds)
519-
.leftJoin(Tables.Players)
520-
.innerJoin(
521-
Tables.oldObjectTable,
522-
{ Tables.Actions.oldObjectId },
523-
{ Tables.oldObjectTable[Tables.ObjectIdentifiers.id] }
524-
)
525-
.innerJoin(Tables.ObjectIdentifiers, { Tables.Actions.objectId }, { id })
526-
.innerJoin(Tables.Sources)
527-
.selectAll()
528-
}
529-
530525
private fun Transaction.rollbackActions(actionIds: Set<Int>) {
531526
Tables.Actions
532527
.update({ Tables.Actions.id inList actionIds }) {
@@ -542,31 +537,33 @@ object DatabaseManager {
542537
}
543538

544539
fun getKnownSources() =
545-
cache.sourceKeys.asMap().keys
540+
cache.sourceKeys.keys
546541

547542
private fun <T> getObjectId(
548543
obj: T,
549-
cache: Cache<T, Int>,
544+
cache: BiMap<T, Int>,
550545
table: EntityClass<Int, Entity<Int>>,
551546
column: Column<T>
552547
): Int? = getObjectId(obj, Function.identity(), cache, table, column)
553548

554549
private fun <T, S> getObjectId(
555550
obj: T,
556551
mapper: Function<T, S>,
557-
cache: Cache<T, Int>,
552+
cache: BiMap<T, Int>,
558553
table: EntityClass<Int, Entity<Int>>,
559554
column: Column<S>
560555
): Int? {
561-
cache.getIfPresent(obj!!)?.let { return it }
556+
if (cache.containsKey(obj)) {
557+
return cache[obj]
558+
}
562559
return table.find { column eq mapper.apply(obj) }.firstOrNull()?.id?.value?.also {
563560
cache.put(obj, it)
564561
}
565562
}
566563

567564
private fun <T> getOrCreateObjectId(
568565
obj: T,
569-
cache: Cache<T, Int>,
566+
cache: BiMap<T, Int>,
570567
entity: IntEntityClass<*>,
571568
table: IntIdTable,
572569
column: Column<T>
@@ -576,7 +573,7 @@ object DatabaseManager {
576573
private fun <T, S> getOrCreateObjectId(
577574
obj: T,
578575
mapper: Function<T, S>,
579-
cache: Cache<T, Int>,
576+
cache: BiMap<T, Int>,
580577
entity: IntEntityClass<*>,
581578
table: IntIdTable,
582579
column: Column<S>

0 commit comments

Comments
 (0)