]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/impl/MapAccessorIterator.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / accessor / impl / MapAccessorIterator.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/impl/MapAccessorIterator.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/accessor/impl/MapAccessorIterator.java
new file mode 100644 (file)
index 0000000..ea7d387
--- /dev/null
@@ -0,0 +1,281 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\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.databoard.accessor.impl;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.MapAccessor;\r
+import org.simantics.databoard.accessor.error.AccessorException;\r
+import org.simantics.databoard.binding.ArrayBinding;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.BooleanBinding;\r
+import org.simantics.databoard.binding.NumberBinding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.impl.BooleanArrayBinding;\r
+import org.simantics.databoard.binding.impl.ByteArrayBinding;\r
+import org.simantics.databoard.binding.impl.DoubleArrayBinding;\r
+import org.simantics.databoard.binding.impl.FloatArrayBinding;\r
+import org.simantics.databoard.binding.impl.IntArrayBinding;\r
+import org.simantics.databoard.binding.impl.LongArrayBinding;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.util.Limit;\r
+import org.simantics.databoard.util.Range;\r
+\r
+/**\r
+ * This helper class creates an iterator to MapAccessor\r
+ *\r
+ * @param <K> key class\r
+ * @param <V> value class\r
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
+ */\r
+public class MapAccessorIterator<K, V> {\r
+       \r
+       MapAccessor map;\r
+       Binding keyBinding;\r
+       Binding valueBinding;\r
+       \r
+       Object from;\r
+       boolean fromInclusive;\r
+       \r
+       Object end;\r
+       boolean endInclusive;\r
+\r
+       ArrayBinding keyCacheBinding;\r
+       Object keyCache;\r
+       \r
+       ArrayBinding valueCacheBinding;\r
+       Object valueCache;\r
+       \r
+       // Entry index, i.e. the number of entries read starting from 0\r
+       int index = -1;\r
+       \r
+       // The number of samples written to cache\r
+       int samplesInCache = 0;\r
+       \r
+       // The index in cache\r
+       int cacheIndex = -1;\r
+       \r
+       /**\r
+        * Initialize iterator with a cache. The cache should already be allocated with some empty elements.\r
+        * @param map\r
+        * @param keyBinding\r
+        * @param from\r
+        * @param fromInclusive\r
+        * @param end\r
+        * @param endInclusive\r
+        * @param keyCacheBinding\r
+        * @param keyCache\r
+        * @param valueCacheBinding\r
+        * @param valueCache\r
+        */\r
+       public MapAccessorIterator(\r
+                       MapAccessor map, \r
+                       Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,                       \r
+                       ArrayBinding keyCacheBinding, Object keyCache,\r
+                       ArrayBinding valueCacheBinding, Object valueCache) {\r
+               this.map = map;\r
+               this.keyBinding = keyBinding;\r
+               this.from = from;\r
+               this.fromInclusive = fromInclusive;\r
+               this.end = end;\r
+               this.endInclusive = endInclusive;\r
+               this.valueBinding = valueCacheBinding.getComponentBinding();\r
+               this.keyCacheBinding = keyCacheBinding;\r
+               this.keyCache = keyCache;\r
+               this.valueCacheBinding = valueCacheBinding;\r
+               this.valueCache = valueCache;\r
+       }\r
+\r
+       /**\r
+        * Initialize map accessor iterator with a default cache\r
+        * @param map\r
+        * @param keyBinding\r
+        * @param from\r
+        * @param fromInclusive\r
+        * @param end\r
+        * @param endInclusive\r
+        * @param valueBinding\r
+        * @param cacheSize\r
+        * @throws BindingException \r
+        * @throws AccessorException \r
+        */\r
+       public MapAccessorIterator(\r
+                       MapAccessor map, \r
+                       Binding keyBinding, Object from, boolean fromInclusive, Object end, boolean endInclusive,\r
+                       Binding valueBinding,\r
+                       int cacheSize) throws BindingException, AccessorException {\r
+               this.map = map;\r
+               this.keyBinding = keyBinding;\r
+               this.from = from;\r
+               this.fromInclusive = fromInclusive;\r
+               this.end = end;\r
+               this.endInclusive = endInclusive;\r
+               this.valueBinding = valueBinding;\r
+               \r
+               // TODO calc num of elements if source\r
+//             int count = map.count(keyBinding, from, fromInclusive, end, endInclusive);              \r
+//             int len = Math.min(count, 256);\r
+               Range range = new Range(Limit.inclusive(cacheSize), Limit.nolimit());\r
+               this.keyCacheBinding = Bindings.getBinding( new ArrayType(keyBinding.type(), range) );\r
+               this.keyCache = keyCacheBinding.createDefault();\r
+               this.valueCacheBinding = Bindings.getBinding( new ArrayType(valueBinding.type(), range) );\r
+               this.valueCache = valueCacheBinding.createDefault();\r
+       }\r
+\r
+    /**\r
+        * Reads data to cache.\r
+        * \r
+        * Updates from and fromInclusive fields for next read.\r
+        * Updates samplesInCache field.\r
+        * Sets cacheIndex to 0.\r
+        * \r
+        * @throws AccessorException\r
+        */\r
+       private void fillCache() throws AccessorException {\r
+               try {\r
+                       int limit = Math.min(keyCacheBinding.size(keyCache), valueCacheBinding.size(valueCache));\r
+                       if (limit==0) throw new AccessorException("You should have some entries in the cache");\r
+                       \r
+                       cacheIndex = -1;\r
+                       \r
+                       if (from==null) {\r
+                               samplesInCache = 0;\r
+                               return;\r
+                       }\r
+               \r
+                       samplesInCache = map.getEntries(\r
+                               keyBinding, from, fromInclusive, \r
+                               end, endInclusive, \r
+                               keyCacheBinding, keyCache, \r
+                               valueCacheBinding, valueCache, \r
+                               limit);\r
+                       \r
+                       if (samplesInCache==0) {\r
+                               from = null;\r
+                               return;\r
+                       }\r
+                       \r
+                       from = keyCacheBinding.get(keyCache, samplesInCache-1);\r
+                       fromInclusive = false;\r
+               } catch (BindingException e) {\r
+                       throw new AccessorException(e);\r
+               }\r
+       }\r
+       \r
+       public boolean hasNext() throws AccessorException {\r
+               if (from==null) return false;           \r
+               if (cacheIndex>=samplesInCache-1) fillCache();\r
+               if (cacheIndex>=samplesInCache-1) return false;\r
+               return cacheIndex+1<samplesInCache;\r
+       }\r
+       \r
+       public boolean next() throws AccessorException {\r
+               if (from==null) return false;\r
+               if (cacheIndex>=samplesInCache-1) fillCache();\r
+               if (cacheIndex>=samplesInCache-1) return false;         \r
+               cacheIndex++;\r
+               index++;\r
+               return true;\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       public K key() throws AccessorException {\r
+               try {\r
+                       return (K) keyCacheBinding.get(keyCache, cacheIndex);\r
+               } catch (IndexOutOfBoundsException e) {\r
+                       throw new AccessorException(e);\r
+               } catch (BindingException e) {\r
+                       throw new AccessorException(e);\r
+               }\r
+       }\r
+       \r
+       @SuppressWarnings("unchecked")\r
+       public V value() throws AccessorException {\r
+               try {\r
+                       return (V) valueCacheBinding.get(valueCache, cacheIndex);\r
+               } catch (IndexOutOfBoundsException e) {\r
+                       throw new AccessorException(e);\r
+               } catch (BindingException e) {\r
+                       throw new AccessorException(e);\r
+               }\r
+       }\r
+       \r
+       public double keyDouble() throws AccessorException {\r
+               try {\r
+                       if (keyCacheBinding instanceof FloatArrayBinding) {\r
+                               return ((float[]) keyCache)[cacheIndex];\r
+                       }\r
+                       if (keyCacheBinding instanceof DoubleArrayBinding) {\r
+                               return ((double[]) keyCache)[cacheIndex];\r
+                       }\r
+                       if (keyCacheBinding instanceof ByteArrayBinding) {\r
+                               return ((byte[]) keyCache)[cacheIndex];\r
+                       }\r
+                       if (keyCacheBinding instanceof IntArrayBinding) {\r
+                               return ((int[]) keyCache)[cacheIndex];\r
+                       }\r
+                       if (keyCacheBinding instanceof LongArrayBinding) {\r
+                               return ((long[]) keyCache)[cacheIndex];\r
+                       }\r
+                       if (keyCacheBinding instanceof BooleanArrayBinding) {\r
+                               return ((boolean[]) keyCache)[cacheIndex] ? 1.0 : 0.0;\r
+                       }\r
+                       Object o = keyCacheBinding.get(keyCache, cacheIndex);\r
+                       Binding b = keyCacheBinding.getComponentBinding();\r
+                       if (b instanceof BooleanBinding)\r
+                               return ((BooleanBinding)b).getValue(o) ? 1.0 : 0.0;\r
+                       NumberBinding nb = (NumberBinding) b;\r
+                       return nb.getValue(o).doubleValue();\r
+               } catch (IndexOutOfBoundsException e) {\r
+                       throw new AccessorException(e);\r
+               } catch (BindingException e) {\r
+                       throw new AccessorException(e);\r
+               }\r
+       }\r
+       \r
+       public double valueDouble() throws AccessorException {\r
+               try {\r
+                       if (valueCacheBinding instanceof FloatArrayBinding) {\r
+                               return ((float[]) valueCache)[cacheIndex];\r
+                       }\r
+                       if (valueCacheBinding instanceof DoubleArrayBinding) {\r
+                               return ((double[]) valueCache)[cacheIndex];\r
+                       }\r
+                       if (valueCacheBinding instanceof ByteArrayBinding) {\r
+                               return ((byte[]) valueCache)[cacheIndex];\r
+                       }\r
+                       if (valueCacheBinding instanceof IntArrayBinding) {\r
+                               return ((int[]) valueCache)[cacheIndex];\r
+                       }\r
+                       if (valueCacheBinding instanceof LongArrayBinding) {\r
+                               return ((long[]) valueCache)[cacheIndex];\r
+                       }\r
+                       if (valueCacheBinding instanceof BooleanArrayBinding) {\r
+                               return ((boolean[]) valueCache)[cacheIndex] ? 1.0 : 0.0;\r
+                       }\r
+                       Object o = valueCacheBinding.get(valueCache, cacheIndex);\r
+                       Binding b = valueCacheBinding.getComponentBinding();\r
+                       if (b instanceof BooleanBinding)\r
+                               return ((BooleanBinding)b).getValue(o) ? 1.0 : 0.0;\r
+                       NumberBinding nb = (NumberBinding) b;\r
+                       return nb.getValue(o).doubleValue();\r
+               } catch (IndexOutOfBoundsException e) {\r
+                       throw new AccessorException(e);\r
+               } catch (BindingException e) {\r
+                       throw new AccessorException(e);\r
+               }\r
+       }\r
+       \r
+       public int index() {\r
+               return index;\r
+       }\r
+\r
+}\r
+\r