Commit ad7ca67b authored by Jon Maltiel Swenson's avatar Jon Maltiel Swenson Committed by facebook-github-bot-4

Bring zstd support into folly/io/Compression.h

Summary: Bring zstd support into folly/io/Compression.h

Reviewed By: chipturner

Differential Revision: D2551026

fb-gh-sync-id: 7c13338d45efb0fc19f0b44015c7e62d945a483b
parent ef011843
......@@ -446,6 +446,7 @@ AC_CHECK_HEADER([lz4.h], AC_CHECK_LIB([lz4], [LZ4_decompress_safe]))
AC_CHECK_HEADER([snappy.h], AC_CHECK_LIB([snappy], [main]))
AC_CHECK_HEADER([zlib.h], AC_CHECK_LIB([z], [main]))
AC_CHECK_HEADER([lzma.h], AC_CHECK_LIB([lzma], [main]))
AC_CHECK_HEADER([zstd.h], AC_CHECK_LIB([zstd], [main]))
# Include directory that contains "folly" so #include <folly/Foo.h> works
AM_CPPFLAGS='-I$(top_srcdir)/..'
......
......@@ -36,6 +36,10 @@
#include <lzma.h>
#endif
#if FOLLY_HAVE_LIBZSTD
#include <zstd.h>
#endif
#include <folly/Conv.h>
#include <folly/Memory.h>
#include <folly/Portability.h>
......@@ -919,6 +923,83 @@ std::unique_ptr<IOBuf> LZMA2Codec::doUncompress(const IOBuf* data,
#endif // FOLLY_HAVE_LIBLZMA
#ifdef FOLLY_HAVE_LIBZSTD
/**
* ZSTD_BETA compression
*/
class ZSTDCodec final : public Codec {
public:
static std::unique_ptr<Codec> create(int level, CodecType);
explicit ZSTDCodec(int level, CodecType type);
private:
bool doNeedsUncompressedLength() const override;
std::unique_ptr<IOBuf> doCompress(const IOBuf* data) override;
std::unique_ptr<IOBuf> doUncompress(
const IOBuf* data,
uint64_t uncompressedLength) override;
};
std::unique_ptr<Codec> ZSTDCodec::create(int level, CodecType type) {
return make_unique<ZSTDCodec>(level, type);
}
ZSTDCodec::ZSTDCodec(int level, CodecType type) : Codec(type) {
DCHECK(type == CodecType::ZSTD_BETA);
}
bool ZSTDCodec::doNeedsUncompressedLength() const {
return true;
}
std::unique_ptr<IOBuf> ZSTDCodec::doCompress(const IOBuf* data) {
size_t rc;
size_t maxCompressedLength = ZSTD_compressBound(data->length());
auto out = IOBuf::createCombined(maxCompressedLength);
CHECK_EQ(out->length(), 0);
rc = ZSTD_compress(
out->writableTail(), out->capacity(), data->data(), data->length());
if (ZSTD_isError(rc)) {
throw std::runtime_error(to<std::string>(
"ZSTD compression returned an error: ",
ZSTD_getErrorName(rc)));
}
out->append(rc);
CHECK_EQ(out->length(), rc);
return out;
}
std::unique_ptr<IOBuf> ZSTDCodec::doUncompress(const IOBuf* data,
uint64_t uncompressedLength) {
size_t rc;
auto out = IOBuf::createCombined(uncompressedLength);
CHECK_GE(out->capacity(), uncompressedLength);
CHECK_EQ(out->length(), 0);
rc = ZSTD_decompress(
out->writableTail(), out->capacity(), data->data(), data->length());
if (ZSTD_isError(rc)) {
throw std::runtime_error(to<std::string>(
"ZSTD decompression returned an error: ",
ZSTD_getErrorName(rc)));
}
out->append(rc);
CHECK_EQ(out->length(), rc);
return out;
}
#endif // FOLLY_HAVE_LIBZSTD
} // namespace
std::unique_ptr<Codec> getCodec(CodecType type, int level) {
......@@ -960,6 +1041,12 @@ std::unique_ptr<Codec> getCodec(CodecType type, int level) {
nullptr,
nullptr,
#endif
#if FOLLY_HAVE_LIBZSTD
ZSTDCodec::create,
#else
nullptr,
#endif
};
size_t idx = static_cast<size_t>(type);
......
......@@ -73,7 +73,14 @@ enum class CodecType {
LZMA2 = 6,
LZMA2_VARINT_SIZE = 7,
NUM_CODEC_TYPES = 8,
/**
* Use ZSTD_BETA compression.
* This format is not yet final; please do not rely on it for anything other
* than testing purposes yet.
*/
ZSTD_BETA = 8,
NUM_CODEC_TYPES = 9,
};
class Codec {
......
......@@ -128,6 +128,7 @@ TEST(CompressionTestNeedsUncompressedLength, Simple) {
EXPECT_TRUE(getCodec(CodecType::LZMA2)->needsUncompressedLength());
EXPECT_FALSE(getCodec(CodecType::LZMA2_VARINT_SIZE)
->needsUncompressedLength());
EXPECT_TRUE(getCodec(CodecType::ZSTD_BETA)->needsUncompressedLength());
}
class CompressionTest
......@@ -180,7 +181,8 @@ INSTANTIATE_TEST_CASE_P(
CodecType::ZLIB,
CodecType::LZ4_VARINT_SIZE,
CodecType::LZMA2,
CodecType::LZMA2_VARINT_SIZE)));
CodecType::LZMA2_VARINT_SIZE,
CodecType::ZSTD_BETA)));
class CompressionVarintTest
: public testing::TestWithParam<std::tr1::tuple<int, CodecType>> {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment