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

98 lines
2.8 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 {
val newValue = (nodeValue + payload) / 2
changeValue(newValue)
send(
FeedbackEpidemicPacket(
address,
packet.senderAddress,
newValue,
if (infectStrategy == InfectStrategy.PUSH)
EpidemicPacket.Type.PUSH else EpidemicPacket.Type.REPLY,
true
)
)
when (infectStrategy) {
InfectStrategy.PUSH -> sendPush()
InfectStrategy.PULL -> sendPull()
InfectStrategy.PUSHPULL -> sendPushPull()
}
}
}
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)
}
}