de.invation.code.toval.time.AbstractIntervalOverlap Maven / Gradle / Ivy
package de.invation.code.toval.time;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* This class can be used to determine all different overlapping groups for a set of time intervals.
* An interval with borders a,b with a
* c lies within [a;b).
* The algorithm works in an online fashion and reports detected overlap groups to interested listeners
* (registration via {@link AbstractIntervalOverlap#registerListener(OverlapListener)} is required) as they occur.
* Please use the method {@link AbstractIntervalOverlap#reportTimeInterval(long, long)} to report new intervals.
*
* @author Thomas Stocker
*/
public abstract class AbstractIntervalOverlap {
protected List> intervalLists = new CopyOnWriteArrayList>();
protected Set> overlapListeners = new HashSet>();
public void registerListener(OverlapListener listener){
this.overlapListeners.add(listener);
}
public void reportTimeInterval(long start, long end){
reportTimeInterval(getNewInterval(start, end));
}
protected void reportTimeInterval(T interval){
boolean insertGranted = true;
for(Iterator> iterator=intervalLists.iterator(); iterator.hasNext();){
OverlapIntervalList nextList = iterator.next();
if(nextList.isCompatible(interval)){
if(!nextList.belongsToCoexistenceGroup(interval)){
removeIntervalList(nextList);
notifyListeners(nextList);
addIntervalList(nextList.refineBy(interval));
} else {
//Add the interval to the interval list
nextList.addTimeInterval(interval);
}
insertGranted = false;
} else {
//TimeInterval list has to be closed
removeIntervalList(nextList);
notifyListeners(nextList);
}
}
if(insertGranted){
addIntervalList(new OverlapIntervalList(interval));
}
}
protected abstract T getNewInterval(long start, long end);
protected void addIntervalList(OverlapIntervalList intervalList){
intervalLists.add(intervalList);
}
protected void removeIntervalList(OverlapIntervalList intervalList){
intervalLists.remove(intervalList);
}
protected void notifyListeners(OverlapIntervalList intervalList){
OverlapEvent overlapEvent = new OverlapEvent(intervalList.getIntervals());
for(OverlapListener listener: overlapListeners){
listener.overlapDetected(overlapEvent);
}
}
public void closeTimeIntervalReporting(){
for(OverlapIntervalList remainingList: intervalLists){
if(remainingList.size() > 1){
notifyListeners(remainingList);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy