lm-sistemi-software-distrib.../src/main/kotlin/drills/drill09/average/AverageNode.kt

108 lines
3.0 KiB
Kotlin

package drills.drill09.average
import util.network.epidemic.EpidemicNode
import util.network.epidemic.packet.EpidemicPacket
import util.network.epidemic.packet.FeedbackEpidemicPacket
import util.network.simulator.Address
import util.network.simulator.Network
class AverageNode(
address: Address,
network: Network,
initialValue: Double,
val infectStrategy: InfectStrategy = InfectStrategy.PUSH,
bufferSize: Int = 1
) : EpidemicNode<Double, FeedbackEpidemicPacket<Double>>(
address, network, initialValue, bufferSize
) {
override fun receivePushOrReply(packet: FeedbackEpidemicPacket<Double>) {
val payload = packet.payload
if (packet.isFeedback)
changeValue(payload)
else {
computeAverage(payload)
sendFeedback(packet.senderAddress)
spreadNewValue()
}
}
private fun computeAverage(payload: Double) {
val newValue = (nodeValue + payload) / 2
changeValue(newValue)
}
private fun sendFeedback(receiverAddress: Address) {
send(
FeedbackEpidemicPacket(
address,
receiverAddress,
nodeValue,
if (infectStrategy == InfectStrategy.PUSH)
EpidemicPacket.Type.PUSH else EpidemicPacket.Type.REPLY,
true
)
)
}
private fun spreadNewValue() {
when (infectStrategy) {
InfectStrategy.PUSH -> sendPushToRandom()
InfectStrategy.PULL -> sendPullToRandom()
InfectStrategy.PUSHPULL -> sendPushPullToRandom()
}
}
override fun receivePull(packet: FeedbackEpidemicPacket<Double>) {
if (packet.type == EpidemicPacket.Type.PUSHPULL)
return
send(
makeInfectionPacket(
packet.senderAddress,
EpidemicPacket.Type.REPLY
)
)
}
override fun infect() {
Thread.interrupted()
}
override fun makeInfectionPacket(
receiverAddress: Address,
type: EpidemicPacket.Type
): EpidemicPacket<Double> {
return FeedbackEpidemicPacket(
address,
receiverAddress,
nodeValue,
type,
false
)
}
companion object {
fun createPushNode(
address: Address,
network: Network,
initialValue: Double,
bufferSize: Int = 1
) = AverageNode(address, network, initialValue, InfectStrategy.PUSH, bufferSize)
fun createPullNode(
address: Address,
network: Network,
initialValue: Double,
bufferSize: Int = 1
) = AverageNode(address, network, initialValue, InfectStrategy.PULL, bufferSize)
fun createPushPullNode(
address: Address,
network: Network,
initialValue: Double,
bufferSize: Int = 1
) = AverageNode(address, network, initialValue, InfectStrategy.PUSHPULL, bufferSize)
}
}