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

Code before:
                "Read beyond last offset ({} > {}): file size = {}, info: {}",
                file_offset_of_buffer_end, *read_until_position, getFileSize(), impl->getInfoForLog());
        }
    }

    return true;
}

std::future<IAsynchronousReader::Result> AsynchronousBoundedReadBuffer::readAsync(char * data, size_t size, Priority priority)
{
    if (use_page_cache)
        assert(data == nullptr);
    IAsynchronousReader::Request request;
    request.descriptor = std::make_shared<RemoteFSFileDescriptor>(*impl, async_read_counters);
    request.buf = data;
    request.size = size;
    request.offset = file_offset_of_buffer_end;
    request.priority = Priority{read_settings.priority.value + priority.value};
    request.ignore = bytes_to_ignore;
    return reader.submit(request);
}

IAsynchronousReader::Result AsynchronousBoundedReadBuffer::readSync(char * data, size_t size)
{
    if (use_page_cache)
        assert(data == nullptr);
    IAsynchronousReader::Request request;
    request.descriptor = std::make_shared<RemoteFSFileDescriptor>(*impl, async_read_counters);
    request.buf = data;
    request.size = size;
    request.offset = file_offset_of_buffer_end;
    request.ignore = bytes_to_ignore;
    return reader.execute(request);
}

void AsynchronousBoundedReadBuffer::prefetch(Priority priority)
{
    if (prefetch_future.valid())
        return;

    if (!hasPendingDataToRead())
        return;

    last_prefetch_info.submit_time = std::chrono::system_clock::now();
    last_prefetch_info.priority = priority;

    if (!use_page_cache)
        prefetch_buffer.resize(buffer_size);
    prefetch_future = readAsync(prefetch_buffer.data(), buffer_size, priority);
    ProfileEvents::increment(ProfileEvents::RemoteFSPrefetches);
}

Review comment (bug):
```suggestion
        chassert(data == nullptr);
```

Code after:
        {
            /// 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());
        }
    }

    return true;
}

std::future<IAsynchronousReader::Result> AsynchronousBoundedReadBuffer::readAsync(char * data, size_t size, Priority priority)
{
    if (use_page_cache)
        chassert(data == nullptr);
    else
        chassert(data != nullptr);
    IAsynchronousReader::Request request;
    request.descriptor = std::make_shared<RemoteFSFileDescriptor>(*impl, async_read_counters);
    request.buf = data;
    request.size = size;
    request.offset = file_offset_of_buffer_end;
    request.priority = Priority{read_settings.priority.value + priority.value};
    request.ignore = bytes_to_ignore;
    return reader.submit(request);
}

IAsynchronousReader::Result AsynchronousBoundedReadBuffer::readSync(char * data, size_t size)
{
    if (use_page_cache)
        chassert(data == nullptr);
    else
        chassert(data != nullptr);
    IAsynchronousReader::Request request;
    request.descriptor = std::make_shared<RemoteFSFileDescriptor>(*impl, async_read_counters);
    request.buf = data;
    request.size = size;
    request.offset = file_offset_of_buffer_end;
    request.ignore = bytes_to_ignore;
    return reader.execute(request);
}

void AsynchronousBoundedReadBuffer::prefetch(Priority priority)
{
    if (prefetch_future.valid())
        return;

    if (!hasPendingDataToRead())