package org.simantics.utils.datastructures.slice; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; /** * @author Tuukka Lehtonen */ public final class SliceUtil { public static final int MAX_NODES_PER_LEVEL_EXP = 2; /** * @param * @param prop * @return */ public static > Collection subnodify(Sliceable prop) { return subnodify(prop, prop.getRange()); } /** * @param * @param prop * @param range * @return */ public static > Collection subnodify(Sliceable prop, ValueRange range) { return subnodify(prop, range.start(), range.size(), MAX_NODES_PER_LEVEL_EXP); } /** * @param * @param prop * @param rangeStart * @param rangeSize * @return */ public static > Collection subnodify(Sliceable prop, int rangeStart, int rangeSize) { return subnodify(prop, rangeStart, rangeSize, MAX_NODES_PER_LEVEL_EXP); } /** * @param * @param p * @param rangeStart * @param rangeSize * @param pow10OfItemsPerLevel * @return */ public static Collection subnodify(Object p, int rangeStart, int rangeSize, int pow10OfItemsPerLevel) { if (rangeSize < 2) return Collections.emptyList(); if (!(p instanceof Sliceable)) return Collections.emptyList(); @SuppressWarnings("unchecked") Sliceable prop = (Sliceable) p; // Defaults for <= 100 nodes int nodes = rangeSize; int intervalSize = 1; int maxNodesPerLevel = (int) Math.pow(10, pow10OfItemsPerLevel); if (rangeSize > maxNodesPerLevel) { double intervalSizeExp = Math.floor(Math.log10(rangeSize)); double intervalMaxSize = Math.pow(10, intervalSizeExp); //System.out.println("EXP: " + intervalSizeExp + " => " + intervalMaxSize); if ((int) intervalMaxSize == rangeSize) { // Need to make the amount of shown children smaller. // As a minimum, always leave at least MAX_NODES_PER_LEVEL // elements into the leaf nodes. intervalMaxSize = Math.pow(10, Math.max(intervalSizeExp - pow10OfItemsPerLevel, pow10OfItemsPerLevel)); //System.out.println("EXP2: " + intervalMaxSize); } nodes = (int) (Math.ceil(rangeSize / intervalMaxSize)); intervalSize = (int) intervalMaxSize; } int start = rangeStart; int sizeLeft = rangeSize; //System.out.println("SUBNODIFY: " + rangeStart + ", " + rangeSize + " => " + intervalSize + ", " + nodes); ArrayList result = new ArrayList(nodes); for (int i = 0; i < nodes; ++i) { result.add(prop.slice(ValueRange.make(start, Math.min(intervalSize, sizeLeft)))); //System.out.println(result.get(result.size()-1)); start += intervalSize; sizeLeft -= intervalSize; } return result; } }