package org.spotter.ext.detection.appHiccups.strategies;
import java.util.ArrayList;
import java.util.List;
import org.lpe.common.util.LpeNumericUtils;
import org.lpe.common.util.NumericPairList;
import org.spotter.core.chartbuilder.AnalysisChartBuilder;
import org.spotter.core.detection.DetectionResultManager;
import org.spotter.ext.detection.appHiccups.IHiccupAnalysisStrategy;
import org.spotter.ext.detection.appHiccups.utils.Hiccup;
import org.spotter.ext.detection.appHiccups.utils.HiccupDetectionConfig;
import org.spotter.shared.result.model.SpotterResult;
public class DBSCANStrategy implements IHiccupAnalysisStrategy {
private static final int numMinNeighbours = 20;
@Override
public List<Hiccup> findHiccups(NumericPairList<Long, Double> responsetimeSeries,
HiccupDetectionConfig hiccupConfig, double perfReqThreshold, double perfReqConfidence,
DetectionResultManager resultManager, SpotterResult result) {
List<Hiccup> hiccups = new ArrayList<Hiccup>();
double keyRange = responsetimeSeries.getKeyMax() - responsetimeSeries.getKeyMin();
double valueRange = responsetimeSeries.getValueMax() - responsetimeSeries.getValueMin();
double epsilon = LpeNumericUtils.meanNormalizedDistance(responsetimeSeries, keyRange, valueRange);
List<NumericPairList<Long, Double>> clusters = LpeNumericUtils.dbscanNormalized(responsetimeSeries, epsilon,
numMinNeighbours, keyRange, valueRange);
for (NumericPairList<Long, Double> c : clusters) {
int numViolations = countRequirementViolations(perfReqThreshold, c.getValueList());
if (((double) numViolations) / ((double) c.size()) > 1.0 - perfReqConfidence) {
Hiccup hiccup = new Hiccup();
hiccup.setStartTimestamp(c.getKeyMin());
hiccup.setEndTimestamp(c.getKeyMax());
hiccup.setMaxHiccupResponseTime(c.getValueMax());
hiccups.add(hiccup);
}
}
AnalysisChartBuilder chartBuilder = AnalysisChartBuilder.getChartBuilder();
chartBuilder.startChartWithoutLegend("Clusters", "Experiment Time [ms]", "Response Time [ms]");
int i = 1;
for (NumericPairList<Long, Double> c : clusters) {
chartBuilder.addFixScaledTimeSeries(c, "Cluster " + i, 1.0 / 1000.0 / 60.0);
i++;
}
chartBuilder.addHorizontalLine(perfReqThreshold, "Performance Requirement");
resultManager.storeImageChartResource(chartBuilder, "Response Time Clusters", result);
return hiccups;
}
private int countRequirementViolations(double perfReqThreshold, List<Double> responseTimes) {
int count = 0;
for (Double rt : responseTimes) {
if (rt > perfReqThreshold) {
count++;
}
}
return count;
}
}