ClickHouse/dbms/include/DB/IO/CompressedReadBuffer.h
2014-07-22 14:35:44 +04:00

88 lines
2.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <DB/IO/CompressedReadBufferBase.h>
namespace DB
{
class CompressedReadBuffer : public CompressedReadBufferBase, public BufferWithOwnMemory<ReadBuffer>
{
private:
size_t size_compressed = 0;
size_t currentBlockCompressedSize() const
{
return size_compressed;
}
bool nextImpl()
{
size_t size_decompressed;
size_compressed = readCompressedData(size_decompressed);
if (!size_compressed)
return false;
memory.resize(size_decompressed);
working_buffer = Buffer(&memory[0], &memory[size_decompressed]);
decompress(working_buffer.begin(), size_decompressed);
return true;
}
public:
CompressedReadBuffer(ReadBuffer & in_)
: CompressedReadBufferBase(&in_), BufferWithOwnMemory<ReadBuffer>(0)
{
}
size_t readBig(char * to, size_t n)
{
size_t bytes_read = 0;
/// Если в буфере есть непрочитанные байты, то скопируем сколько надо в to.
if (pos < working_buffer.end())
bytes_read += read(to, std::min(static_cast<size_t>(working_buffer.end() - pos), n));
/// Если надо ещё прочитать - будем, по возможности, разжимать сразу в to.
while (bytes_read < n)
{
size_t size_decompressed;
if (!readCompressedData(size_decompressed))
return bytes_read;
/// Если разжатый блок помещается целиком туда, куда его надо скопировать.
if (size_decompressed <= n - bytes_read)
{
decompress(to + bytes_read, size_decompressed);
bytes_read += size_decompressed;
bytes += size_decompressed;
}
else
{
bytes += offset();
memory.resize(size_decompressed);
working_buffer = Buffer(&memory[0], &memory[size_decompressed]);
pos = working_buffer.begin();
decompress(working_buffer.begin(), size_decompressed);
bytes_read += read(to + bytes_read, n - bytes_read);
break;
}
}
return bytes_read;
}
/// Сжатый размер текущего блока.
size_t getSizeCompressed() const
{
return size_compressed;
}
};
}