Repository: ClickHouse/ClickHouse
File: src/Disks/IO/AsynchronousBoundedReadBuffer.cpp (C++)

Code before:
    AsyncReadCountersPtr async_read_counters_,
    FilesystemReadPrefetchesLogPtr prefetches_log_)
    : ReadBufferFromFileBase(0, nullptr, 0, impl_->getFileSize())
    , impl(std::move(impl_))
    , read_settings(settings_)
    , buffer_size(buffer_size_)
    , min_bytes_for_seek(min_bytes_for_seek_)
    /// Avoid calling thread-unsafe impl->getFileName() while prefetch is in progress.
    /// If impl's getFileName() can change on the fly, our getFileName() won't reflect that.
    /// That is ok, it's not used for anything important.
    , file_name(impl->getFileName())
    , reader(reader_)
    , query_id(CurrentThread::isInitialized() && CurrentThread::get().getQueryContext() != nullptr ? CurrentThread::getQueryId() : "")
    , current_reader_id(getRandomASCIIString(8))
    , log(getLogger("AsynchronousBoundedReadBuffer"))
    , async_read_counters(async_read_counters_)
    , prefetches_log(prefetches_log_)
{
    ProfileEvents::increment(ProfileEvents::RemoteFSBuffers);

    const auto * cached_impl = typeid_cast<const CachedInMemoryReadBufferFromFile *>(impl.get());
    if (cached_impl)
    {
        use_page_cache = true;
        buffer_size = cached_impl->getPageCache()->defaultBlockSize();
    }
}

String AsynchronousBoundedReadBuffer::getInfoForLog()
{
    if (prefetch_future.valid())
        prefetch_future.wait();
    return impl->getInfoForLog();
}

bool AsynchronousBoundedReadBuffer::hasPendingDataToRead()
{
    if (read_until_position)
    {
        if (file_offset_of_buffer_end == *read_until_position) /// Everything is already read.
            return false;

        if (file_offset_of_buffer_end > *read_until_position)
        {
            /// Avoid race condition on impl->getInfoForLog().
            if (prefetch_future.valid())
                prefetch_future.wait();
            throw Exception(
                ErrorCodes::LOGICAL_ERROR,
                "Read beyond last offset ({} > {}): file size = {}, info: {}",
                file_offset_of_buffer_end, *read_until_position, getFileSize(), impl->getInfoForLog());

Review comment (performance):
```suggestion
        buffer_size = cached_impl->getPageCache()->defaultBlockSize();
    }
    LOG_TEST(log, "Using buffer size {} while reading {}", buffer_size, file_name);
```

Code after:
    size_t buffer_size_,
    size_t min_bytes_for_seek_,
    AsyncReadCountersPtr async_read_counters_,
    FilesystemReadPrefetchesLogPtr prefetches_log_)
    : ReadBufferFromFileBase(0, nullptr, 0, impl_->getFileSize())
    , impl(std::move(impl_))
    , read_settings(settings_)
    , buffer_size(buffer_size_)
    , min_bytes_for_seek(min_bytes_for_seek_)
    /// Avoid calling thread-unsafe impl->getFileName() while prefetch is in progress.
    /// If impl's getFileName() can change on the fly, our getFileName() won't reflect that.
    /// That is ok, it's not used for anything important.
    , file_name(impl->getFileName())
    , reader(reader_)
    , query_id(CurrentThread::isInitialized() && CurrentThread::get().getQueryContext() != nullptr ? CurrentThread::getQueryId() : "")
    , current_reader_id(getRandomASCIIString(8))
    , log(getLogger("AsynchronousBoundedReadBuffer"))
    , async_read_counters(async_read_counters_)
    , prefetches_log(prefetches_log_)
{
    ProfileEvents::increment(ProfileEvents::RemoteFSBuffers);

    const auto * cached_impl = typeid_cast<const CachedInMemoryReadBufferFromFile *>(impl.get());
    if (cached_impl)
    {
        use_page_cache = true;
        buffer_size = read_settings.page_cache_block_size;
    }
    LOG_TEST(log, "Using buffer size {} while reading {}", buffer_size, file_name);

    if (buffer_size == 0)
        throw Exception(ErrorCodes::BAD_ARGUMENTS, "Buffer size cannot be zero");
}

String AsynchronousBoundedReadBuffer::getInfoForLog()
{
    if (prefetch_future.valid())
        prefetch_future.wait();
    return impl->getInfoForLog();
}

bool AsynchronousBoundedReadBuffer::hasPendingDataToRead()
{
    if (read_until_position)
    {
        if (file_offset_of_buffer_end == *read_until_position) /// Everything is already read.
            return false;

        if (file_offset_of_buffer_end > *read_until_position)
        {
            /// Avoid race condition on impl->getInfoForLog().