package Salsa.Core; public final class RangePartitioner { public static Range[] Partition(int length, int numPartitions) { return Partition(0, length, numPartitions); } public static Range[] Partition(Range range, int numPartitions) { return Partition(range.StartIndex, range.getLength(), numPartitions); } public static Range[] Partition(int startIndex, int length, int numPartitions) { if (numPartitions < 1) { throw new IllegalArgumentException("count Partitioning requires numPartitions to be greater than zero."); } if (length < 1) { // throw new ArgumentOutOfRangeException("length", "Partitioning requires length to be greater than zero."); } if (length < numPartitions) { // throw new InvalidOperationException("Partitioning cannot be performed when length is less than numPartitions requested."); } Range[] ranges = new Range[numPartitions]; int chunksize = length / numPartitions; int remainder = length % numPartitions; for (int i = 0; i < numPartitions; i++) { if (remainder > 0) { ranges[i] = new Range(startIndex, startIndex + chunksize); startIndex += chunksize + 1; remainder--; } else { ranges[i] = new Range(startIndex, startIndex + chunksize - 1); startIndex += chunksize; } } return ranges; } public static Range[] PartitionByLength(int length, int maxPartitionLength) { return PartitionByLength(0, length, maxPartitionLength); } public static Range[] PartitionByLength(Range range, int maxPartitionLength) { return PartitionByLength(range.StartIndex, range.getLength(), maxPartitionLength); } public static Range[] PartitionByLength(int startIndex, int length, int maxPartitionLength) { if (maxPartitionLength < 1) { throw new IllegalArgumentException("maxPartitionLength Partitioning requires the maxPartitionLength to be greater than zero."); } if (length < 1) { throw new IllegalArgumentException("length Partitioning requires the length to be greater than zero."); } if (length < maxPartitionLength) { throw new IllegalArgumentException("length Partitioning requires the length to be greater than maxPartitionLength."); } int rangeCount = length / maxPartitionLength; int lastRangeLength = length % maxPartitionLength; if (lastRangeLength > 0) { rangeCount++; } else { lastRangeLength = maxPartitionLength; } Range[] ranges = new Range[rangeCount]; for (int i = 0; i < rangeCount; i++) { int start = i * maxPartitionLength; int end = (i == rangeCount - 1 ? start + lastRangeLength - 1 : start + maxPartitionLength - 1); ranges[i] = new Range(start, end); start += maxPartitionLength; } return ranges; } }