/** * 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); } }