Repository: ClickHouse/ClickHouse
File: src/IO/AsynchronousReader.h (C/C++)

Code before:
    };

    struct Result
    {
        /// The read data is at [buf + offset, buf + size).
        /// (Notice that `offset` is included in `size`.)
        /// offset is equal to request.ignore.
        /// buf is either the buf from Request or inside page_cache_cell's buffer,
        /// or nullptr if size = 0.
        /// Less than requested amount of data can be returned.
        /// If size is zero - the file has ended.
        /// (for example, EINTR must be handled by implementation automatically)
        char * buf = nullptr;
        size_t size = 0;
        size_t offset = 0;

        PageCacheCellPtr page_cache_cell = {};

        std::unique_ptr<Stopwatch> execution_watch = {};
    };

    /// Submit request and obtain a handle. This method don't perform any waits.
    /// If this method did not throw, the caller must wait for the result with 'wait' method
    /// or destroy the whole reader before destroying the buffer for request.
    /// The method can be called concurrently from multiple threads.
    virtual std::future<Result> submit(Request request) = 0;
    virtual Result execute(Request request) = 0;

    virtual void wait() = 0;

    /// Destructor must wait for all not completed request and ignore the results.
    /// It may also cancel the requests.
    virtual ~IAsynchronousReader() = default;
};

using AsynchronousReaderPtr = std::shared_ptr<IAsynchronousReader>;

}


Review comment (performance):
As `page_cache_cell` does not seem to be used anyhow in `AsynchronousBoundedReadBuffer` then we can remove it from here as well

Code after:
        /// AsynchronousBoundedReadBuffer may set ignore >= size, so it should only be used with
        /// implementations that don't require that.
        size_t ignore = 0;
        bool direct_io = false;
    };

    struct Result
    {
        /// The read data is at [buf + offset, buf + size).
        /// (Notice that `offset` is included in `size`.)
        /// buf is either the buf from Request or inside page_cache_cell's buffer,
        /// or nullptr if size = 0.
        /// Less than requested amount of data can be returned.
        /// If size is zero - the file has ended.
        /// (for example, EINTR must be handled by implementation automatically)
        char * buf = nullptr;
        size_t size = 0;
        size_t offset = 0;

        /// File offset corresponding to `buf + size`. Equal to:
        /// request.offset + request.ignore + (result.size - result.offset)
        size_t file_offset_of_buffer_end = 0;

        /// If not null, `buf` points into it, so this shared_ptr must be kept alive for as long
        /// as `buf` is in use.
        PageCacheCellPtr page_cache_cell = {};

        std::unique_ptr<Stopwatch> execution_watch = {};
    };

    /// Submit request and obtain a handle. This method don't perform any waits.
    /// If this method did not throw, the caller must wait for the result with 'wait' method
    /// or destroy the whole reader before destroying the buffer for request.
    /// The method can be called concurrently from multiple threads.
    virtual std::future<Result> submit(Request request) = 0;
    virtual Result execute(Request request) = 0;

    virtual void wait() = 0;

    /// Destructor must wait for all not completed request and ignore the results.
    /// It may also cancel the requests.
    virtual ~IAsynchronousReader() = default;
};

using AsynchronousReaderPtr = std::shared_ptr<IAsynchronousReader>;

}