public List split()

in accord-core/src/main/java/accord/local/ShardDistributor.java [62:111]


        public List<Ranges> split(Ranges ranges)
        {
            if (ranges.isEmpty())
                return Collections.emptyList();

            Splitter<T> splitter = this.splitter.apply(ranges);
            T totalSize = splitter.zero();
            for (int i = 0 ; i < ranges.size() ; ++i)
                totalSize = splitter.add(totalSize, splitter.sizeOf(ranges.get(i)));

            if (splitter.compare(totalSize, splitter.zero()) <= 0)
                throw new IllegalStateException();

            int numberOfShards = splitter.min(totalSize, this.numberOfShards);
            T shardSize = splitter.divide(totalSize, numberOfShards);
            List<Range> buffer = new ArrayList<>(ranges.size());
            List<Ranges> result = new ArrayList<>(numberOfShards);
            int ri = 0;
            T rOffset = splitter.zero();
            T rSize = splitter.sizeOf(ranges.get(0));
            while (result.size() < numberOfShards)
            {
                T required = result.size() < numberOfShards - 1 ? shardSize : splitter.subtract(totalSize, splitter.multiply(shardSize, (numberOfShards - 1)));
                while (true)
                {
                    if (splitter.compare(splitter.subtract(rSize, rOffset), required) >= 0)
                    {
                        buffer.add(splitter.subRange(ranges.get(ri), rOffset, splitter.add(rOffset, required)));
                        result.add(Ranges.ofSortedAndDeoverlapped(buffer.toArray(new Range[0])));
                        buffer.clear();
                        rOffset = splitter.add(rOffset, required);
                        if (splitter.compare(rOffset, rSize) >= 0 && ++ri < ranges.size())
                        {
                            Invariants.checkState(splitter.compare(rOffset, rSize) == 0);
                            rOffset = splitter.zero();
                            rSize = splitter.sizeOf(ranges.get(ri));
                        }
                        break;
                    }
                    else
                    {
                        buffer.add(splitter.subRange(ranges.get(ri), rOffset, rSize));
                        required = splitter.subtract(required, splitter.subtract(rSize, rOffset));
                        rOffset = splitter.zero();
                        rSize = splitter.sizeOf(ranges.get(++ri));
                    }
                }
            }
            return result;
        }