108 lines
3.0 KiB
Kotlin
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)
|
|
}
|
|
}
|