in Sources/XCMetricsBackendLib/Statistics/Repositories/SQLStatisticsRepository.swift [108:143]
func getBuildTime(day: Date, using eventLoop: EventLoop) -> EventLoopFuture<DayBuildTime> {
var durations: EventLoopFuture<[Double]>;
if let sql = db as? SQLDatabase {
// Optimization to speed up queries if we're using tables sharded by day
durations = sql.select()
.column("duration")
.from("\(Build.schema)_\(day.xcm_toPartitionedTableFormat())")
.orderBy("duration")
.all()
.flatMapError { _ in return eventLoop.makeSucceededFuture([]) }
.mapEach { (try? $0.decode(column: "duration", as: Double.self)) ?? 0 }
} else {
durations = Build.query(on: db).filter(\.$day == day).sort(\.$duration).all(\.$duration)
}
return
durations.flatMap { durations in
let count = Float(durations.count)
guard durations.count > 0 else {
return eventLoop.makeSucceededFuture(
DayBuildTime(day: day, durationP50: 0, durationP95: 0, totalDuration: 0)
)
}
// Nearest-rank percentiles
let durationP50 = durations[Int((0.50 * count).rounded(.up)) - 1]
let durationP95 = durations[Int((0.95 * count).rounded(.up)) - 1]
let totalDuration = durations.reduce(0, +)
return eventLoop.makeSucceededFuture(
DayBuildTime(day: day, durationP50: durationP50, durationP95: durationP95, totalDuration: totalDuration)
)
}
}