public FetchDataInfo read(long startOffset, int maxSize, Optional<Long> maxPositionOpt, boolean minOneMessage) throws IOException {
        if (maxSize < 0)
            throw new IllegalArgumentException("Invalid max size " + maxSize + " for log read from segment " + log);

        LogOffsetPosition startOffsetAndSize = translateOffset(startOffset);

        // if the start position is already off the end of the log, return null
        if (startOffsetAndSize == null)
            return null;

        int startPosition = startOffsetAndSize.position;
        LogOffsetMetadata offsetMetadata = new LogOffsetMetadata(startOffset, this.baseOffset, startPosition);

        int adjustedMaxSize = maxSize;
        if (minOneMessage)
            adjustedMaxSize = Math.max(maxSize, startOffsetAndSize.size);

        // return empty records in the fetch-data-info when:
        // 1. adjustedMaxSize is 0 (or)
        // 2. maxPosition to read is unavailable
        if (adjustedMaxSize == 0 || !maxPositionOpt.isPresent())
            return new FetchDataInfo(offsetMetadata, MemoryRecords.EMPTY);

        // calculate the length of the message set to read based on whether or not they gave us a maxOffset
        int fetchSize = Math.min((int) (maxPositionOpt.get() - startPosition), adjustedMaxSize);

        return new FetchDataInfo(offsetMetadata, log.slice(startPosition, fetchSize),
            adjustedMaxSize < startOffsetAndSize.size, Optional.empty());
    }
Read a message set from this segment beginning with the first offset >= startOffset. The message set will include
no more than maxSize bytes and will end before maxOffset if a maxOffset is specified.

This method is thread-safe.

@param startOffset A lower bound on the first offset to include in the message set we read
@param maxSize The maximum number of bytes to include in the message set we read
@param maxPositionOpt The maximum position in the log segment that should be exposed for read
@param minOneMessage If this is true, the first message will be returned even if it exceeds `maxSize` (if one exists)

@return The fetched data and the offset metadata of the first message whose offset is >= startOffset,
        or null if the startOffset is larger than the largest offset in this log
storage/src/main/java/org/apache/kafka/storage/internals/log/LogSegment.java