aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/IO/BoundedReadBuffer.cpp
blob: bda79d82ad3cb1b1f9be5eea2809fd92ae0209ad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include "BoundedReadBuffer.h"
#include <IO/SwapHelper.h>

namespace DB
{

BoundedReadBuffer::BoundedReadBuffer(std::unique_ptr<SeekableReadBuffer> impl_)
    : ReadBufferFromFileDecorator(std::move(impl_))
{
}

void BoundedReadBuffer::setReadUntilPosition(size_t position)
{
    read_until_position = position;
}

void BoundedReadBuffer::setReadUntilEnd()
{
    read_until_position.reset();
}

off_t BoundedReadBuffer::getPosition()
{
    return file_offset_of_buffer_end - (working_buffer.end() - pos);
}

bool BoundedReadBuffer::nextImpl()
{
    if (read_until_position && file_offset_of_buffer_end == *read_until_position)
        return false;

    bool result;
    {
        SwapHelper swap(*this, *impl);
        result = impl->next();
    }
    chassert(file_offset_of_buffer_end + available() == impl->getFileOffsetOfBufferEnd());
    if (result && read_until_position)
    {
        size_t remaining_size_to_read = *read_until_position - file_offset_of_buffer_end;
        if (working_buffer.size() > remaining_size_to_read)
        {
            ///  file:            [______________________________]
            ///  working buffer:       [_______________]
            ///                                 ^
            ///                                 read_until_position
            ///                        ^
            ///                        file_offset_of_buffer_end
            working_buffer.resize(remaining_size_to_read);
        }
    }
    file_offset_of_buffer_end += available();
    return result;
}

off_t BoundedReadBuffer::seek(off_t off, int whence)
{
    swap(*impl);
    auto result = impl->seek(off, whence);
    swap(*impl);

    file_offset_of_buffer_end = impl->getFileOffsetOfBufferEnd();
    return result;
}

}