Make EntityIndex#walk significantly faster when querying large regions

This commit is contained in:
DBotThePony 2024-05-01 11:59:04 +07:00
parent afd93fea99
commit 884a432676
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,6 +1,7 @@
package ru.dbotthepony.kstarbound.world
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
import it.unimi.dsi.fastutil.longs.LongArrayList
@ -317,7 +318,7 @@ class EntityIndex(val geometry: WorldGeometry) {
}
fun <V> walk(rect: AABB, visitor: (AbstractEntity) -> KOptional<V>, withEdges: Boolean = true): KOptional<V> {
val seen = IntAVLTreeSet()
val seen = IntOpenHashSet(256)
for (actualRegion in geometry.split(rect).first) {
val xMin = geometry.x.chunkFromCell(actualRegion.mins.x)
@ -327,9 +328,22 @@ class EntityIndex(val geometry: WorldGeometry) {
val yMax = geometry.y.chunkFromCell(actualRegion.maxs.y)
for (x in xMin .. xMax) {
val xIsEdge = x == xMin || x == xMax
for (y in yMin .. yMax) {
val sector = map[index(x, y)] ?: continue
val yIsEdge = y == yMin || y == yMax
if (!xIsEdge && !yIsEdge) {
for (entry in sector.entries) {
if (seen.add(entry.id)) {
val visit = visitor(entry.value)
if (visit.isPresent)
return visit
}
}
} else {
for (entry in sector.entries) {
if (seen.add(entry.id) && entry.intersects(actualRegion, withEdges)) {
val visit = visitor(entry.value)
@ -341,6 +355,7 @@ class EntityIndex(val geometry: WorldGeometry) {
}
}
}
}
return KOptional()
}