--- /dev/null
+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