Created
July 1, 2020 14:07
-
-
Save michaelfmnk/db87e463f4f6dcfc9a806bb28e61c7b3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.michaelfmnk.jsp | |
import java.time.Duration | |
import java.time.LocalDateTime | |
fun main() { | |
val load = Load() | |
load.addRequest( | |
Period( | |
LocalDateTime.now().minusDays(10), | |
LocalDateTime.now().minusDays(1), | |
100 | |
) | |
) | |
println(load) | |
load.addRequest( | |
Period( | |
LocalDateTime.now().minusDays(6), | |
LocalDateTime.now().minusDays(2), | |
100 | |
) | |
) | |
load.addRequest( | |
Period( | |
LocalDateTime.now().minusYears(6), | |
LocalDateTime.now().plusDays(2), | |
1000 | |
) | |
) | |
println(load) | |
println(load.peak) | |
} | |
data class Period( | |
val from: LocalDateTime, | |
val to: LocalDateTime, | |
val bandwidth: Int | |
) | |
data class LoadPoint( | |
val date: LocalDateTime, | |
var bandwidth: Int | |
) | |
class Load { | |
private val points: MutableList<LoadPoint> = ArrayList() | |
fun addRequest(period: Period) { | |
val bandAtFromPoint = calculateBandAtPoint(period.from) | |
val bandAtToPoint = calculateBandAtPoint(period.to) | |
points += LoadPoint(period.from, bandAtFromPoint + period.bandwidth) | |
points += LoadPoint(period.to, bandAtToPoint) | |
points.asSequence() | |
.filter { it.date.isAfter(period.from) && it.date.isBefore(period.to) } | |
.forEach { | |
it.bandwidth = it.bandwidth + period.bandwidth | |
} | |
} | |
private fun calculateBandAtPoint(time: LocalDateTime): Int = points.asSequence() | |
.filter { it.date.isBefore(time) } | |
.sortedWith(Comparator { a, b -> | |
Duration.between(a.date, time).compareTo(Duration.between(b.date, time)) | |
}) | |
.map { it.bandwidth } | |
.firstOrNull() ?: 0 | |
val peak: Period? | |
get() { | |
val peakStartPoint = points.asSequence() | |
.maxBy { it.bandwidth } ?: return null | |
val peakEndDate = points.asSequence() | |
.filter { it.date > peakStartPoint.date } | |
.minBy { it.date } ?: return null | |
return Period( | |
peakStartPoint.date, | |
peakEndDate.date, | |
peakStartPoint.bandwidth | |
) | |
} | |
override fun toString(): String { | |
return points.sortedWith(Comparator { a, b -> a.date.compareTo(b.date) }).toString() | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment