]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / slice / SliceUtil.java
diff --git a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java
new file mode 100644 (file)
index 0000000..5a209f5
--- /dev/null
@@ -0,0 +1,97 @@
+package org.simantics.utils.datastructures.slice;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public final class SliceUtil {\r
+\r
+    public static final int MAX_NODES_PER_LEVEL_EXP = 2;\r
+\r
+    /**\r
+     * @param <T>\r
+     * @param prop\r
+     * @return\r
+     */\r
+    public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop) {\r
+        return subnodify(prop, prop.getRange());\r
+    }\r
+\r
+    /**\r
+     * @param <T>\r
+     * @param prop\r
+     * @param range\r
+     * @return\r
+     */\r
+    public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop, ValueRange range) {\r
+        return subnodify(prop, range.start(), range.size(), MAX_NODES_PER_LEVEL_EXP);\r
+    }\r
+\r
+    /**\r
+     * @param <T>\r
+     * @param prop\r
+     * @param rangeStart\r
+     * @param rangeSize\r
+     * @return\r
+     */\r
+    public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop, int rangeStart, int rangeSize) {\r
+        return subnodify(prop, rangeStart, rangeSize, MAX_NODES_PER_LEVEL_EXP);\r
+    }\r
+\r
+    /**\r
+     * @param <T>\r
+     * @param p\r
+     * @param rangeStart\r
+     * @param rangeSize\r
+     * @param pow10OfItemsPerLevel\r
+     * @return\r
+     */\r
+    public static <T> Collection<T> subnodify(Object p, int rangeStart, int rangeSize, int pow10OfItemsPerLevel) {\r
+        if (rangeSize < 2)\r
+            return Collections.emptyList();\r
+        if (!(p instanceof Sliceable<?>))\r
+            return Collections.emptyList();\r
+\r
+        @SuppressWarnings("unchecked")\r
+        Sliceable<T> prop = (Sliceable<T>) p;\r
+\r
+        // Defaults for <= 100 nodes\r
+        int nodes = rangeSize;\r
+        int intervalSize = 1;\r
+\r
+        int maxNodesPerLevel = (int) Math.pow(10, pow10OfItemsPerLevel);\r
+\r
+        if (rangeSize > maxNodesPerLevel) {\r
+            double intervalSizeExp = Math.floor(Math.log10(rangeSize));\r
+            double intervalMaxSize = Math.pow(10, intervalSizeExp);\r
+            //System.out.println("EXP: " + intervalSizeExp + " => " + intervalMaxSize);\r
+            if ((int) intervalMaxSize == rangeSize) {\r
+                // Need to make the amount of shown children smaller.\r
+                // As a minimum, always leave at least MAX_NODES_PER_LEVEL\r
+                // elements into the leaf nodes.\r
+                intervalMaxSize = Math.pow(10, Math.max(intervalSizeExp - pow10OfItemsPerLevel, pow10OfItemsPerLevel));\r
+                //System.out.println("EXP2: " + intervalMaxSize);\r
+            }\r
+            nodes = (int) (Math.ceil(rangeSize / intervalMaxSize));\r
+            intervalSize = (int) intervalMaxSize;\r
+        }\r
+\r
+        int start = rangeStart;\r
+        int sizeLeft = rangeSize;\r
+\r
+        //System.out.println("SUBNODIFY: " + rangeStart + ", " + rangeSize + " => " + intervalSize + ", " + nodes);\r
+\r
+        ArrayList<T> result = new ArrayList<T>(nodes);\r
+        for (int i = 0; i < nodes; ++i) {\r
+            result.add(prop.slice(ValueRange.make(start, Math.min(intervalSize, sizeLeft))));\r
+            //System.out.println(result.get(result.size()-1));\r
+            start += intervalSize;\r
+            sizeLeft -= intervalSize;\r
+        }\r
+        return result;\r
+    }\r
+\r
+}\r