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