private void mergedRangeRead0(ReadOptions options, String path, long start, long end,
        CompletableFuture<ByteBuf> cf) {
        TimerUtil timerUtil = new TimerUtil();
        long size = end - start;
        doRangeRead(options, path, start, end).thenAccept(buf -> {
            // the end may be RANGE_READ_TO_END (-1) for read all object
            long dataSize = buf.readableBytes();
            if (logger.isDebugEnabled()) {
                logger.debug("GetObject for object {} [{}, {}), size: {}, cost: {} ms",
                    path, start, end, dataSize, timerUtil.elapsedAs(TimeUnit.MILLISECONDS));
            }
            S3OperationStats.getInstance().downloadSizeTotalStats.add(MetricsLevel.INFO, dataSize);
            S3OperationStats.getInstance().getObjectStats(dataSize, true).record(timerUtil.elapsedAs(TimeUnit.NANOSECONDS));
            cf.complete(buf);
        }).exceptionally(ex -> {
            Pair<RetryStrategy, Throwable> strategyAndCause = toRetryStrategyAndCause(ex, S3Operation.GET_OBJECT);
            RetryStrategy retryStrategy = strategyAndCause.getLeft();
            Throwable cause = strategyAndCause.getRight();
            if (retryStrategy == RetryStrategy.ABORT || checkS3ApiMode) {
                if (!(cause instanceof ObjectNotExistException)) {
                    logger.error("GetObject for object {} [{}, {}) fail", path, start, end, cause);
                }
                cf.completeExceptionally(cause);
            } else {
                int delay = retryDelay(S3Operation.GET_OBJECT, options.retryCountGetAndAdd());
                logger.warn("GetObject for object {} [{}, {}) fail, retry in {}ms", path, start, end, delay, cause);
                scheduler.schedule(() -> mergedRangeRead0(options, path, start, end, cf), delay, TimeUnit.MILLISECONDS);
            }
            S3OperationStats.getInstance().getObjectStats(size, false).record(timerUtil.elapsedAs(TimeUnit.NANOSECONDS));
            return null;
        });
    }
Get adjacent read tasks and merge them into one read task which read range is not exceed 16MB.
s3stream/src/main/java/com/automq/stream/s3/operator/AbstractObjectStorage.java