Make EntityIndex#walk significantly faster when querying large regions
This commit is contained in:
parent
afd93fea99
commit
884a432676
@ -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,15 +328,29 @@ 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
|
||||
|
||||
for (entry in sector.entries) {
|
||||
if (seen.add(entry.id) && entry.intersects(actualRegion, withEdges)) {
|
||||
val visit = visitor(entry.value)
|
||||
if (!xIsEdge && !yIsEdge) {
|
||||
for (entry in sector.entries) {
|
||||
if (seen.add(entry.id)) {
|
||||
val visit = visitor(entry.value)
|
||||
|
||||
if (visit.isPresent)
|
||||
return visit
|
||||
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)
|
||||
|
||||
if (visit.isPresent)
|
||||
return visit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user