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>( address, network, initialValue, bufferSize ) { override fun receivePushOrReply(packet: FeedbackEpidemicPacket) { 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) { 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 { 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) } }