]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.history/src/org/simantics/history/util/StreamIterator.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / StreamIterator.java
diff --git a/bundles/org.simantics.history/src/org/simantics/history/util/StreamIterator.java b/bundles/org.simantics.history/src/org/simantics/history/util/StreamIterator.java
new file mode 100644 (file)
index 0000000..c30862a
--- /dev/null
@@ -0,0 +1,291 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 Association for Decentralized Information Management in\r
+ * Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.history.util;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.ArrayAccessor;\r
+import org.simantics.databoard.accessor.error.AccessorException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.RecordBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.history.HistoryException;\r
+\r
+/**\r
+ * Stream iterator iterates sample entries in an array.\r
+ * \r
+ * Is scans the next sample and knows its time stamp.\r
+ * \r
+ * @author toni.kalajainen\r
+ */\r
+public class StreamIterator {\r
+\r
+       // Sample binding\r
+       RecordBinding sampleBinding;\r
+       \r
+       // Array accessor\r
+       ArrayAccessor aa;\r
+       // Array stream\r
+       Stream stream;\r
+       // From and end times of the whole stream\r
+       double from, end;\r
+       \r
+       // Current and next sample\r
+       Object current, next;\r
+\r
+       // Utility for reading sample\r
+       ValueBand valueBand, nextValueBand;\r
+       // Start and end time of current sample\r
+       double startTime, endTime;\r
+       \r
+       int index = -1;\r
+       int size;\r
+       \r
+       public StreamIterator(ArrayAccessor aa) throws HistoryException {\r
+               try {\r
+                       this.aa = aa;\r
+                       sampleBinding = (RecordBinding) Bindings.getBeanBinding( aa.type().componentType );\r
+                       current = sampleBinding.createDefault();\r
+                       next = sampleBinding.createDefault();\r
+                       valueBand = new ValueBand(sampleBinding, current);\r
+                       nextValueBand = new ValueBand(sampleBinding, next);\r
+                       stream = new Stream( aa, sampleBinding );\r
+                       size = aa.size();\r
+                       if ( size>0 ) {\r
+                       aa.get(0, sampleBinding, current);\r
+                               from = valueBand.getTimeDouble();\r
+                       aa.get(size-1, sampleBinding, current);\r
+                               end = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();\r
+                       }\r
+               } catch (BindingException e) {\r
+                       throw new HistoryException( e );\r
+               } catch (AccessorException e) {\r
+                       throw new HistoryException( e );\r
+               } \r
+       }\r
+       \r
+       /**\r
+        * Go to time using random access\r
+        * @param time\r
+        * @return true if sample was found\r
+        * @throws HistoryException \r
+        */\r
+       public boolean gotoTime(double time) throws HistoryException {\r
+               // Outside range\r
+               if ( time<from || time>end ) {\r
+                       index = -1;\r
+                       return false;\r
+               }\r
+               \r
+               // Already at cursor\r
+               if ( time>=startTime && time<endTime ) return hasValue();\r
+               int i = stream.binarySearch(Bindings.DOUBLE, time);\r
+               if (i>=0) {\r
+                       gotoIndex( i );\r
+               } else {\r
+                       int insertPos = -i-2;\r
+                       if ( insertPos<0 || insertPos>=size ) {\r
+                               index = -1;\r
+                       } else {\r
+                               gotoIndex( insertPos );\r
+                               if ( endTime<time ) index = -1;\r
+                       }\r
+               }\r
+               \r
+               return hasValue();              \r
+       }\r
+       \r
+       /**\r
+        * Proceed to time using sequential seek.\r
+        * \r
+        * @param time\r
+        * @return true if sample was found\r
+        * @throws HistoryException \r
+        */\r
+       public boolean proceedToTime(double time) throws HistoryException {\r
+               // Outside range\r
+               if ( time<from || time>end ) {\r
+                       index = -1;\r
+                       return false;\r
+               }\r
+\r
+               // No position, or going to past\r
+               if (index<0 || startTime>time) {\r
+                       gotoTime(time);\r
+                       return hasValue();\r
+               }\r
+               \r
+               // Proceed until end hit\r
+               while (time>=endTime && hasNext()) gotoIndex(index+1);\r
+               return hasValue();\r
+       }\r
+       \r
+       /**\r
+        * Go to index. If element does not exist, index is set to -1;\r
+        * @param pos\r
+        * @throws HistoryException\r
+        */\r
+       public void gotoIndex(int pos) throws HistoryException {\r
+               if (pos == index) return;\r
+               \r
+               if (pos<0 || pos>=size) {\r
+                       index = -1;\r
+                       return;\r
+               }\r
+\r
+               try {\r
+                       // Read current value\r
+                       if (pos == index+1 && index>=0) {\r
+                               sampleBinding.readFrom(sampleBinding, next, current);\r
+                       } else {\r
+                               aa.get(pos, sampleBinding, current);\r
+                       }\r
+                       startTime = valueBand.getTimeDouble();\r
+                       \r
+                       // Read next value\r
+                       if (pos+1<size) {\r
+                               aa.get(pos+1, sampleBinding, next);\r
+                               //endTime = valueBand.isValidValue() ? nextValueBand.getTimeDouble() : ( nextValueBand.isValidValue() ? nextValueBand.getTimeDouble() : nextValueBand.getTimeDouble() );\r
+                               endTime = nextValueBand.getTimeDouble();\r
+                       } else {                                \r
+                               endTime = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();\r
+                       }\r
+                       \r
+                       // \r
+                       index = pos;\r
+               } catch (AccessorException e) {\r
+                       throw new HistoryException( e );\r
+               } catch (BindingException e) {\r
+                       throw new HistoryException( e );\r
+               }\r
+       }\r
+\r
+       \r
+       public boolean hasNext() {\r
+               return index<size-1;\r
+       }\r
+\r
+       public void next() throws HistoryException {\r
+               //if (index>=0) \r
+               gotoIndex( index+1 );\r
+       }\r
+       \r
+       public ValueBand getValueBand() {\r
+               return valueBand;\r
+       }\r
+       \r
+       public Object getValue(Binding binding) throws HistoryException {\r
+               return valueBand.getValue(binding);\r
+       }\r
+       \r
+       public Object getSample() {\r
+               return current;\r
+       }\r
+       \r
+       public RecordBinding getSampleBinding() {\r
+               return sampleBinding;\r
+       }\r
+       \r
+       public boolean hasValue() {\r
+               return index!=-1;\r
+       }\r
+       \r
+       public boolean hasValidValue() throws HistoryException {\r
+               return index!=-1 && !valueBand.isNanSample() && !valueBand.isNullValue();\r
+       }\r
+       /**\r
+        * Get the start time. The value is valid if index != -1\r
+        * @return start time\r
+        */\r
+       public double getStartTime() {\r
+               return startTime;\r
+       }\r
+       \r
+       /**\r
+        * Get end time, the value is valid if index != -1\r
+        * @return end time\r
+        */\r
+       public double getEndTime() {\r
+               return endTime;\r
+       }\r
+       \r
+       public Double getNextTime() throws HistoryException {\r
+               if ( size==0 ) return null;\r
+               if ( index==-1 ) return from;\r
+               return (Double) nextValueBand.getTime(Bindings.DOUBLE);\r
+       }\r
+       \r
+       public Double getNextTime( double currentTime ) throws HistoryException {\r
+               if ( size==0 ) return null;\r
+               if ( index==-1 ) return from;\r
+               \r
+               if ( valueBand.hasEndTime() ) {\r
+                       Double endTime = (Double) valueBand.getEndTime(Bindings.DOUBLE);\r
+                       if ( endTime>currentTime ) return endTime;\r
+               }\r
+               \r
+               double nextTime = (Double) nextValueBand.getTime(Bindings.DOUBLE);\r
+               return nextTime;\r
+       }\r
+       \r
+       \r
+       \r
+       /**\r
+        * get index of the cursor\r
+        * @return index or -1\r
+        */\r
+       public int getIndex() {\r
+               return index;\r
+       }\r
+       \r
+       @Override\r
+       public String toString() {\r
+               Binding valueBinding = valueBand.getValueBinding();\r
+               String valueStr;\r
+               try {\r
+                       valueStr = valueBinding.toString( valueBand.getValue() );\r
+               } catch (BindingException e) {\r
+                       valueStr = e.toString();\r
+               } catch (HistoryException e) {\r
+                       valueStr = e.toString();\r
+               }\r
+               if ( hasValue() ) {\r
+                       return "i="+index+", time=["+startTime+"-"+endTime+"], value="+valueStr;\r
+               } else {\r
+                       return "<no value>";\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Get start time of the first sample.\r
+        * @return time\r
+        */\r
+       public double getFirstTime() {\r
+               return from;\r
+       }\r
+       \r
+       /**\r
+        * Get end time of the last sample.\r
+        * @return time\r
+        */\r
+       public double getLastTime() {\r
+               return end;\r
+       }\r
+       \r
+       public int size() {\r
+               return size;\r
+       }\r
+       \r
+       public boolean isEmpty() {\r
+               return size==0;\r
+       }\r
+       \r
+}\r