#ifndef DBMS_COMMON_COMPRESSED_READBUFFER_H #define DBMS_COMMON_COMPRESSED_READBUFFER_H #include #include #include #include #include #include namespace DB { class CompressedReadBuffer : public ReadBuffer { private: ReadBuffer & in; std::vector compressed_buffer; std::vector decompressed_buffer; char scratch[QLZ_SCRATCH_COMPRESS]; size_t pos_in_buffer; public: CompressedReadBuffer(ReadBuffer & in_) : in(in_), compressed_buffer(QUICKLZ_HEADER_SIZE), pos_in_buffer(0) { } /** Читает и разжимает следующий кусок сжатых данных. */ void readCompressedChunk() { in.readStrict(&compressed_buffer[0], QUICKLZ_HEADER_SIZE); size_t size_compressed = qlz_size_compressed(internal_buffer); size_t size_decompressed = qlz_size_decompressed(internal_buffer); compressed_buffer.resize(size_compressed); decompressed_buffer.resize(size_decompressed); in.readStrict(&compressed_buffer[QUICKLZ_HEADER_SIZE], size_compressed - QUICKLZ_HEADER_SIZE); pos_in_buffer = 0; } bool next() { if (pos_in_buffer == decompressed_buffer.size()) { if (in.eof()) return false; readCompressedChunk(); } size_t bytes_to_copy = std::min(decompressed_buffer.size() - pos_in_buffer, static_cast(DEFAULT_READ_BUFFER_SIZE)); std::memcpy(internal_buffer, &decompressed_buffer[pos_in_buffer], bytes_to_copy); pos = internal_buffer; working_buffer = Buffer(internal_buffer, internal_buffer + bytes_to_copy); return true; } }; } #endif