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
|
package ru.dbotthepony.kstarbound.world
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.IntAVLTreeSet
|
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.Long2ObjectFunction
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||||
import it.unimi.dsi.fastutil.longs.LongArrayList
|
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> {
|
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) {
|
for (actualRegion in geometry.split(rect).first) {
|
||||||
val xMin = geometry.x.chunkFromCell(actualRegion.mins.x)
|
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)
|
val yMax = geometry.y.chunkFromCell(actualRegion.maxs.y)
|
||||||
|
|
||||||
for (x in xMin .. xMax) {
|
for (x in xMin .. xMax) {
|
||||||
|
val xIsEdge = x == xMin || x == xMax
|
||||||
|
|
||||||
for (y in yMin .. yMax) {
|
for (y in yMin .. yMax) {
|
||||||
val sector = map[index(x, y)] ?: continue
|
val sector = map[index(x, y)] ?: continue
|
||||||
|
val yIsEdge = y == yMin || y == yMax
|
||||||
|
|
||||||
for (entry in sector.entries) {
|
if (!xIsEdge && !yIsEdge) {
|
||||||
if (seen.add(entry.id) && entry.intersects(actualRegion, withEdges)) {
|
for (entry in sector.entries) {
|
||||||
val visit = visitor(entry.value)
|
if (seen.add(entry.id)) {
|
||||||
|
val visit = visitor(entry.value)
|
||||||
|
|
||||||
if (visit.isPresent)
|
if (visit.isPresent)
|
||||||
return visit
|
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