in s3-artifact-storage-agent/src/main/java/jetbrains/buildServer/artifacts/s3/download/parallel/splitter/impl/FileSplitterImpl.java [24:73]
public List<FilePart> split(long fileSize) {
if (fileSize <= 0) throw new IllegalArgumentException("File size is not positive: " + fileSize);
final int maxThreads = myConfiguration.getMaxThreads();
if (fileSize < getSplitThreshold() || maxThreads == 1) {
// unsplittable, return one part
return Collections.singletonList(new FilePart(0, 0, fileSize - 1));
}
List<FilePart> parts = new ArrayList<>();
final long minPartSize = myConfiguration.getMinPartSizeBytes();
final long partSize;
if (fileSize < maxThreads * minPartSize) {
// from 2 to maxThreads parts of size = minPartSize except, possibly, the last
partSize = minPartSize;
long residualSize = fileSize % partSize;
int fullParts = (int)(fileSize / partSize); // fileSize / partSize < maxThreads, safe to case to int
boolean extendLastFullPart = residualSize < myConfiguration.getMinPartSizeLowerBoundBytes(); // don't create new part for too few bytes, extend the last full part
for (int partNumber = 0; partNumber < fullParts - 1; partNumber++) {
long startByte = partSize * partNumber;
long endByte = startByte + partSize - 1;
parts.add(new FilePart(partNumber, startByte, endByte));
}
int lastFullPartNumber = fullParts - 1;
long lastFullPartStartByte = partSize * lastFullPartNumber;
long lastFullPartEndByte = extendLastFullPart ? fileSize - 1 : lastFullPartStartByte + partSize - 1;
parts.add(new FilePart(lastFullPartNumber, lastFullPartStartByte, lastFullPartEndByte));
if (!extendLastFullPart && residualSize > 0) {
int lastPartNumber = lastFullPartNumber + 1;
long lastPartStartByte = partSize * lastPartNumber;
long lastPartEndByte = fileSize - 1;
parts.add(new FilePart(lastPartNumber, lastPartStartByte, lastPartEndByte));
}
} else {
// maxThreads parts of size >= minPartSize
partSize = fileSize / maxThreads;
for (int partNumber = 0; partNumber < maxThreads; partNumber++) {
long startByte = partSize * partNumber;
long endByte = partNumber != maxThreads - 1 ? startByte + partSize - 1 : fileSize - 1;
parts.add(new FilePart(partNumber, startByte, endByte));
}
}
return parts;
}