18 #if FOLLY_HAVE_LIBZSTD 31 ZSTD_VERSION_NUMBER >= 10302,
32 "zstd-1.3.2 is the minimum supported zstd version.");
42 void zstdFreeCCtx(ZSTD_CCtx* zc) {
46 void zstdFreeDCtx(ZSTD_DCtx* zd) {
50 size_t zstdThrowIfError(
size_t rc) {
51 if (!ZSTD_isError(rc)) {
54 throw std::runtime_error(
55 to<std::string>(
"ZSTD returned an error: ", ZSTD_getErrorName(rc)));
61 return ZSTD_e_continue;
67 throw std::invalid_argument(
"ZSTDStreamCodec: Invalid flush");
71 class ZSTDStreamCodec final :
public StreamCodec {
73 explicit ZSTDStreamCodec(Options options);
75 std::vector<std::string> validPrefixes()
const override;
76 bool canUncompress(
const IOBuf*
data, Optional<uint64_t> uncompressedLength)
80 bool doNeedsUncompressedLength()
const override;
82 Optional<uint64_t> doGetUncompressedLength(
84 Optional<uint64_t> uncompressedLength)
const override;
86 void doResetStream()
override;
87 bool doCompressStream(
91 bool doUncompressStream(
100 bool needReset_{
true};
111 constexpr
uint32_t kZSTDMagicLE = 0xFD2FB528;
113 std::vector<std::string> ZSTDStreamCodec::validPrefixes()
const {
117 bool ZSTDStreamCodec::canUncompress(
const IOBuf*
data, Optional<uint64_t>)
122 CodecType codecType(Options
const& options) {
123 int const level = options.level();
128 ZSTDStreamCodec::ZSTDStreamCodec(Options options)
129 : StreamCodec(codecType(options), options.level()),
130 options_(
std::
move(options)) {}
132 bool ZSTDStreamCodec::doNeedsUncompressedLength()
const {
136 uint64_t ZSTDStreamCodec::doMaxCompressedLength(
137 uint64_t uncompressedLength)
const {
138 return ZSTD_compressBound(uncompressedLength);
141 Optional<uint64_t> ZSTDStreamCodec::doGetUncompressedLength(
143 Optional<uint64_t> uncompressedLength)
const {
145 auto const decompressedSize =
146 ZSTD_getFrameContentSize(data->data(), data->length());
147 if (decompressedSize == ZSTD_CONTENTSIZE_UNKNOWN ||
148 decompressedSize == ZSTD_CONTENTSIZE_ERROR) {
149 return uncompressedLength;
151 if (uncompressedLength && *uncompressedLength != decompressedSize) {
152 throw std::runtime_error(
"ZSTD: invalid uncompressed length");
154 return decompressedSize;
157 void ZSTDStreamCodec::doResetStream() {
161 void ZSTDStreamCodec::resetCCtx() {
163 cctx_.reset(ZSTD_createCCtx());
165 throw std::bad_alloc{};
168 ZSTD_CCtx_reset(cctx_.get());
170 ZSTD_CCtx_setParametersUsingCCtxParams(cctx_.get(), options_.params()));
171 zstdThrowIfError(ZSTD_CCtx_setPledgedSrcSize(
172 cctx_.get(), uncompressedLength().value_or(ZSTD_CONTENTSIZE_UNKNOWN)));
175 bool ZSTDStreamCodec::doCompressStream(
178 StreamCodec::FlushOp flushOp) {
183 ZSTD_inBuffer in = {input.data(), input.size(), 0};
184 ZSTD_outBuffer out = {output.data(), output.size(), 0};
186 input.uncheckedAdvance(in.pos);
187 output.uncheckedAdvance(out.pos);
189 size_t const rc = zstdThrowIfError(ZSTD_compress_generic(
190 cctx_.get(), &out, &in, zstdTranslateFlush(flushOp)));
192 case StreamCodec::FlushOp::NONE:
194 case StreamCodec::FlushOp::FLUSH:
195 case StreamCodec::FlushOp::END:
198 throw std::invalid_argument(
"ZSTD: invalid FlushOp");
202 void ZSTDStreamCodec::resetDCtx() {
204 dctx_.reset(ZSTD_createDCtx());
206 throw std::bad_alloc{};
209 ZSTD_DCtx_reset(dctx_.get());
210 if (options_.maxWindowSize() != 0) {
212 ZSTD_DCtx_setMaxWindowSize(dctx_.get(), options_.maxWindowSize()));
216 bool ZSTDStreamCodec::doUncompressStream(
219 StreamCodec::FlushOp) {
224 ZSTD_inBuffer in = {input.data(), input.size(), 0};
225 ZSTD_outBuffer out = {output.data(), output.size(), 0};
227 input.uncheckedAdvance(in.pos);
228 output.uncheckedAdvance(out.pos);
231 zstdThrowIfError(ZSTD_decompress_generic(dctx_.get(), &out, &in));
237 Options::Options(
int level) : params_(ZSTD_createCCtxParams()), level_(level) {
238 if (params_ ==
nullptr) {
239 throw std::bad_alloc{};
241 #if ZSTD_VERSION_NUMBER >= 10304 242 zstdThrowIfError(ZSTD_CCtxParams_init(params_.get(), level));
244 zstdThrowIfError(ZSTD_initCCtxParams(params_.get(), level));
245 set(ZSTD_p_contentSizeFlag, 1);
250 set(ZSTD_p_compressionLevel, level);
254 zstdThrowIfError(ZSTD_CCtxParam_setParameter(params_.get(), param,
value));
255 if (param == ZSTD_p_compressionLevel) {
256 level_ =
static_cast<int>(
value);
260 void Options::freeCCtxParams(ZSTD_CCtx_params*
params) {
261 ZSTD_freeCCtxParams(params);
264 std::unique_ptr<Codec>
getCodec(Options options) {
265 return std::make_unique<ZSTDStreamCodec>(
std::move(options));
269 return std::make_unique<ZSTDStreamCodec>(
std::move(options));
constexpr detail::Map< Move > move
—— Concurrent Priority Queue Implementation ——
Range< unsigned char * > MutableByteRange
std::enable_if< std::is_arithmetic< T >::value, std::string >::type prefixToStringLE(T prefix, uint64_t n=sizeof(T))
constexpr Params params[]
std::unique_ptr< StreamCodec > getStreamCodec(CodecType type, int level)
constexpr auto data(C &c) -> decltype(c.data())
static const char *const value
Range< const unsigned char * > ByteRange
std::enable_if< std::is_unsigned< T >::value, bool >::type dataStartsWithLE(const IOBuf *data, T prefix, uint64_t n=sizeof(T))
std::unique_ptr< Codec > getCodec(CodecType type, int level)
static constexpr uint64_t data[1]