Merge branch 'main' of https://gitea.codersquack.nl/NeoFlock/NeoComputers
This commit is contained in:
27
TODO.md
27
TODO.md
@@ -1,29 +1,12 @@
|
|||||||
# Networking
|
# Networking
|
||||||
> All that is left is optimization
|
> All that is left is optimization
|
||||||
|
|
||||||
## ERADICATE DIRECT
|
## Copy the networking optimizations of OC
|
||||||
|
> https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/network/Network.scala
|
||||||
|
|
||||||
We only need NONE, SOME and NETWORK.
|
We should implement this, as it not only makes behavior match better, but also optimizes
|
||||||
|
it a lot. We do need to replace the NEIGHBORS rule with implementing the SOME visibility.
|
||||||
## Optimize compute and memory
|
A direct port is not needed, just taking heavy inspiration from OC.
|
||||||
> OC does this too
|
|
||||||
|
|
||||||
Optimize both *time* and *memory* using graph theory.
|
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
It obviously must be fast and memory-efficient, and respect the current semantics.
|
|
||||||
|
|
||||||
The current idea is to make NETWORK style nodes the only ones with a cache,
|
|
||||||
and to instead appoint a connection that is also a NETWORK node, if any, as
|
|
||||||
the one source of truth, or steal the source. This means only one node
|
|
||||||
in a local network gets to actually compute the graph layout.
|
|
||||||
Complications can happen when merges happen, the idea is to pick one source of truth
|
|
||||||
then as well.
|
|
||||||
|
|
||||||
Also, `onNodeAdded` and `onNodeRemoved` should also be called when a reachable node is added/removed.
|
|
||||||
This is for perf. We only care about nodes being added/removed then.
|
|
||||||
This can be done by broadcasting to all of their *connections*, to circumvent the NONE/SOME/NETWORK asymmetric reachability sets.
|
|
||||||
|
|
||||||
## Optimize power balancing
|
## Optimize power balancing
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ open class DeviceNode(_address: UUID? = null) {
|
|||||||
return maximum
|
return maximum
|
||||||
}
|
}
|
||||||
|
|
||||||
val boundNetworks = HashSet<LocalNetwork>()
|
|
||||||
// meaningless except visibility is NETWORK, where there can only be one
|
|
||||||
fun getPrimaryNetwork() = boundNetworks.firstOrNull()
|
|
||||||
|
|
||||||
fun getChargerNodes(): Set<DeviceNode> = getReachable().filter { it.powerRole != PowerRole.CONSUMER }.toSet()
|
fun getChargerNodes(): Set<DeviceNode> = getReachable().filter { it.powerRole != PowerRole.CONSUMER }.toSet()
|
||||||
fun totalEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energy }
|
fun totalEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energy }
|
||||||
fun maxEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energyCapacity }
|
fun maxEnergyInConnections(): Long = getChargerNodes().fold(0) { acc, node -> acc + node.energyCapacity }
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
package org.neoflock.neocomputers.network
|
|
||||||
|
|
||||||
class LocalNetwork(val sourceOfTruth: DeviceNode) {
|
|
||||||
val devices = HashSet<DeviceNode>()
|
|
||||||
|
|
||||||
fun getReachableByTruth() = sourceOfTruth.computeReachable()
|
|
||||||
|
|
||||||
fun performMerge(other: LocalNetwork) {
|
|
||||||
for(dev in other.devices) {
|
|
||||||
if(other in dev.boundNetworks) {
|
|
||||||
dev.boundNetworks.remove(other)
|
|
||||||
dev.boundNetworks.add(this)
|
|
||||||
}
|
|
||||||
devices.add(dev)
|
|
||||||
}
|
|
||||||
other.devices.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addToNetwork(dev: DeviceNode) {
|
|
||||||
if(dev in devices) return
|
|
||||||
if(dev.reachability == Networking.Visibility.NETWORK) {
|
|
||||||
val primNet = dev.getPrimaryNetwork()
|
|
||||||
if(primNet != null) {
|
|
||||||
// Merge the networks!
|
|
||||||
// merge smallest into largest for perf
|
|
||||||
if(primNet.devices.size > devices.size) {
|
|
||||||
primNet.performMerge(this)
|
|
||||||
} else {
|
|
||||||
performMerge(primNet)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
devices.add(dev)
|
|
||||||
dev.boundNetworks.add(this)
|
|
||||||
|
|
||||||
when(dev.reachability) {
|
|
||||||
Networking.Visibility.NONE -> return
|
|
||||||
Networking.Visibility.SOME -> {
|
|
||||||
dev.getPreferredFew().forEach { addToNetwork(it) }
|
|
||||||
}
|
|
||||||
Networking.Visibility.NETWORK -> {
|
|
||||||
dev.connections.forEach { addToNetwork(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkIfStillConnected(dev: DeviceNode) {
|
|
||||||
if(dev !in devices) return
|
|
||||||
if(dev in getReachableByTruth()) return
|
|
||||||
removeFromNetwork(dev)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeFromNetwork(dev: DeviceNode) {
|
|
||||||
// TODO: this is wrong, rewrite it. We need it to make a sub-network.
|
|
||||||
if(dev == sourceOfTruth) {
|
|
||||||
throw UnsupportedOperationException("removing the source of truth is not supported")
|
|
||||||
}
|
|
||||||
if(dev !in devices) return
|
|
||||||
devices.remove(dev)
|
|
||||||
dev.boundNetworks.remove(this)
|
|
||||||
|
|
||||||
when(dev.reachability) {
|
|
||||||
Networking.Visibility.NONE -> {}
|
|
||||||
Networking.Visibility.SOME -> dev.getPreferredFew().forEach { removeFromNetwork(it) }
|
|
||||||
Networking.Visibility.NETWORK -> dev.connections.forEach { removeFromNetwork(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user