Skip to content

Instantly share code, notes, and snippets.

@dkandalov
Created February 12, 2013 11:13
Show Gist options
  • Save dkandalov/4761632 to your computer and use it in GitHub Desktop.
Save dkandalov/4761632 to your computer and use it in GitHub Desktop.
AnalysisUtil
class AnalysisUtil {
static def aggregateByDuration = { events -> events.sum(0) { it.duration } }
static def aggregateByQueryDuration = { events -> events.sum(0) { it.queryDuration } }
static def aggregateByAmount = { events -> events.size() }
static def histogramOf(Closure criteria, amountOfIntervals, List lines) {
double maxValue = criteria(lines.max(criteria))
double minValue = criteria(lines.min(criteria))
double intervalSize = (maxValue - minValue) / amountOfIntervals
def closestIntervalTo = { value ->
double intervalsFromMin = (value - minValue) / intervalSize
double intervalsToMax = (maxValue - value) / intervalSize
def closerToLowerInterval = (intervalsFromMin - Math.floor(intervalsFromMin) < intervalsToMax - Math.floor(intervalsToMax))
closerToLowerInterval ? Math.floor(intervalsFromMin) * intervalSize : Math.floor(intervalsToMax) * intervalSize
}
def groupedByInterval = lines.groupBy{ closestIntervalTo(criteria(it)) }
minValue.step(maxValue, intervalSize){ value ->
def threshold = intervalSize / 3
def containsIntervalValue = (groupedByInterval.keySet().find { (it - value).abs() < threshold } != null)
if (!containsIntervalValue) groupedByInterval[value] = []
}
groupedByInterval.sort{it.key}.collect{ "" + it.key + "," + aggregateByAmount(it.value) }.join("\n")
}
static groupedByMinuteAnd(Closure criteria, Collection lines, Closure aggregate = aggregateByAmount) {
def criteriaValuesByAggregate = lines.groupBy(criteria).collect{[criteriaValue: it.key, aggregateValue: aggregate(it.value)]}
def criteriaValues = criteriaValuesByAggregate.sort{-it.aggregateValue}.collect{ it.criteriaValue }.take(30).sort().toList()
Map byMinute = lines.groupBy([{it.timeByMinute}, criteria])
addMissingTimeKeys(byMinute, 1000 * 60L, [:])
"time,${criteriaValues.join(",")}\n" +
byMinute.sort{ it.key }.collect{ "" + formatAsTime(it.key) + "," + subGroupToString(criteriaValues, (Map) it.value, aggregate) }.join("\n")
}
static groupedByHourAnd(Closure criteria, Collection lines, Closure aggregate = aggregateByAmount) {
def criteriaValuesByAggregate = lines.groupBy(criteria).collect{[criteriaValue: it.key, aggregateValue: aggregate(it.value)]}
def criteriaValues = criteriaValuesByAggregate.sort{-it.aggregateValue}.collect{ it.criteriaValue }.take(30).sort().toList()
Map byHour = lines.groupBy([{it.timeByHour}, criteria])
addMissingTimeKeys(byHour, 1000 * 60 * 60L, [:])
"time,${criteriaValues.join(",")}\n" +
byHour.sort{ it.key }.collect{ "" + formatAsTime(it.key) + "," + subGroupToString(criteriaValues, (Map) it.value, aggregate) }.join("\n")
}
static groupedByMinute(lines, Closure aggregate = aggregateByAmount) {
Map byMinute = addMissingTimeKeys(lines.groupBy{ it.timeByMinute }, 1000 * 60L, [])
byMinute.sort{ it.key }.collect{ "" + formatAsTime(it.key) + "," + aggregate(it.value) }.join("\n")
}
static groupedByHour(lines, Closure aggregate = aggregateByAmount) {
Map byHour = addMissingTimeKeys(lines.groupBy{ it.timeByHour }, 1000 * 60 * 60L, [])
byHour.sort { it.key }.collect { "" + formatAsTime(it.key) + "," + aggregate(it.value) }.join("\n")
}
private static addMissingTimeKeys(Map<Date, Object> map, stepSize, defaultValue) {
def fromTime = (map.keySet().min{ it.time }).time
def toTime = (map.keySet().max{ it.time }).time
while (fromTime < toTime) {
def date = new Date(fromTime)
if (!map.containsKey(date)) map[date] = defaultValue
fromTime += stepSize
}
map
}
private static final SimpleDateFormat outputDateFormat = new SimpleDateFormat("kk:mm:ss")
private static formatAsTime(date) {
outputDateFormat.format(date)
}
private static subGroupToString(values, Map eventsByValue, Closure aggregate) {
values.collect{ eventsByValue.containsKey(it) ? aggregate(eventsByValue.get(it)).toString() : "0" }.join(",")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment