]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/impl/MapAccessorIterator.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / accessor / impl / MapAccessorIterator.java
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
7  *
8  * Contributors:
9  *     VTT Technical Research Centre of Finland - initial API and implementation
10  *******************************************************************************/
11 package org.simantics.databoard.accessor.impl;
12
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;
30
31 /**
32  * This helper class creates an iterator to MapAccessor
33  *
34  * @param <K> key class
35  * @param <V> value class
36  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>
37  */
38 public class MapAccessorIterator<K, V> {
39         
40         MapAccessor map;
41         Binding keyBinding;
42         Binding valueBinding;
43         
44         Object from;
45         boolean fromInclusive;
46         
47         Object end;
48         boolean endInclusive;
49
50         ArrayBinding keyCacheBinding;
51         Object keyCache;
52         
53         ArrayBinding valueCacheBinding;
54         Object valueCache;
55         
56         // Entry index, i.e. the number of entries read starting from 0
57         int index = -1;
58         
59         // The number of samples written to cache
60         int samplesInCache = 0;
61         
62         // The index in cache
63         int cacheIndex = -1;
64         
65         /**
66          * Initialize iterator with a cache. The cache should already be allocated with some empty elements.
67          * @param map
68          * @param keyBinding
69          * @param from
70          * @param fromInclusive
71          * @param end
72          * @param endInclusive
73          * @param keyCacheBinding
74          * @param keyCache
75          * @param valueCacheBinding
76          * @param valueCache
77          */
78         public MapAccessorIterator(
79                         MapAccessor map, 
80                         Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,                       
81                         ArrayBinding keyCacheBinding, Object keyCache,
82                         ArrayBinding valueCacheBinding, Object valueCache) {
83                 this.map = map;
84                 this.keyBinding = keyBinding;
85                 this.from = from;
86                 this.fromInclusive = fromInclusive;
87                 this.end = end;
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;
94         }
95
96         /**
97          * Initialize map accessor iterator with a default cache
98          * @param map
99          * @param keyBinding
100          * @param from
101          * @param fromInclusive
102          * @param end
103          * @param endInclusive
104          * @param valueBinding
105          * @param cacheSize
106          * @throws BindingException 
107          * @throws AccessorException 
108          */
109         public MapAccessorIterator(
110                         MapAccessor map, 
111                         Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,
112                         Binding valueBinding,
113                         int cacheSize) throws BindingException, AccessorException {
114                 this.map = map;
115                 this.keyBinding = keyBinding;
116                 this.from = from;
117                 this.fromInclusive = fromInclusive;
118                 this.end = end;
119                 this.endInclusive = endInclusive;
120                 this.valueBinding = valueBinding;
121                 
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();
130         }
131
132     /**
133          * Reads data to cache.
134          * 
135          * Updates from and fromInclusive fields for next read.
136          * Updates samplesInCache field.
137          * Sets cacheIndex to 0.
138          * 
139          * @throws AccessorException
140          */
141         private void fillCache() throws AccessorException {
142                 try {
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");
145                         
146                         cacheIndex = -1;
147                         
148                         if (from==null) {
149                                 samplesInCache = 0;
150                                 return;
151                         }
152                 
153                         samplesInCache = map.getEntries(
154                                 keyBinding, from, fromInclusive, 
155                                 end, endInclusive, 
156                                 keyCacheBinding, keyCache, 
157                                 valueCacheBinding, valueCache, 
158                                 limit);
159                         
160                         if (samplesInCache==0) {
161                                 from = null;
162                                 return;
163                         }
164                         
165                         from = keyCacheBinding.get(keyCache, samplesInCache-1);
166                         fromInclusive = false;
167                 } catch (BindingException e) {
168                         throw new AccessorException(e);
169                 }
170         }
171         
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;
177         }
178         
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;         
183                 cacheIndex++;
184                 index++;
185                 return true;
186         }
187
188         @SuppressWarnings("unchecked")
189         public K key() throws AccessorException {
190                 try {
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);
196                 }
197         }
198         
199         @SuppressWarnings("unchecked")
200         public V value() throws AccessorException {
201                 try {
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);
207                 }
208         }
209         
210         public double keyDouble() throws AccessorException {
211                 try {
212                         if (keyCacheBinding instanceof FloatArrayBinding) {
213                                 return ((float[]) keyCache)[cacheIndex];
214                         }
215                         if (keyCacheBinding instanceof DoubleArrayBinding) {
216                                 return ((double[]) keyCache)[cacheIndex];
217                         }
218                         if (keyCacheBinding instanceof ByteArrayBinding) {
219                                 return ((byte[]) keyCache)[cacheIndex];
220                         }
221                         if (keyCacheBinding instanceof IntArrayBinding) {
222                                 return ((int[]) keyCache)[cacheIndex];
223                         }
224                         if (keyCacheBinding instanceof LongArrayBinding) {
225                                 return ((long[]) keyCache)[cacheIndex];
226                         }
227                         if (keyCacheBinding instanceof BooleanArrayBinding) {
228                                 return ((boolean[]) keyCache)[cacheIndex] ? 1.0 : 0.0;
229                         }
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);
240                 }
241         }
242         
243         public double valueDouble() throws AccessorException {
244                 try {
245                         if (valueCacheBinding instanceof FloatArrayBinding) {
246                                 return ((float[]) valueCache)[cacheIndex];
247                         }
248                         if (valueCacheBinding instanceof DoubleArrayBinding) {
249                                 return ((double[]) valueCache)[cacheIndex];
250                         }
251                         if (valueCacheBinding instanceof ByteArrayBinding) {
252                                 return ((byte[]) valueCache)[cacheIndex];
253                         }
254                         if (valueCacheBinding instanceof IntArrayBinding) {
255                                 return ((int[]) valueCache)[cacheIndex];
256                         }
257                         if (valueCacheBinding instanceof LongArrayBinding) {
258                                 return ((long[]) valueCache)[cacheIndex];
259                         }
260                         if (valueCacheBinding instanceof BooleanArrayBinding) {
261                                 return ((boolean[]) valueCache)[cacheIndex] ? 1.0 : 0.0;
262                         }
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);
273                 }
274         }
275         
276         public int index() {
277                 return index;
278         }
279
280 }
281