package com.linkedin.thirdeye.util;
import com.linkedin.thirdeye.api.DimensionMap;
import com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.joda.time.Interval;
public class IntervalUtils {
/**
* This method is designed to merge a list of intervals to a list of intervals with no overlap in between
* @param intervals
* @return
* a list of intervals with no overlap in between
*/
public static List<Interval> mergeIntervals (List<Interval> intervals) {
if(intervals == null || intervals.size() == 0) {
return intervals;
}
// Sort Intervals
Collections.sort(intervals, new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
return o1.getStart().compareTo(o2.getStart());
}
});
// Merge intervals
Stack<Interval> intervalStack = new Stack<>();
intervalStack.push(intervals.get(0));
for(int i = 1; i < intervals.size(); i++) {
Interval top = intervalStack.peek();
Interval target = intervals.get(i);
if(top.overlap(target) == null && (top.getEnd() != target.getStart())) {
intervalStack.push(target);
}
else if(top.equals(target)) {
continue;
}
else {
Interval newTop = new Interval(Math.min(top.getStart().getMillis(), target.getStart().getMillis()),
Math.max(top.getEnd().getMillis(), target.getEnd().getMillis()));
intervalStack.pop();
intervalStack.push(newTop);
}
}
return intervalStack;
}
/**
* Merge intervals for each dimension map
* @param anomalyIntervals
*/
public static void mergeIntervals(Map<DimensionMap, List<Interval>> anomalyIntervals) {
for(DimensionMap dimension : anomalyIntervals.keySet()) {
anomalyIntervals.put(dimension ,mergeIntervals(anomalyIntervals.get(dimension)));
}
}
}