aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/blockcodecs/codecs/lz4/lz4.cpp
blob: 7ece0ad448c3da7de1f55f3a5361683fd9f6dadb (plain) (blame)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <library/cpp/blockcodecs/core/codecs.h>
#include <library/cpp/blockcodecs/core/common.h>
#include <library/cpp/blockcodecs/core/register.h>
 
#include <contrib/libs/lz4/lz4.h> 
#include <contrib/libs/lz4/lz4hc.h> 
#include <contrib/libs/lz4/generated/iface.h> 
 
using namespace NBlockCodecs; 
 
namespace { 
    struct TLz4Base { 
        static inline size_t DoMaxCompressedLength(size_t in) { 
            return LZ4_compressBound(SafeIntegerCast<int>(in)); 
        } 
    }; 
 
    struct TLz4FastCompress { 
        inline TLz4FastCompress(int memory) 
            : Memory(memory) 
            , Methods(LZ4Methods(Memory)) 
        { 
        } 
 
        inline size_t DoCompress(const TData& in, void* buf) const { 
            return Methods->LZ4CompressLimited(in.data(), (char*)buf, in.size(), LZ4_compressBound(in.size())); 
        } 
 
        inline TString CPrefix() { 
            return "fast" + ToString(Memory); 
        } 
 
        const int Memory; 
        const TLZ4Methods* Methods; 
    }; 
 
    struct TLz4BestCompress { 
        inline size_t DoCompress(const TData& in, void* buf) const { 
            return LZ4_compress_HC(in.data(), (char*)buf, in.size(), LZ4_compressBound(in.size()), 0); 
        } 
 
        static inline TString CPrefix() { 
            return "hc"; 
        } 
    }; 
 
    struct TLz4FastDecompress { 
        inline void DoDecompress(const TData& in, void* out, size_t len) const { 
            ssize_t res = LZ4_decompress_fast(in.data(), (char*)out, len); 
            if (res < 0) { 
                ythrow TDecompressError(res); 
            } 
        } 
 
        static inline TStringBuf DPrefix() { 
            return TStringBuf("fast");
        } 
    }; 
 
    struct TLz4SafeDecompress { 
        inline void DoDecompress(const TData& in, void* out, size_t len) const { 
            ssize_t res = LZ4_decompress_safe(in.data(), (char*)out, in.size(), len); 
            if (res < 0) { 
                ythrow TDecompressError(res); 
            } 
        } 
 
        static inline TStringBuf DPrefix() { 
            return TStringBuf("safe");
        } 
    }; 
 
    template <class TC, class TD> 
    struct TLz4Codec: public TAddLengthCodec<TLz4Codec<TC, TD>>, public TLz4Base, public TC, public TD { 
        inline TLz4Codec() 
            : MyName("lz4-" + TC::CPrefix() + "-" + TD::DPrefix()) 
        { 
        } 
 
        template <class T> 
        inline TLz4Codec(const T& t) 
            : TC(t) 
            , MyName("lz4-" + TC::CPrefix() + "-" + TD::DPrefix()) 
        { 
        } 
 
        TStringBuf Name() const noexcept override { 
            return MyName; 
        } 
 
        const TString MyName; 
    }; 
 
    struct TLz4Registrar { 
        TLz4Registrar() { 
            for (int i = 0; i < 30; ++i) { 
                typedef TLz4Codec<TLz4FastCompress, TLz4FastDecompress> T1; 
                typedef TLz4Codec<TLz4FastCompress, TLz4SafeDecompress> T2; 
 
                THolder<T1> t1(new T1(i)); 
                THolder<T2> t2(new T2(i)); 
 
                if (t1->Methods) { 
                    RegisterCodec(std::move(t1));
                } 
 
                if (t2->Methods) { 
                    RegisterCodec(std::move(t2));
                } 
            } 
 
            RegisterCodec(MakeHolder<TLz4Codec<TLz4BestCompress, TLz4FastDecompress>>());
            RegisterCodec(MakeHolder<TLz4Codec<TLz4BestCompress, TLz4SafeDecompress>>());
 
            RegisterAlias("lz4-fast-safe", "lz4-fast14-safe"); 
            RegisterAlias("lz4-fast-fast", "lz4-fast14-fast"); 
            RegisterAlias("lz4", "lz4-fast-safe"); 
            RegisterAlias("lz4fast", "lz4-fast-fast"); 
            RegisterAlias("lz4hc", "lz4-hc-safe"); 
        } 
    }; 
    const TLz4Registrar Registrar{};
}