Make energy cable graph track node + side in lively nodes list, considerably improving performance
This commit is contained in:
parent
d5e05a2439
commit
b8e76a0fd4
@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.block.entity.cable
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet
|
||||
import net.minecraft.core.Direction
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.SERVER_IS_LIVE
|
||||
import ru.dbotthepony.mc.otm.UNIVERSE_TICKS
|
||||
@ -74,16 +75,20 @@ private class LinkedPriorityQueue<T : Comparable<T>> {
|
||||
}
|
||||
|
||||
class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableGraph>() {
|
||||
private val livelyNodes = HashSet<EnergyCableBlockEntity.Node>()
|
||||
private val livelyNodesList = ArrayList<EnergyCableBlockEntity.Node>()
|
||||
private val livelyNodes = HashSet<Pair<EnergyCableBlockEntity.Node, RelativeSide>>()
|
||||
private val livelyNodesList = ArrayList<Pair<EnergyCableBlockEntity.Node, RelativeSide>>()
|
||||
|
||||
fun addLivelyNode(node: EnergyCableBlockEntity.Node) {
|
||||
when (contains(node)) {
|
||||
ContainsStatus.ABOUT_TO_BE_REMOVED, ContainsStatus.ABOUT_TO_BE_ADDED -> { } // do nothing
|
||||
ContainsStatus.DOES_NOT_BELONG -> throw IllegalArgumentException("$node does not belong to $this")
|
||||
ContainsStatus.CONTAINS -> {
|
||||
if (livelyNodes.add(node)) {
|
||||
livelyNodesList.add(node)
|
||||
for (dir in RelativeSide.entries) {
|
||||
val pair = node to dir
|
||||
|
||||
if (livelyNodes.add(pair)) {
|
||||
livelyNodesList.add(pair)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -584,8 +589,12 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
||||
}
|
||||
|
||||
override fun onNodeRemoved(node: EnergyCableBlockEntity.Node) {
|
||||
if (livelyNodes.remove(node)) {
|
||||
check(livelyNodesList.remove(node))
|
||||
for (dir in RelativeSide.entries) {
|
||||
val pair = node to dir
|
||||
|
||||
if (livelyNodes.remove(pair)) {
|
||||
check(livelyNodesList.remove(pair))
|
||||
}
|
||||
}
|
||||
|
||||
val touchedSegments = HashSet<Segment>()
|
||||
@ -608,8 +617,11 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
||||
}
|
||||
|
||||
override fun onNodeAdded(node: EnergyCableBlockEntity.Node) {
|
||||
check(livelyNodes.add(node))
|
||||
livelyNodesList.add(node)
|
||||
for (dir in RelativeSide.entries) {
|
||||
val pair = node to dir
|
||||
check(livelyNodes.add(pair))
|
||||
livelyNodesList.add(pair)
|
||||
}
|
||||
|
||||
notifyThroughputsChanged()
|
||||
}
|
||||
@ -622,22 +634,27 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
||||
var residue = howMuch.coerceAtMost(fromNode.energyThroughput)
|
||||
val snapshot = Reference2ObjectOpenHashMap<Segment, Decimal>()
|
||||
|
||||
for (node in itr) {
|
||||
var hit = false
|
||||
for (pair in itr) {
|
||||
val (node, relSide) = pair
|
||||
val side = node.sides[relSide]!!
|
||||
|
||||
for (side in node.sides.values) {
|
||||
if (!side.isEnabled)
|
||||
if (!side.isEnabled) {
|
||||
itr.remove()
|
||||
check(livelyNodes.remove(pair)) { "Lively nodes Set does not contain $pair" }
|
||||
continue
|
||||
else if (fromNode === node && side.side === fromSide) {
|
||||
hit = true
|
||||
} else if (fromNode === node && side.side === fromSide) {
|
||||
continue
|
||||
}
|
||||
|
||||
val it = side.neighbour.get() ?: continue
|
||||
if (it is EnergyCableBlockEntity.CableSide) continue
|
||||
val it = side.neighbour.get()
|
||||
|
||||
if (it == null || it is EnergyCableBlockEntity.CableSide) {
|
||||
itr.remove()
|
||||
check(livelyNodes.remove(pair)) { "Lively nodes Set does not contain $pair" }
|
||||
continue
|
||||
}
|
||||
|
||||
val paths = getPath(fromNode, node, it.receiveEnergy(residue, true), !simulate)
|
||||
hit = true
|
||||
|
||||
if (paths.size == 1) {
|
||||
// Single path, fast scenario
|
||||
@ -711,12 +728,6 @@ class EnergyCableGraph : GraphNodeList<EnergyCableBlockEntity.Node, EnergyCableG
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit) {
|
||||
itr.remove()
|
||||
check(livelyNodes.remove(node)) { "Lively nodes Set does not contain $node" }
|
||||
}
|
||||
}
|
||||
|
||||
return received
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user