aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/blockcodecs/codecs
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/blockcodecs/codecs
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/blockcodecs/codecs')
-rw-r--r--library/cpp/blockcodecs/codecs/brotli/brotli.cpp67
-rw-r--r--library/cpp/blockcodecs/codecs/brotli/ya.make15
-rw-r--r--library/cpp/blockcodecs/codecs/bzip/bzip.cpp62
-rw-r--r--library/cpp/blockcodecs/codecs/bzip/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/fastlz/fastlz.cpp54
-rw-r--r--library/cpp/blockcodecs/codecs/fastlz/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/legacy_zstd06/legacy_zstd06.cpp58
-rw-r--r--library/cpp/blockcodecs/codecs/legacy_zstd06/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/lz4/lz4.cpp123
-rw-r--r--library/cpp/blockcodecs/codecs/lz4/ya.make15
-rw-r--r--library/cpp/blockcodecs/codecs/lzma/lzma.cpp74
-rw-r--r--library/cpp/blockcodecs/codecs/lzma/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/snappy/snappy.cpp52
-rw-r--r--library/cpp/blockcodecs/codecs/snappy/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/zlib/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/zlib/zlib.cpp64
-rw-r--r--library/cpp/blockcodecs/codecs/zstd/ya.make14
-rw-r--r--library/cpp/blockcodecs/codecs/zstd/zstd.cpp59
18 files changed, 741 insertions, 0 deletions
diff --git a/library/cpp/blockcodecs/codecs/brotli/brotli.cpp b/library/cpp/blockcodecs/codecs/brotli/brotli.cpp
new file mode 100644
index 0000000000..6e3cd971bd
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/brotli/brotli.cpp
@@ -0,0 +1,67 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/brotli/include/brotli/encode.h>
+#include <contrib/libs/brotli/include/brotli/decode.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TBrotliCodec : public TAddLengthCodec<TBrotliCodec> {
+ static constexpr int BEST_QUALITY = 11;
+
+ inline TBrotliCodec(ui32 level)
+ : Quality(level)
+ , MyName(TStringBuf("brotli_") + ToString(level))
+ {
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t l) noexcept {
+ return BrotliEncoderMaxCompressedSize(l);
+ }
+
+ inline size_t DoCompress(const TData& in, void* out) const {
+ size_t resultSize = MaxCompressedLength(in);
+ auto result = BrotliEncoderCompress(
+ /*quality*/ Quality,
+ /*window*/ BROTLI_DEFAULT_WINDOW,
+ /*mode*/ BrotliEncoderMode::BROTLI_MODE_GENERIC,
+ /*input_size*/ in.size(),
+ /*input_buffer*/ (const unsigned char*)(in.data()),
+ /*encoded_size*/ &resultSize,
+ /*encoded_buffer*/ static_cast<unsigned char*>(out));
+ if (result != BROTLI_TRUE) {
+ ythrow yexception() << "internal brotli error during compression";
+ }
+
+ return resultSize;
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t dsize) const {
+ size_t decoded = dsize;
+ auto result = BrotliDecoderDecompress(in.size(), (const unsigned char*)in.data(), &decoded, static_cast<unsigned char*>(out));
+ if (result != BROTLI_DECODER_RESULT_SUCCESS) {
+ ythrow yexception() << "internal brotli error during decompression";
+ } else if (decoded != dsize) {
+ ythrow TDecompressError(dsize, decoded);
+ }
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ const int Quality = BEST_QUALITY;
+ const TString MyName;
+ };
+
+ struct TBrotliRegistrar {
+ TBrotliRegistrar() {
+ for (int i = 1; i <= TBrotliCodec::BEST_QUALITY; ++i) {
+ RegisterCodec(MakeHolder<TBrotliCodec>(i));
+ }
+ }
+ };
+ const TBrotliRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/brotli/ya.make b/library/cpp/blockcodecs/codecs/brotli/ya.make
new file mode 100644
index 0000000000..17aff0bb72
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/brotli/ya.make
@@ -0,0 +1,15 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/brotli/enc
+ contrib/libs/brotli/dec
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL brotli.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/bzip/bzip.cpp b/library/cpp/blockcodecs/codecs/bzip/bzip.cpp
new file mode 100644
index 0000000000..3a5cfdd0e9
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/bzip/bzip.cpp
@@ -0,0 +1,62 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/libbz2/bzlib.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TBZipCodec: public TAddLengthCodec<TBZipCodec> {
+ inline TBZipCodec(int level)
+ : Level(level)
+ , MyName("bzip2-" + ToString(Level))
+ {
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t in) noexcept {
+ // very strange
+ return in * 2 + 128;
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ inline size_t DoCompress(const TData& in, void* buf) const {
+ unsigned int ret = DoMaxCompressedLength(in.size());
+ const int res = BZ2_bzBuffToBuffCompress((char*)buf, &ret, (char*)in.data(), in.size(), Level, 0, 0);
+ if (res != BZ_OK) {
+ ythrow TCompressError(res);
+ }
+
+ return ret;
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t len) const {
+ unsigned int tmp = SafeIntegerCast<unsigned int>(len);
+ const int res = BZ2_bzBuffToBuffDecompress((char*)out, &tmp, (char*)in.data(), in.size(), 0, 0);
+
+ if (res != BZ_OK) {
+ ythrow TDecompressError(res);
+ }
+
+ if (len != tmp) {
+ ythrow TDecompressError(len, tmp);
+ }
+ }
+
+ const int Level;
+ const TString MyName;
+ };
+
+ struct TBZipRegistrar {
+ TBZipRegistrar() {
+ for (int i = 1; i < 10; ++i) {
+ RegisterCodec(MakeHolder<TBZipCodec>(i));
+ }
+ RegisterAlias("bzip2", "bzip2-6");
+ }
+ };
+ const TBZipRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/bzip/ya.make b/library/cpp/blockcodecs/codecs/bzip/ya.make
new file mode 100644
index 0000000000..f0a8aefd62
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/bzip/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/libbz2
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL bzip.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/fastlz/fastlz.cpp b/library/cpp/blockcodecs/codecs/fastlz/fastlz.cpp
new file mode 100644
index 0000000000..da2831fbd2
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/fastlz/fastlz.cpp
@@ -0,0 +1,54 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/fastlz/fastlz.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TFastLZCodec: public TAddLengthCodec<TFastLZCodec> {
+ inline TFastLZCodec(int level)
+ : MyName("fastlz-" + ToString(level))
+ , Level(level)
+ {
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t in) noexcept {
+ return Max<size_t>(in + in / 20, 128);
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ inline size_t DoCompress(const TData& in, void* buf) const {
+ if (Level) {
+ return fastlz_compress_level(Level, in.data(), in.size(), buf);
+ }
+
+ return fastlz_compress(in.data(), in.size(), buf);
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t len) const {
+ const int ret = fastlz_decompress(in.data(), in.size(), out, len);
+
+ if (ret < 0 || (size_t)ret != len) {
+ ythrow TDataError() << TStringBuf("can not decompress");
+ }
+ }
+
+ const TString MyName;
+ const int Level;
+ };
+
+ struct TFastLZRegistrar {
+ TFastLZRegistrar() {
+ for (int i = 0; i < 3; ++i) {
+ RegisterCodec(MakeHolder<TFastLZCodec>(i));
+ }
+ RegisterAlias("fastlz", "fastlz-0");
+ }
+ };
+ const TFastLZRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/fastlz/ya.make b/library/cpp/blockcodecs/codecs/fastlz/ya.make
new file mode 100644
index 0000000000..59c09b329b
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/fastlz/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/fastlz
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL fastlz.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/legacy_zstd06/legacy_zstd06.cpp b/library/cpp/blockcodecs/codecs/legacy_zstd06/legacy_zstd06.cpp
new file mode 100644
index 0000000000..042f031679
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/legacy_zstd06/legacy_zstd06.cpp
@@ -0,0 +1,58 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/zstd06/common/zstd.h>
+#include <contrib/libs/zstd06/common/zstd_static.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TZStd06Codec: public TAddLengthCodec<TZStd06Codec> {
+ inline TZStd06Codec(unsigned level)
+ : Level(level)
+ , MyName(TStringBuf("zstd06_") + ToString(Level))
+ {
+ }
+
+ static inline size_t CheckError(size_t ret, const char* what) {
+ if (ZSTD_isError(ret)) {
+ ythrow yexception() << what << TStringBuf(" zstd error: ") << ZSTD_getErrorName(ret);
+ }
+
+ return ret;
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t l) noexcept {
+ return ZSTD_compressBound(l);
+ }
+
+ inline size_t DoCompress(const TData& in, void* out) const {
+ return CheckError(ZSTD_compress(out, DoMaxCompressedLength(in.size()), in.data(), in.size(), Level), "compress");
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t dsize) const {
+ const size_t res = CheckError(ZSTD_decompress(out, dsize, in.data(), in.size()), "decompress");
+
+ if (res != dsize) {
+ ythrow TDecompressError(dsize, res);
+ }
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ const unsigned Level;
+ const TString MyName;
+ };
+
+ struct TZStd06Registrar {
+ TZStd06Registrar() {
+ for (unsigned i = 1; i <= ZSTD_maxCLevel(); ++i) {
+ RegisterCodec(MakeHolder<TZStd06Codec>(i));
+ }
+ }
+ };
+ const TZStd06Registrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/legacy_zstd06/ya.make b/library/cpp/blockcodecs/codecs/legacy_zstd06/ya.make
new file mode 100644
index 0000000000..067f731233
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/legacy_zstd06/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/zstd06
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL legacy_zstd06.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/lz4/lz4.cpp b/library/cpp/blockcodecs/codecs/lz4/lz4.cpp
new file mode 100644
index 0000000000..fbf0fe110f
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/lz4/lz4.cpp
@@ -0,0 +1,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{};
+}
diff --git a/library/cpp/blockcodecs/codecs/lz4/ya.make b/library/cpp/blockcodecs/codecs/lz4/ya.make
new file mode 100644
index 0000000000..f2471d7d96
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/lz4/ya.make
@@ -0,0 +1,15 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/lz4
+ contrib/libs/lz4/generated
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL lz4.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/lzma/lzma.cpp b/library/cpp/blockcodecs/codecs/lzma/lzma.cpp
new file mode 100644
index 0000000000..6c8d5fded4
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/lzma/lzma.cpp
@@ -0,0 +1,74 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/lzmasdk/LzmaLib.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TLzmaCodec: public TAddLengthCodec<TLzmaCodec> {
+ inline TLzmaCodec(int level)
+ : Level(level)
+ , MyName("lzma-" + ToString(Level))
+ {
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t in) noexcept {
+ return Max<size_t>(in + in / 20, 128) + LZMA_PROPS_SIZE;
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ inline size_t DoCompress(const TData& in, void* buf) const {
+ unsigned char* props = (unsigned char*)buf;
+ unsigned char* data = props + LZMA_PROPS_SIZE;
+ size_t destLen = Max<size_t>();
+ size_t outPropsSize = LZMA_PROPS_SIZE;
+
+ const int ret = LzmaCompress(data, &destLen, (const unsigned char*)in.data(), in.size(), props, &outPropsSize, Level, 0, -1, -1, -1, -1, -1);
+
+ if (ret != SZ_OK) {
+ ythrow TCompressError(ret);
+ }
+
+ return destLen + LZMA_PROPS_SIZE;
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t len) const {
+ if (in.size() <= LZMA_PROPS_SIZE) {
+ ythrow TDataError() << TStringBuf("broken lzma stream");
+ }
+
+ const unsigned char* props = (const unsigned char*)in.data();
+ const unsigned char* data = props + LZMA_PROPS_SIZE;
+ size_t destLen = len;
+ SizeT srcLen = in.size() - LZMA_PROPS_SIZE;
+
+ const int res = LzmaUncompress((unsigned char*)out, &destLen, data, &srcLen, props, LZMA_PROPS_SIZE);
+
+ if (res != SZ_OK) {
+ ythrow TDecompressError(res);
+ }
+
+ if (destLen != len) {
+ ythrow TDecompressError(len, destLen);
+ }
+ }
+
+ const int Level;
+ const TString MyName;
+ };
+
+ struct TLzmaRegistrar {
+ TLzmaRegistrar() {
+ for (int i = 0; i < 10; ++i) {
+ RegisterCodec(MakeHolder<TLzmaCodec>(i));
+ }
+ RegisterAlias("lzma", "lzma-5");
+ }
+ };
+ const TLzmaRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/lzma/ya.make b/library/cpp/blockcodecs/codecs/lzma/ya.make
new file mode 100644
index 0000000000..e145834da6
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/lzma/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/lzmasdk
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL lzma.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/snappy/snappy.cpp b/library/cpp/blockcodecs/codecs/snappy/snappy.cpp
new file mode 100644
index 0000000000..f6be05a05f
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/snappy/snappy.cpp
@@ -0,0 +1,52 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/snappy/snappy.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TSnappyCodec: public ICodec {
+ size_t DecompressedLength(const TData& in) const override {
+ size_t ret;
+
+ if (snappy::GetUncompressedLength(in.data(), in.size(), &ret)) {
+ return ret;
+ }
+
+ ythrow TDecompressError(0);
+ }
+
+ size_t MaxCompressedLength(const TData& in) const override {
+ return snappy::MaxCompressedLength(in.size());
+ }
+
+ size_t Compress(const TData& in, void* out) const override {
+ size_t ret;
+
+ snappy::RawCompress(in.data(), in.size(), (char*)out, &ret);
+
+ return ret;
+ }
+
+ size_t Decompress(const TData& in, void* out) const override {
+ if (snappy::RawUncompress(in.data(), in.size(), (char*)out)) {
+ return DecompressedLength(in);
+ }
+
+ ythrow TDecompressError(0);
+ }
+
+ TStringBuf Name() const noexcept override {
+ return "snappy";
+ }
+ };
+
+ struct TSnappyRegistrar {
+ TSnappyRegistrar() {
+ RegisterCodec(MakeHolder<TSnappyCodec>());
+ }
+ };
+ const TSnappyRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/snappy/ya.make b/library/cpp/blockcodecs/codecs/snappy/ya.make
new file mode 100644
index 0000000000..0cf2be2f94
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/snappy/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/snappy
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL snappy.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/zlib/ya.make b/library/cpp/blockcodecs/codecs/zlib/ya.make
new file mode 100644
index 0000000000..9f04995f66
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/zlib/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/zlib
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL zlib.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/zlib/zlib.cpp b/library/cpp/blockcodecs/codecs/zlib/zlib.cpp
new file mode 100644
index 0000000000..cdb556c36d
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/zlib/zlib.cpp
@@ -0,0 +1,64 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#include <contrib/libs/zlib/zlib.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TZLibCodec: public TAddLengthCodec<TZLibCodec> {
+ inline TZLibCodec(int level)
+ : MyName("zlib-" + ToString(level))
+ , Level(level)
+ {
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t in) noexcept {
+ return compressBound(in);
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ inline size_t DoCompress(const TData& in, void* buf) const {
+ //TRASH detected
+ uLong ret = Max<unsigned int>();
+
+ int cres = compress2((Bytef*)buf, &ret, (const Bytef*)in.data(), in.size(), Level);
+
+ if (cres != Z_OK) {
+ ythrow TCompressError(cres);
+ }
+
+ return ret;
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t len) const {
+ uLong ret = len;
+
+ int uncres = uncompress((Bytef*)out, &ret, (const Bytef*)in.data(), in.size());
+ if (uncres != Z_OK) {
+ ythrow TDecompressError(uncres);
+ }
+
+ if (ret != len) {
+ ythrow TDecompressError(len, ret);
+ }
+ }
+
+ const TString MyName;
+ const int Level;
+ };
+
+ struct TZLibRegistrar {
+ TZLibRegistrar() {
+ for (int i = 0; i < 10; ++i) {
+ RegisterCodec(MakeHolder<TZLibCodec>(i));
+ }
+ RegisterAlias("zlib", "zlib-6");
+ }
+ };
+ const TZLibRegistrar Registrar{};
+}
diff --git a/library/cpp/blockcodecs/codecs/zstd/ya.make b/library/cpp/blockcodecs/codecs/zstd/ya.make
new file mode 100644
index 0000000000..c077dd47b7
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/zstd/ya.make
@@ -0,0 +1,14 @@
+LIBRARY()
+
+OWNER(pg)
+
+PEERDIR(
+ contrib/libs/zstd
+ library/cpp/blockcodecs/core
+)
+
+SRCS(
+ GLOBAL zstd.cpp
+)
+
+END()
diff --git a/library/cpp/blockcodecs/codecs/zstd/zstd.cpp b/library/cpp/blockcodecs/codecs/zstd/zstd.cpp
new file mode 100644
index 0000000000..95299b3f6d
--- /dev/null
+++ b/library/cpp/blockcodecs/codecs/zstd/zstd.cpp
@@ -0,0 +1,59 @@
+#include <library/cpp/blockcodecs/core/codecs.h>
+#include <library/cpp/blockcodecs/core/common.h>
+#include <library/cpp/blockcodecs/core/register.h>
+
+#define ZSTD_STATIC_LINKING_ONLY
+#include <contrib/libs/zstd/include/zstd.h>
+
+using namespace NBlockCodecs;
+
+namespace {
+ struct TZStd08Codec: public TAddLengthCodec<TZStd08Codec> {
+ inline TZStd08Codec(unsigned level)
+ : Level(level)
+ , MyName(TStringBuf("zstd08_") + ToString(Level))
+ {
+ }
+
+ static inline size_t CheckError(size_t ret, const char* what) {
+ if (ZSTD_isError(ret)) {
+ ythrow yexception() << what << TStringBuf(" zstd error: ") << ZSTD_getErrorName(ret);
+ }
+
+ return ret;
+ }
+
+ static inline size_t DoMaxCompressedLength(size_t l) noexcept {
+ return ZSTD_compressBound(l);
+ }
+
+ inline size_t DoCompress(const TData& in, void* out) const {
+ return CheckError(ZSTD_compress(out, DoMaxCompressedLength(in.size()), in.data(), in.size(), Level), "compress");
+ }
+
+ inline void DoDecompress(const TData& in, void* out, size_t dsize) const {
+ const size_t res = CheckError(ZSTD_decompress(out, dsize, in.data(), in.size()), "decompress");
+
+ if (res != dsize) {
+ ythrow TDecompressError(dsize, res);
+ }
+ }
+
+ TStringBuf Name() const noexcept override {
+ return MyName;
+ }
+
+ const unsigned Level;
+ const TString MyName;
+ };
+
+ struct TZStd08Registrar {
+ TZStd08Registrar() {
+ for (int i = 1; i <= ZSTD_maxCLevel(); ++i) {
+ RegisterCodec(MakeHolder<TZStd08Codec>(i));
+ RegisterAlias("zstd_" + ToString(i), "zstd08_" + ToString(i));
+ }
+ }
+ };
+ const TZStd08Registrar Registrar{};
+}