1 /*******************************************************************************
2 * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * VTT Technical Research Centre of Finland - initial API and implementation
10 *******************************************************************************/
11 package org.simantics.databoard.accessor.impl;
13 import org.simantics.databoard.Bindings;
14 import org.simantics.databoard.accessor.MapAccessor;
15 import org.simantics.databoard.accessor.error.AccessorException;
16 import org.simantics.databoard.binding.ArrayBinding;
17 import org.simantics.databoard.binding.Binding;
18 import org.simantics.databoard.binding.BooleanBinding;
19 import org.simantics.databoard.binding.NumberBinding;
20 import org.simantics.databoard.binding.error.BindingException;
21 import org.simantics.databoard.binding.impl.BooleanArrayBinding;
22 import org.simantics.databoard.binding.impl.ByteArrayBinding;
23 import org.simantics.databoard.binding.impl.DoubleArrayBinding;
24 import org.simantics.databoard.binding.impl.FloatArrayBinding;
25 import org.simantics.databoard.binding.impl.IntArrayBinding;
26 import org.simantics.databoard.binding.impl.LongArrayBinding;
27 import org.simantics.databoard.type.ArrayType;
28 import org.simantics.databoard.util.Limit;
29 import org.simantics.databoard.util.Range;
32 * This helper class creates an iterator to MapAccessor
34 * @param <K> key class
35 * @param <V> value class
36 * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
38 public class MapAccessorIterator<K, V> {
45 boolean fromInclusive;
50 ArrayBinding keyCacheBinding;
53 ArrayBinding valueCacheBinding;
56 // Entry index, i.e. the number of entries read starting from 0
59 // The number of samples written to cache
60 int samplesInCache = 0;
66 * Initialize iterator with a cache. The cache should already be allocated with some empty elements.
70 * @param fromInclusive
73 * @param keyCacheBinding
75 * @param valueCacheBinding
78 public MapAccessorIterator(
80 Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,
81 ArrayBinding keyCacheBinding, Object keyCache,
82 ArrayBinding valueCacheBinding, Object valueCache) {
84 this.keyBinding = keyBinding;
86 this.fromInclusive = fromInclusive;
88 this.endInclusive = endInclusive;
89 this.valueBinding = valueCacheBinding.getComponentBinding();
90 this.keyCacheBinding = keyCacheBinding;
91 this.keyCache = keyCache;
92 this.valueCacheBinding = valueCacheBinding;
93 this.valueCache = valueCache;
97 * Initialize map accessor iterator with a default cache
101 * @param fromInclusive
103 * @param endInclusive
104 * @param valueBinding
106 * @throws BindingException
107 * @throws AccessorException
109 public MapAccessorIterator(
111 Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,
112 Binding valueBinding,
113 int cacheSize) throws BindingException, AccessorException {
115 this.keyBinding = keyBinding;
117 this.fromInclusive = fromInclusive;
119 this.endInclusive = endInclusive;
120 this.valueBinding = valueBinding;
122 // TODO calc num of elements if source
123 // int count = map.count(keyBinding, from, fromInclusive, end, endInclusive);
124 // int len = Math.min(count, 256);
125 Range range = new Range(Limit.inclusive(cacheSize), Limit.nolimit());
126 this.keyCacheBinding = Bindings.getBinding( new ArrayType(keyBinding.type(), range) );
127 this.keyCache = keyCacheBinding.createDefault();
128 this.valueCacheBinding = Bindings.getBinding( new ArrayType(valueBinding.type(), range) );
129 this.valueCache = valueCacheBinding.createDefault();
133 * Reads data to cache.
135 * Updates from and fromInclusive fields for next read.
136 * Updates samplesInCache field.
137 * Sets cacheIndex to 0.
139 * @throws AccessorException
141 private void fillCache() throws AccessorException {
143 int limit = Math.min(keyCacheBinding.size(keyCache), valueCacheBinding.size(valueCache));
144 if (limit==0) throw new AccessorException("You should have some entries in the cache");
153 samplesInCache = map.getEntries(
154 keyBinding, from, fromInclusive,
156 keyCacheBinding, keyCache,
157 valueCacheBinding, valueCache,
160 if (samplesInCache==0) {
165 from = keyCacheBinding.get(keyCache, samplesInCache-1);
166 fromInclusive = false;
167 } catch (BindingException e) {
168 throw new AccessorException(e);
172 public boolean hasNext() throws AccessorException {
173 if (from==null) return false;
174 if (cacheIndex>=samplesInCache-1) fillCache();
175 if (cacheIndex>=samplesInCache-1) return false;
176 return cacheIndex+1<samplesInCache;
179 public boolean next() throws AccessorException {
180 if (from==null) return false;
181 if (cacheIndex>=samplesInCache-1) fillCache();
182 if (cacheIndex>=samplesInCache-1) return false;
188 @SuppressWarnings("unchecked")
189 public K key() throws AccessorException {
191 return (K) keyCacheBinding.get(keyCache, cacheIndex);
192 } catch (IndexOutOfBoundsException e) {
193 throw new AccessorException(e);
194 } catch (BindingException e) {
195 throw new AccessorException(e);
199 @SuppressWarnings("unchecked")
200 public V value() throws AccessorException {
202 return (V) valueCacheBinding.get(valueCache, cacheIndex);
203 } catch (IndexOutOfBoundsException e) {
204 throw new AccessorException(e);
205 } catch (BindingException e) {
206 throw new AccessorException(e);
210 public double keyDouble() throws AccessorException {
212 if (keyCacheBinding instanceof FloatArrayBinding) {
213 return ((float[]) keyCache)[cacheIndex];
215 if (keyCacheBinding instanceof DoubleArrayBinding) {
216 return ((double[]) keyCache)[cacheIndex];
218 if (keyCacheBinding instanceof ByteArrayBinding) {
219 return ((byte[]) keyCache)[cacheIndex];
221 if (keyCacheBinding instanceof IntArrayBinding) {
222 return ((int[]) keyCache)[cacheIndex];
224 if (keyCacheBinding instanceof LongArrayBinding) {
225 return ((long[]) keyCache)[cacheIndex];
227 if (keyCacheBinding instanceof BooleanArrayBinding) {
228 return ((boolean[]) keyCache)[cacheIndex] ? 1.0 : 0.0;
230 Object o = keyCacheBinding.get(keyCache, cacheIndex);
231 Binding b = keyCacheBinding.getComponentBinding();
232 if (b instanceof BooleanBinding)
233 return ((BooleanBinding)b).getValue(o) ? 1.0 : 0.0;
234 NumberBinding nb = (NumberBinding) b;
235 return nb.getValue(o).doubleValue();
236 } catch (IndexOutOfBoundsException e) {
237 throw new AccessorException(e);
238 } catch (BindingException e) {
239 throw new AccessorException(e);
243 public double valueDouble() throws AccessorException {
245 if (valueCacheBinding instanceof FloatArrayBinding) {
246 return ((float[]) valueCache)[cacheIndex];
248 if (valueCacheBinding instanceof DoubleArrayBinding) {
249 return ((double[]) valueCache)[cacheIndex];
251 if (valueCacheBinding instanceof ByteArrayBinding) {
252 return ((byte[]) valueCache)[cacheIndex];
254 if (valueCacheBinding instanceof IntArrayBinding) {
255 return ((int[]) valueCache)[cacheIndex];
257 if (valueCacheBinding instanceof LongArrayBinding) {
258 return ((long[]) valueCache)[cacheIndex];
260 if (valueCacheBinding instanceof BooleanArrayBinding) {
261 return ((boolean[]) valueCache)[cacheIndex] ? 1.0 : 0.0;
263 Object o = valueCacheBinding.get(valueCache, cacheIndex);
264 Binding b = valueCacheBinding.getComponentBinding();
265 if (b instanceof BooleanBinding)
266 return ((BooleanBinding)b).getValue(o) ? 1.0 : 0.0;
267 NumberBinding nb = (NumberBinding) b;
268 return nb.getValue(o).doubleValue();
269 } catch (IndexOutOfBoundsException e) {
270 throw new AccessorException(e);
271 } catch (BindingException e) {
272 throw new AccessorException(e);