1#include "CompressedReadBuffer.h"
2#include <Compression/CompressionInfo.h>
3#include <Compression/LZ4_decompress_faster.h>
4
5
6namespace DB
7{
8
9bool CompressedReadBuffer::nextImpl()
10{
11 size_t size_decompressed;
12 size_t size_compressed_without_checksum;
13 size_compressed = readCompressedData(size_decompressed, size_compressed_without_checksum);
14 if (!size_compressed)
15 return false;
16
17 memory.resize(size_decompressed + codec->getAdditionalSizeAtTheEndOfBuffer());
18 working_buffer = Buffer(memory.data(), &memory[size_decompressed]);
19
20 decompress(working_buffer.begin(), size_decompressed, size_compressed_without_checksum);
21
22 return true;
23}
24
25size_t CompressedReadBuffer::readBig(char * to, size_t n)
26{
27 size_t bytes_read = 0;
28
29 /// If there are unread bytes in the buffer, then we copy necessary to `to`.
30 if (pos < working_buffer.end())
31 bytes_read += read(to, std::min(static_cast<size_t>(working_buffer.end() - pos), n));
32
33 /// If you need to read more - we will, if possible, uncompress at once to `to`.
34 while (bytes_read < n)
35 {
36 size_t size_decompressed;
37 size_t size_compressed_without_checksum;
38
39 if (!readCompressedData(size_decompressed, size_compressed_without_checksum))
40 return bytes_read;
41
42 /// If the decompressed block is placed entirely where it needs to be copied.
43 if (size_decompressed + codec->getAdditionalSizeAtTheEndOfBuffer() <= n - bytes_read)
44 {
45 decompress(to + bytes_read, size_decompressed, size_compressed_without_checksum);
46 bytes_read += size_decompressed;
47 bytes += size_decompressed;
48 }
49 else
50 {
51 bytes += offset();
52 memory.resize(size_decompressed + codec->getAdditionalSizeAtTheEndOfBuffer());
53 working_buffer = Buffer(memory.data(), &memory[size_decompressed]);
54 pos = working_buffer.begin();
55
56 decompress(working_buffer.begin(), size_decompressed, size_compressed_without_checksum);
57
58 bytes_read += read(to + bytes_read, n - bytes_read);
59 break;
60 }
61 }
62
63 return bytes_read;
64}
65
66}
67