2010-06-04 18:25:25 +00:00
|
|
|
#ifndef DBMS_COMMON_COMPRESSED_WRITEBUFFER_H
|
|
|
|
#define DBMS_COMMON_COMPRESSED_WRITEBUFFER_H
|
|
|
|
|
2011-06-24 20:18:09 +00:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <city.h>
|
2011-06-17 21:19:39 +00:00
|
|
|
#include <quicklz/quicklz_level1.h>
|
2010-06-04 18:25:25 +00:00
|
|
|
|
|
|
|
#include <DB/IO/WriteBuffer.h>
|
2011-06-27 18:22:14 +00:00
|
|
|
#include <DB/IO/BufferWithOwnMemory.h>
|
2011-06-17 21:19:39 +00:00
|
|
|
#include <DB/IO/CompressedStream.h>
|
2010-06-04 18:25:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2011-06-27 18:22:14 +00:00
|
|
|
class CompressedWriteBuffer : public BufferWithOwnMemory<WriteBuffer>
|
2010-06-04 18:25:25 +00:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
WriteBuffer & out;
|
|
|
|
|
2011-06-24 20:18:09 +00:00
|
|
|
std::vector<char> compressed_buffer;
|
2011-06-17 21:19:39 +00:00
|
|
|
char scratch[QLZ_SCRATCH_COMPRESS];
|
|
|
|
|
2011-06-24 21:08:26 +00:00
|
|
|
void nextImpl()
|
2010-06-04 18:25:25 +00:00
|
|
|
{
|
2011-06-27 19:34:03 +00:00
|
|
|
if (!offset())
|
|
|
|
return;
|
|
|
|
|
2011-06-27 18:22:14 +00:00
|
|
|
size_t uncompressed_size = offset();
|
2011-06-24 20:18:09 +00:00
|
|
|
compressed_buffer.resize(uncompressed_size + QUICKLZ_ADDITIONAL_SPACE);
|
2011-06-26 21:30:59 +00:00
|
|
|
|
2011-06-17 21:19:39 +00:00
|
|
|
size_t compressed_size = qlz_compress(
|
2011-05-13 19:40:56 +00:00
|
|
|
working_buffer.begin(),
|
2011-06-24 20:18:09 +00:00
|
|
|
&compressed_buffer[0],
|
|
|
|
uncompressed_size,
|
2011-06-17 21:19:39 +00:00
|
|
|
scratch);
|
2010-06-04 18:25:25 +00:00
|
|
|
|
2011-06-24 20:18:09 +00:00
|
|
|
uint128 checksum = CityHash128(&compressed_buffer[0], compressed_size);
|
|
|
|
out.write(reinterpret_cast<const char *>(&checksum), sizeof(checksum));
|
|
|
|
|
|
|
|
out.write(&compressed_buffer[0], compressed_size);
|
2011-05-05 19:10:17 +00:00
|
|
|
}
|
|
|
|
|
2011-06-26 21:30:59 +00:00
|
|
|
public:
|
2011-06-30 15:21:35 +00:00
|
|
|
CompressedWriteBuffer(WriteBuffer & out_) : out(out_) {}
|
2011-06-26 21:30:59 +00:00
|
|
|
|
2011-06-24 21:08:26 +00:00
|
|
|
/// Объём сжатых данных
|
2011-05-05 19:10:17 +00:00
|
|
|
size_t getCompressedBytes()
|
|
|
|
{
|
|
|
|
nextIfAtEnd();
|
2011-06-30 15:21:35 +00:00
|
|
|
return out.count();
|
2011-05-05 19:10:17 +00:00
|
|
|
}
|
|
|
|
|
2011-05-11 17:27:08 +00:00
|
|
|
/// Сколько несжатых байт было записано в буфер
|
2011-05-05 19:10:17 +00:00
|
|
|
size_t getUncompressedBytes()
|
2011-05-11 17:27:08 +00:00
|
|
|
{
|
|
|
|
return count();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Сколько байт находится в буфере (ещё не сжато)
|
|
|
|
size_t getRemainingBytes()
|
2011-05-05 19:10:17 +00:00
|
|
|
{
|
|
|
|
nextIfAtEnd();
|
2011-06-30 15:21:35 +00:00
|
|
|
return offset();
|
2010-06-04 18:25:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
~CompressedWriteBuffer()
|
|
|
|
{
|
2011-12-12 00:38:01 +00:00
|
|
|
bool uncaught_exception = std::uncaught_exception();
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2011-12-12 01:06:13 +00:00
|
|
|
next();
|
2011-12-12 00:38:01 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
/// Если до этого уже было какое-то исключение, то второе исключение проигнорируем.
|
|
|
|
if (!uncaught_exception)
|
|
|
|
throw;
|
|
|
|
}
|
2010-06-04 18:25:25 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|