X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2Fslice%2FSliceUtil.java;fp=bundles%2Forg.simantics.utils.datastructures%2Fsrc%2Forg%2Fsimantics%2Futils%2Fdatastructures%2Fslice%2FSliceUtil.java;h=5a209f5ddc40a0124f8f4ee19e8033f8dea4e6d7;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java new file mode 100644 index 000000000..5a209f5dd --- /dev/null +++ b/bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/slice/SliceUtil.java @@ -0,0 +1,97 @@ +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; + } + +}