1 /*******************************************************************************
2 * Copyright (c) 2007, 2012 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.history.util;
14 import org.simantics.databoard.Bindings;
15 import org.simantics.databoard.accessor.ArrayAccessor;
16 import org.simantics.databoard.accessor.error.AccessorException;
17 import org.simantics.databoard.binding.Binding;
18 import org.simantics.databoard.binding.RecordBinding;
19 import org.simantics.databoard.binding.error.BindingException;
20 import org.simantics.history.HistoryException;
23 * Stream iterator iterates sample entries in an array.
25 * Is scans the next sample and knows its time stamp.
27 * @author toni.kalajainen
29 public class StreamIterator {
32 RecordBinding sampleBinding;
38 // From and end times of the whole stream
41 // Current and next sample
44 // Utility for reading sample
45 ValueBand valueBand, nextValueBand;
46 // Start and end time of current sample
47 double startTime, endTime;
52 public StreamIterator(ArrayAccessor aa) throws HistoryException {
55 sampleBinding = (RecordBinding) Bindings.getBeanBinding( aa.type().componentType );
56 current = sampleBinding.createDefault();
57 next = sampleBinding.createDefault();
58 valueBand = new ValueBand(sampleBinding, current);
59 nextValueBand = new ValueBand(sampleBinding, next);
60 stream = new Stream( aa, sampleBinding );
63 aa.get(0, sampleBinding, current);
64 from = valueBand.getTimeDouble();
65 aa.get(size-1, sampleBinding, current);
66 end = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
68 } catch (BindingException e) {
69 throw new HistoryException( e );
70 } catch (AccessorException e) {
71 throw new HistoryException( e );
76 * Go to time using random access
78 * @return true if sample was found
79 * @throws HistoryException
81 public boolean gotoTime(double time) throws HistoryException {
83 if ( time<from || time>end ) {
89 if ( time>=startTime && time<endTime ) return hasValue();
90 int i = stream.binarySearch(Bindings.DOUBLE, time);
95 if ( insertPos<0 || insertPos>=size ) {
98 gotoIndex( insertPos );
99 if ( endTime<time ) index = -1;
107 * Proceed to time using sequential seek.
110 * @return true if sample was found
111 * @throws HistoryException
113 public boolean proceedToTime(double time) throws HistoryException {
115 if ( time<from || time>end ) {
120 // No position, or going to past
121 if (index<0 || startTime>time) {
126 // Proceed until end hit
127 while (time>=endTime && hasNext()) gotoIndex(index+1);
132 * Go to index. If element does not exist, index is set to -1;
134 * @throws HistoryException
136 public void gotoIndex(int pos) throws HistoryException {
137 if (pos == index) return;
139 if (pos<0 || pos>=size) {
145 // Read current value
146 if (pos == index+1 && index>=0) {
147 sampleBinding.readFrom(sampleBinding, next, current);
149 aa.get(pos, sampleBinding, current);
151 startTime = valueBand.getTimeDouble();
155 aa.get(pos+1, sampleBinding, next);
156 //endTime = valueBand.isValidValue() ? nextValueBand.getTimeDouble() : ( nextValueBand.isValidValue() ? nextValueBand.getTimeDouble() : nextValueBand.getTimeDouble() );
157 endTime = nextValueBand.getTimeDouble();
159 endTime = valueBand.hasEndTime() ? valueBand.getEndTimeDouble() : valueBand.getTimeDouble();
164 } catch (AccessorException e) {
165 throw new HistoryException( e );
166 } catch (BindingException e) {
167 throw new HistoryException( e );
172 public boolean hasNext() {
176 public void next() throws HistoryException {
178 gotoIndex( index+1 );
181 public ValueBand getValueBand() {
185 public Object getValue(Binding binding) throws HistoryException {
186 return valueBand.getValue(binding);
189 public Object getSample() {
193 public RecordBinding getSampleBinding() {
194 return sampleBinding;
197 public boolean hasValue() {
201 public boolean hasValidValue() throws HistoryException {
202 return index!=-1 && !valueBand.isNanSample() && !valueBand.isNullValue();
205 * Get the start time. The value is valid if index != -1
208 public double getStartTime() {
213 * Get end time, the value is valid if index != -1
216 public double getEndTime() {
220 public Double getNextTime() throws HistoryException {
221 if ( size==0 ) return null;
222 if ( index==-1 ) return from;
223 return (Double) nextValueBand.getTime(Bindings.DOUBLE);
226 public Double getNextTime( double currentTime ) throws HistoryException {
227 if ( size==0 ) return null;
228 if ( index==-1 ) return from;
230 if ( valueBand.hasEndTime() ) {
231 Double endTime = (Double) valueBand.getEndTime(Bindings.DOUBLE);
232 if ( endTime>currentTime ) return endTime;
235 double nextTime = (Double) nextValueBand.getTime(Bindings.DOUBLE);
242 * get index of the cursor
243 * @return index or -1
245 public int getIndex() {
250 public String toString() {
251 Binding valueBinding = valueBand.getValueBinding();
254 valueStr = valueBinding.toString( valueBand.getValue() );
255 } catch (BindingException e) {
256 valueStr = e.toString();
257 } catch (HistoryException e) {
258 valueStr = e.toString();
261 return "i="+index+", time=["+startTime+"-"+endTime+"], value="+valueStr;
268 * Get start time of the first sample.
271 public double getFirstTime() {
276 * Get end time of the last sample.
279 public double getLastTime() {
287 public boolean isEmpty() {