X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.simulation%2Fsrc%2Forg%2Fsimantics%2Fsimulation%2Fhistory%2FHistoryUtil.java;h=27f2bf895bff382b0ae05cf251cd160425249739;hb=f212fa100ac8c0ce464a826794b3d1737b138b25;hp=8b78fe18e50f203c13170986ce9f31045c844379;hpb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;p=simantics%2Fplatform.git 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..27f2bf895 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; @@ -60,14 +55,23 @@ import org.simantics.fastlz.FastLZ; import org.simantics.history.HistoryException; import org.simantics.history.HistoryManager; import org.simantics.history.ItemManager; +import org.simantics.history.impl.CollectorImpl; +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.history.util.WeightedMedian; import org.simantics.layer0.Layer0; import org.simantics.simulation.Activator; 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 +950,83 @@ public class HistoryUtil { return 0L; } + public static CollectorState truncateHistory(double toBeforeTime, HistoryManager history, CollectorState state) throws AccessorException, BindingException, HistoryException { + Double t = toBeforeTime; + Binding timeBinding = 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, "rw"); + 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; + Bean prevSample = newSize > 0 ? (Bean) sa.get(newSize - 1, s.sampleBinding) : null; + Object prevValue = prevSample != null ? prevSample.getField(s.valueIndex) : 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 = toTime(prevTime); + is.firstValue = toValue(s.valueBinding, prevValue); + is.currentTime = is.firstTime; + is.currentValue = toValue(s.valueBinding, prevValue); + is.isNaN = isNan; + is.isValid = prevValue != null; + is.sum = Double.NaN; + is.count = 0; + is.ooDeadband = false; + is.firstDisabledTime = Double.NaN; + is.lastDisabledTime = Double.NaN; + is.median = new WeightedMedian( CollectorImpl.MEDIAN_LIMIT ); + } + } + } + } finally { + sa.close(); + } + } + + if (timeBinding != null && state != null) { + state.time.setValue(timeBinding, t); + state.dT = 1.0; + } + + return state; + } + + private static double toTime(Object time) { + return time instanceof Number ? ((Number) time).doubleValue() : Double.NaN; + } + + private static MutableVariant toValue(Binding valueBinding, Object value) { + return new MutableVariant(valueBinding, value != null ? value : valueBinding.createDefaultUnchecked()); + } + + 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); + } + }