public List split()

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;
  }