1 package org.simantics.utils.datastructures.slice;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Collections;
8 * @author Tuukka Lehtonen
10 public final class SliceUtil {
12 public static final int MAX_NODES_PER_LEVEL_EXP = 2;
19 public static <T extends Sliceable<T>> Collection<T> subnodify(Sliceable<T> prop) {
20 return subnodify(prop, prop.getRange());
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);
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);
49 * @param pow10OfItemsPerLevel
52 public static <T> Collection<T> subnodify(Object p, int rangeStart, int rangeSize, int pow10OfItemsPerLevel) {
54 return Collections.emptyList();
55 if (!(p instanceof Sliceable<?>))
56 return Collections.emptyList();
58 @SuppressWarnings("unchecked")
59 Sliceable<T> prop = (Sliceable<T>) p;
61 // Defaults for <= 100 nodes
62 int nodes = rangeSize;
65 int maxNodesPerLevel = (int) Math.pow(10, pow10OfItemsPerLevel);
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);
78 nodes = (int) (Math.ceil(rangeSize / intervalMaxSize));
79 intervalSize = (int) intervalMaxSize;
82 int start = rangeStart;
83 int sizeLeft = rangeSize;
85 //System.out.println("SUBNODIFY: " + rangeStart + ", " + rangeSize + " => " + intervalSize + ", " + nodes);
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;