]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 package org.simantics.utils.datastructures.slice;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.Collections;\r
6 \r
7 /**\r
8  * @author Tuukka Lehtonen\r
9  */\r
10 public final class SliceUtil {\r
11 \r
12     public static final int MAX_NODES_PER_LEVEL_EXP = 2;\r
13 \r
14     /**\r
15      * @param <T>\r
16      * @param prop\r
17      * @return\r
18      */\r
19     public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop) {\r
20         return subnodify(prop, prop.getRange());\r
21     }\r
22 \r
23     /**\r
24      * @param <T>\r
25      * @param prop\r
26      * @param range\r
27      * @return\r
28      */\r
29     public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop, ValueRange range) {\r
30         return subnodify(prop, range.start(), range.size(), MAX_NODES_PER_LEVEL_EXP);\r
31     }\r
32 \r
33     /**\r
34      * @param <T>\r
35      * @param prop\r
36      * @param rangeStart\r
37      * @param rangeSize\r
38      * @return\r
39      */\r
40     public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop, int rangeStart, int rangeSize) {\r
41         return subnodify(prop, rangeStart, rangeSize, MAX_NODES_PER_LEVEL_EXP);\r
42     }\r
43 \r
44     /**\r
45      * @param <T>\r
46      * @param p\r
47      * @param rangeStart\r
48      * @param rangeSize\r
49      * @param pow10OfItemsPerLevel\r
50      * @return\r
51      */\r
52     public static <T> Collection<T> subnodify(Object p, int rangeStart, int rangeSize, int pow10OfItemsPerLevel) {\r
53         if (rangeSize < 2)\r
54             return Collections.emptyList();\r
55         if (!(p instanceof Sliceable<?>))\r
56             return Collections.emptyList();\r
57 \r
58         @SuppressWarnings("unchecked")\r
59         Sliceable<T> prop = (Sliceable<T>) p;\r
60 \r
61         // Defaults for <= 100 nodes\r
62         int nodes = rangeSize;\r
63         int intervalSize = 1;\r
64 \r
65         int maxNodesPerLevel = (int) Math.pow(10, pow10OfItemsPerLevel);\r
66 \r
67         if (rangeSize > maxNodesPerLevel) {\r
68             double intervalSizeExp = Math.floor(Math.log10(rangeSize));\r
69             double intervalMaxSize = Math.pow(10, intervalSizeExp);\r
70             //System.out.println("EXP: " + intervalSizeExp + " => " + intervalMaxSize);\r
71             if ((int) intervalMaxSize == rangeSize) {\r
72                 // Need to make the amount of shown children smaller.\r
73                 // As a minimum, always leave at least MAX_NODES_PER_LEVEL\r
74                 // elements into the leaf nodes.\r
75                 intervalMaxSize = Math.pow(10, Math.max(intervalSizeExp - pow10OfItemsPerLevel, pow10OfItemsPerLevel));\r
76                 //System.out.println("EXP2: " + intervalMaxSize);\r
77             }\r
78             nodes = (int) (Math.ceil(rangeSize / intervalMaxSize));\r
79             intervalSize = (int) intervalMaxSize;\r
80         }\r
81 \r
82         int start = rangeStart;\r
83         int sizeLeft = rangeSize;\r
84 \r
85         //System.out.println("SUBNODIFY: " + rangeStart + ", " + rangeSize + " => " + intervalSize + ", " + nodes);\r
86 \r
87         ArrayList<T> result = new ArrayList<T>(nodes);\r
88         for (int i = 0; i < nodes; ++i) {\r
89             result.add(prop.slice(ValueRange.make(start, Math.min(intervalSize, sizeLeft))));\r
90             //System.out.println(result.get(result.size()-1));\r
91             start += intervalSize;\r
92             sizeLeft -= intervalSize;\r
93         }\r
94         return result;\r
95     }\r
96 \r
97 }\r