+ public static void truncateHistory(double toBeforeTime, HistoryManager history, Collector collector) throws AccessorException, BindingException, HistoryException {
+ Double t = toBeforeTime;
+ Binding timeBinding = null;
+ CollectorState state = collector != null ? (CollectorState) collector.getState() : null;
+
+ Bean[] items = history.getItems();
+ //System.out.println("truncating all samples after t=" + toBeforeTime + " for " + items.length + " history items");
+
+ for (Bean item : items) {
+ String id = (String) item.getField("id");
+ StreamAccessor sa = history.openStream(id, "w");
+ try {
+ Stream s = new Stream(sa);
+ timeBinding = s.timeBinding;
+ int currentSize = sa.size();
+ int index = s.binarySearch(timeBinding, toBeforeTime);
+ int newSize = truncationSize(index);
+ if (newSize < currentSize) {
+ //System.out.println("truncating item: " + item + " from size " + currentSize + " to " + newSize);
+ sa.setSize(newSize);
+
+ if (state != null) {
+ Object prevTime = newSize > 0 ? s.getItemTime(s.timeBinding, newSize - 1) : null;
+ Object prevValue = newSize > 0 ? sa.get(newSize - 1, s.valueBinding) : null;
+ boolean isNan = isNaN(prevValue);
+
+ VariableState vs = state.values.get(id);
+ if (vs != null && vs.value != null && prevValue != null) {
+ vs.value.setValue(vs.value.getBinding(), prevValue);
+ vs.isValid = true;
+ vs.isNan = isNan;
+ }
+
+ CollectorState.Item is = state.itemStates.get(id);
+ if (is != null) {
+ is.firstTime = Double.NaN;
+ is.firstValue = null;
+ is.currentTime = toTime(prevTime);
+ is.currentValue = prevValue != null ? new MutableVariant(s.valueBinding, prevValue) : null;
+ is.isNaN = isNaN(is.currentValue);
+ is.isValid = is.currentValue != null;
+ is.sum = Double.NaN;
+ is.count = 0;
+ is.ooDeadband = false;
+ is.firstDisabledTime = Double.NaN;
+ is.lastDisabledTime = Double.NaN;
+ is.median = null;
+ }
+ }
+ }
+ } finally {
+ sa.close();
+ }
+ }
+
+ if (timeBinding != null && state != null) {
+ state.time.setValue(timeBinding, t);
+ state.dT = 1.0;
+ collector.setState(state);
+ }
+ }
+
+ private static double toTime(Object time) {
+ return time instanceof Number ? ((Number) time).doubleValue() : Double.NaN;
+ }
+
+ private static boolean isNaN(Object value) {
+ return value instanceof Number ? Double.isNaN(((Number) value).doubleValue()) : false;
+ }
+
+ private static int truncationSize(int binarySearchResult) {
+ return binarySearchResult >= 0 ? binarySearchResult + 1 : (-binarySearchResult - 1);
+ }
+