/**
* Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
* All rights reserved. Use is subject to license terms. See LICENSE.TXT
*/
package org.diirt.datasource.timecache.util;
import java.time.Duration;
import java.time.Instant;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import org.diirt.util.time.TimeInterval;
/**
* Transforms a set of {@link Timestamp} to an {@link IntervalsList}.
* @author Fred Arnaud (Sopra Group) - ITER
*/
public class TimestampsSet {
private Set<Instant> timestamps;
private Duration tolerance = Duration.ofSeconds(1);
/** Build an empty {@link TimestampsSet}. */
public TimestampsSet() {
timestamps = new TreeSet<Instant>();
}
/** Check if the instance is empty. */
public boolean isEmpty() {
return timestamps.isEmpty();
}
/** Get the number of {@link Instant} in the set. */
public int getSize() {
return timestamps.size();
}
/**
* Add a {@link Instant} to the set.
* @param t {@link Instant} to be added.
*/
public void add(Instant t) {
if (t != null)
timestamps.add(t);
}
/**
* Set the {@link Duration} used to define the minimum duration of
* generated {@link TimeInterval}.
* @param tolerance {@link Duration} minimal duration
*/
public void setTolerance(Duration tolerance) {
this.tolerance = tolerance;
}
/**
* Returns an {@link IntervalsList} built from a set of {@link Instant}
* using the following algorithm: if the {@link Duration} between two
* {@link Instant} is inferior to the defined tolerance, they are grouped
* in the same {@link TimeInterval}. A {@link TimeInterval} duration can not
* be inferior to the defined tolerance. TODO: better algorithm ?
*/
public IntervalsList toIntervalsList() {
IntervalsList ilist = new IntervalsList();
if (isEmpty()) // empty list
return ilist;
Iterator<Instant> iterator = timestamps.iterator();
Instant first = iterator.next();
Instant previous = first;
while (iterator.hasNext()) {
Instant next = iterator.next();
if (previous.plus(tolerance).compareTo(next) < 0) {
if (first.equals(previous)) {
ilist.addToSelf(intervalOfSinglePoint(first));
} else {
ilist.addToSelf(TimeInterval.between(first, previous));
}
first = next;
}
previous = next;
}
// Process end of set
if (first.equals(previous)) {
ilist.addToSelf(intervalOfSinglePoint(first));
} else {
ilist.addToSelf(TimeInterval.between(first, previous));
}
return ilist;
}
// Generate a TimeInterval from a single timestamp
private TimeInterval intervalOfSinglePoint(Instant first) {
return TimeInterval.between(first, first.plus(tolerance));
}
}