private CompletableFuture<List<Block>> getBlocks(long startOffset, long endOffset, int maxBytes,
        boolean readahead) {
        GetBlocksContext context = new GetBlocksContext(readahead);
        try {
            getBlocks0(context, startOffset, endOffset, maxBytes);
        } catch (Throwable ex) {
            context.cf.completeExceptionally(ex);
        }
        context.cf.exceptionally(ex -> {
            context.blocks.forEach(Block::release);
            return null;
        });
        return context.cf;
    }
This method is only for unit testing.
inflightReadaheadCf is empty, the task has been completed
inflightReadaheadCf is not empty, the task may be completed

@return readahead.inflightReadaheadCf
s3stream/src/main/java/com/automq/stream/s3/cache/blockcache/StreamReader.java