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

Code before:

        ProfileEvents::increment(ProfileEvents::RemoteFSPrefetchedReads);
        ProfileEvents::increment(ProfileEvents::RemoteFSPrefetchedBytes, result.size);
    }
    else
    {
        memory.resize(buffer_size);

        {
            ProfileEventTimeIncrement<Microseconds> watch(ProfileEvents::SynchronousRemoteReadWaitMicroseconds);
            result = readSync(memory.data(), buffer_size);
        }

        ProfileEvents::increment(ProfileEvents::RemoteFSUnprefetchedReads);
        ProfileEvents::increment(ProfileEvents::RemoteFSUnprefetchedBytes, result.size);
    }

    bytes_to_ignore = 0;
    resetWorkingBuffer();

    size_t bytes_read = result.size - result.offset;
    if (bytes_read)
    {
        if (use_page_cache)
        {
            page_cache_cell = result.page_cache_cell;
            internal_buffer = Buffer(page_cache_cell->data(), page_cache_cell->data() + page_cache_cell->size());
        }
        else
        {
            internal_buffer = Buffer(memory.data(), memory.data() + memory.size());
        }

        /// Adjust the working buffer so that it ignores `offset` bytes.
        working_buffer = Buffer(internal_buffer.begin() + result.offset, internal_buffer.begin() + result.size);
        pos = working_buffer.begin();
    }

    file_offset_of_buffer_end = impl->getFileOffsetOfBufferEnd();

    chassert(file_offset_of_buffer_end <= getFileSize());

    if (read_until_position && (file_offset_of_buffer_end > *read_until_position))
    {
        size_t excessive_bytes_read = file_offset_of_buffer_end - *read_until_position;

        if (excessive_bytes_read > working_buffer.size())
            throw Exception(ErrorCodes::LOGICAL_ERROR,
                            "File offset moved too far: old_file_offset = {}, new_file_offset = {}, read_until_position = {}, bytes_read = {}",
                            old_file_offset_of_buffer_end, file_offset_of_buffer_end, *read_until_position, bytes_read);


Review comment (performance):
[Not sure if it makes much sense but] 
It seems if we add `data` (or better named like `data_begin` or `data_without_offset`) parameter to `IAsynchronousReader::Result result`, which will be set by `ThreadPoolRemoteFSReader` to proper value (in case of page cache and without it), then we can unify both cases and get rid of explicit `use_page_cache` check and remove `page_cache_cell` from `IAsynchronousReader::Result result`, and so it will look like:
```
internal_buffer = Buffer(result.data_without_offset, result.data_without_offset + buffer_size);
working_buffer = Buffer(internal_buffer.begin() + result.offset, internal_buffer.begin() + result.size);
```
(here we know that `buffer_size == page_cache_cell->size()` as I understand, so we can substitute)

Code after:
            CurrentMetrics::Increment metric_increment{CurrentMetrics::AsynchronousReadWait};

            result = prefetch_future.get();
        }

        prefetch_future = {};
        prefetch_buffer.swap(memory);

        if (read_settings.enable_filesystem_read_prefetches_log)
            appendToPrefetchLog(FilesystemPrefetchState::USED, result.size, result.execution_watch);

        last_prefetch_info = {};

        ProfileEvents::increment(ProfileEvents::RemoteFSPrefetchedReads);
        ProfileEvents::increment(ProfileEvents::RemoteFSPrefetchedBytes, result.size);
    }
    else
    {
        /// Don't allocate any buffers if page cache is in use, the cache has its own buffers (PageCacheCell).
        if (!use_page_cache)
            memory.resize(buffer_size);

        {
            ProfileEventTimeIncrement<Microseconds> watch(ProfileEvents::SynchronousRemoteReadWaitMicroseconds);
            result = readSync(memory.data(), buffer_size);
        }

        ProfileEvents::increment(ProfileEvents::RemoteFSUnprefetchedReads);
        ProfileEvents::increment(ProfileEvents::RemoteFSUnprefetchedBytes, result.size);
    }

    bytes_to_ignore = 0;
    resetWorkingBuffer();

    chassert(use_page_cache || !result.page_cache_cell);

    size_t bytes_read = result.size - result.offset;
    if (bytes_read)
    {
        page_cache_cell = result.page_cache_cell;
        working_buffer = Buffer(result.buf + result.offset, result.buf + result.size);
        pos = working_buffer.begin();
    }

    file_offset_of_buffer_end = result.file_offset_of_buffer_end;

    chassert(file_offset_of_buffer_end <= getFileSize());

    if (read_until_position && (file_offset_of_buffer_end > *read_until_position))
    {
        size_t excessive_bytes_read = file_offset_of_buffer_end - *read_until_position;