From b93b08597911347520cbd9e900be026645f7b743 Mon Sep 17 00:00:00 2001 From: Tuukka Lehtonen Date: Wed, 15 Nov 2017 15:21:38 +0200 Subject: [PATCH] Added utility for truncating collected history data The utility also supports an approximate truncation of the dynamic CollectorState structure related to an active Collector instance. refs #7622 Change-Id: I0041f26ca53250f3bed22f32de6c789f80a607c5 --- .../org/simantics/history/util/Stream.java | 11 ++- .../simulation/history/HistoryUtil.java | 89 +++++++++++++++++-- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/bundles/org.simantics.history/src/org/simantics/history/util/Stream.java b/bundles/org.simantics.history/src/org/simantics/history/util/Stream.java index dce3a6fc6..3366a1c26 100644 --- a/bundles/org.simantics.history/src/org/simantics/history/util/Stream.java +++ b/bundles/org.simantics.history/src/org/simantics/history/util/Stream.java @@ -300,7 +300,16 @@ public class Stream { throw new HistoryException(e); } } - + + public Object getItemTime(Binding timeBinding, int index) throws HistoryException + { + try { + return _getTime( accessor.get(index, sampleBinding), timeBinding ); + } catch (AccessorException e) { + throw new HistoryException( e ); + } + } + public Object getLowerTime(Binding timeBinding, Object time) throws HistoryException { try { diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java index 8b78fe18e..53a76d136 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java @@ -12,9 +12,6 @@ *******************************************************************************/ package org.simantics.simulation.history; -import gnu.trove.map.TObjectLongMap; -import gnu.trove.map.hash.TObjectLongHashMap; - import java.io.EOFException; import java.io.IOException; import java.io.InputStream; @@ -23,9 +20,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import net.jpountz.lz4.LZ4BlockInputStream; -import net.jpountz.lz4.LZ4BlockOutputStream; - import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; @@ -41,6 +35,7 @@ import org.simantics.databoard.binding.RecordBinding; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.impl.ObjectArrayBinding; +import org.simantics.databoard.binding.mutable.MutableVariant; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.container.DataContainer; import org.simantics.databoard.container.DataContainers; @@ -57,9 +52,12 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ServiceNotFoundException; import org.simantics.db.request.Read; import org.simantics.fastlz.FastLZ; +import org.simantics.history.Collector; import org.simantics.history.HistoryException; import org.simantics.history.HistoryManager; import org.simantics.history.ItemManager; +import org.simantics.history.impl.CollectorState; +import org.simantics.history.impl.CollectorState.VariableState; import org.simantics.history.util.Stream; import org.simantics.history.util.ValueBand; import org.simantics.layer0.Layer0; @@ -68,6 +66,11 @@ import org.simantics.simulation.ontology.HistoryResource; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.utils.FileUtils; +import gnu.trove.map.TObjectLongMap; +import gnu.trove.map.hash.TObjectLongHashMap; +import net.jpountz.lz4.LZ4BlockInputStream; +import net.jpountz.lz4.LZ4BlockOutputStream; + /** * @author Toni Kalajainen * @author Tuukka Lehtonen @@ -946,4 +949,78 @@ public class HistoryUtil { return 0L; } + 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); + } + } -- 2.43.2