package cz.cuni.mff.d3s.spl.core.data.segment;

import java.util.SortedMap;
import java.util.TreeMap;

import cz.cuni.mff.d3s.spl.core.data.PrecomputedStatistics;
import cz.cuni.mff.d3s.spl.core.data.SampleBasedDataSource;
import cz.cuni.mff.d3s.spl.core.data.Statistics;

public class SlidingTimeSlotDataSource implements SampleBasedDataSource {
	private static class TickRecords {
		public long sampleCount = 0;
		public double sampleSum = 0.0;
		
		public TickRecords() {
			
		}
		
		public void newSample(long sample) {
			sampleCount++;
			sampleSum += (double) sample;
		}
	}
	
	private SortedMap<Long, TickRecords> samples = new TreeMap<>();
	private long clockStart = Long.MIN_VALUE;
	private long clockEnd = Long.MAX_VALUE;
	
	public SlidingTimeSlotDataSource(long start, long end) {
		if (start > end) {
			throw new IllegalArgumentException("It is forbidden to have `from > end'.");
		}
		clockStart = start;
		clockEnd = end;
	}
	
	public void shift(long offset) {
		clockStart += offset;
		clockEnd += offset;
		samples = samples.subMap(clockStart, clockEnd);
	}

	@Override
	public Statistics get() {
		double totalSum = 0;
		long sampleCount = 0;
		for (TickRecords rec : samples.values()) {
				totalSum += rec.sampleSum;
				sampleCount += rec.sampleCount;
		}
		if (sampleCount == 0) {
			return PrecomputedStatistics.empty;
		} else {
			return PrecomputedStatistics.create(totalSum / (double) sampleCount, sampleCount);
		}
	}

	@Override
	public void newSample(long sample, long clock) {
		if ((clock < clockStart) || (clock >= clockEnd)) {
			return;
		}
	
		getTickRecord(clock).newSample(sample);
	}

	@Override
	public void addSubSource(SampleBasedDataSource subSource) {
		throw new UnsupportedOperationException("Not implemented.");
	}
	
	private TickRecords getTickRecord(long clock) {
		TickRecords rec = samples.get(clock);
		if (rec == null) {
			rec = new TickRecords();
			samples.put(clock, rec);
		}
		return rec;
	}
}

@@ -1019,16 +1019,52 @@
 fset;%0A%09%09
+/*%0A%09%09 * We cannot use directly%0A%09%09 * 
 samples 
@@ -1103,16 +1103,365 @@
 ckEnd);%0A
+%09%09 * because subMap checks that all added values are within%0A%09%09 * the range and also subMap of a subMap must respect that.%0A%09%09 * %0A%09%09 * Thus, we need to create a whole new Map and copy all the%0A%09%09 * elements there.%0A%09%09 */%0A%09%09SortedMap%3CLong, TickRecords%3E newMap = new TreeMap%3C%3E();%0A%09%09newMap.putAll(samples.subMap(clockStart, clockEnd));%0A%09%09samples = newMap;%0A
 %09%7D%0A%0A%09@Ov

Fix sliding time slot data source