/**
* Copyright (C) 2012-14 graphene developers. See COPYRIGHT.TXT
* All rights reserved. Use is subject to license terms. See LICENSE.TXT
*/
package org.epics.graphene.rrdtool;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.epics.util.array.CircularBufferDouble;
import org.epics.util.array.ListDouble;
import org.epics.util.time.Timestamp;
/**
*
* @author carcassi
*/
public class TimeSeriesMulti {
private List<Timestamp> time;
private Map<String, ListDouble> values;
public TimeSeriesMulti(List<Timestamp> time, Map<String, ListDouble> values) {
this.time = time;
this.values = values;
}
public List<Timestamp> getTime() {
return time;
}
public Map<String, ListDouble> getValues() {
return values;
}
public static TimeSeriesMulti synchronizeSeries(Map<String, TimeSeries> seriesMap) {
int[] offsets = new int[seriesMap.size()];
Timestamp[] timestamps = new Timestamp[seriesMap.size()];
boolean done = false;
List<Timestamp> finalTimes = new ArrayList<>();
Map<String, ListDouble> data = new HashMap<>();
List<CircularBufferDouble> buffers = new ArrayList<>();
List<TimeSeries> series = new ArrayList<>();
for (Map.Entry<String, TimeSeries> entry : seriesMap.entrySet()) {
String name = entry.getKey();
TimeSeries timeSeries = entry.getValue();
CircularBufferDouble buffer = new CircularBufferDouble(1000000);
data.put(name, buffer);
buffers.add(buffer);
series.add(timeSeries);
}
while (!done) {
// The next time is going to be the maximum between all the
// next time, because we want all values to change
for (int i = 0; i < timestamps.length; i++) {
timestamps[i] = series.get(i).getTime().get(offsets[i]);
}
Timestamp nextTime = Collections.max(Arrays.asList(timestamps));
// Advance all the offsets to a time that is nextTime or later
for (int i = 0; i < offsets.length; i++) {
List<Timestamp> times = series.get(i).getTime();
while((offsets[i] != times.size() - 1) && (times.get(offsets[i]).compareTo(nextTime) < 0)) {
offsets[i]++;
}
}
// Add next values and increment
finalTimes.add(nextTime);
boolean hasIncremented = false;
for (int i = 0; i < offsets.length; i++) {
buffers.get(i).addDouble(series.get(i).getValues().getDouble(offsets[i]));
if (offsets[i] < series.get(i).getValues().size() - 1) {
hasIncremented = true;
offsets[i]++;
}
}
// If no increment, we are done
if (!hasIncremented) {
done = true;
}
}
return new TimeSeriesMulti(finalTimes, data);
}
}