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
|
#include <Columns/ColumnCompressed.h>
#pragma clang diagnostic ignored "-Wold-style-cast"
#include <lz4.h>
namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_COMPRESS;
extern const int CANNOT_DECOMPRESS;
}
std::shared_ptr<Memory<>> ColumnCompressed::compressBuffer(const void * data, size_t data_size, bool always_compress)
{
size_t max_dest_size = LZ4_COMPRESSBOUND(data_size);
if (max_dest_size > std::numeric_limits<int>::max())
throw Exception(ErrorCodes::CANNOT_COMPRESS, "Cannot compress column of size {}", formatReadableSizeWithBinarySuffix(data_size));
Memory<> compressed(max_dest_size);
int compressed_size = LZ4_compress_default(
reinterpret_cast<const char *>(data),
compressed.data(),
static_cast<int>(data_size),
static_cast<int>(max_dest_size));
if (compressed_size <= 0)
throw Exception(ErrorCodes::CANNOT_COMPRESS, "Cannot compress column");
/// If compression is inefficient.
if (!always_compress && static_cast<size_t>(compressed_size) * 2 > data_size)
return {};
/// Shrink to fit.
auto shrank = std::make_shared<Memory<>>(compressed_size);
memcpy(shrank->data(), compressed.data(), compressed_size);
return shrank;
}
void ColumnCompressed::decompressBuffer(
const void * compressed_data, void * decompressed_data, size_t compressed_size, size_t decompressed_size)
{
auto processed_size = LZ4_decompress_safe(
reinterpret_cast<const char *>(compressed_data),
reinterpret_cast<char *>(decompressed_data),
static_cast<int>(compressed_size),
static_cast<int>(decompressed_size));
if (processed_size <= 0)
throw Exception(ErrorCodes::CANNOT_DECOMPRESS, "Cannot decompress column");
}
}
|