1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2015 Haomai Wang <haomaiwang@gmail.com>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #ifndef CEPH_ZSTDCOMPRESSOR_H
16 #define CEPH_ZSTDCOMPRESSOR_H
18 #include "zstd/lib/zstd.h"
19 #include "include/buffer.h"
20 #include "include/encoding.h"
21 #include "compressor/Compressor.h"
23 #define COMPRESSION_LEVEL 5
25 class ZstdCompressor : public Compressor {
27 ZstdCompressor() : Compressor(COMP_ALG_ZSTD, "zstd") {}
29 int compress(const bufferlist &src, bufferlist &dst) override {
30 bufferptr outptr = buffer::create_page_aligned(
31 ZSTD_compressBound(src.length()));
32 ZSTD_outBuffer_s outbuf;
33 outbuf.dst = outptr.c_str();
34 outbuf.size = outptr.length();
37 ZSTD_CStream *s = ZSTD_createCStream();
38 ZSTD_initCStream(s, COMPRESSION_LEVEL);
40 size_t left = src.length();
43 struct ZSTD_inBuffer_s inbuf;
45 inbuf.size = p.get_ptr_and_advance(left, (const char**)&inbuf.src);
46 ZSTD_compressStream(s, &outbuf, &inbuf);
50 ZSTD_flushStream(s, &outbuf);
51 ZSTD_endStream(s, &outbuf);
54 // prefix with decompressed length
55 ::encode((uint32_t)src.length(), dst);
56 dst.append(outptr, 0, outbuf.pos);
60 int decompress(const bufferlist &src, bufferlist &dst) override {
61 bufferlist::iterator i = const_cast<bufferlist&>(src).begin();
62 return decompress(i, src.length(), dst);
65 int decompress(bufferlist::iterator &p,
66 size_t compressed_len,
67 bufferlist &dst) override {
68 if (compressed_len < 4) {
75 bufferptr dstptr(dst_len);
76 ZSTD_outBuffer_s outbuf;
77 outbuf.dst = dstptr.c_str();
78 outbuf.size = dstptr.length();
80 ZSTD_DStream *s = ZSTD_createDStream();
82 while (compressed_len > 0) {
86 ZSTD_inBuffer_s inbuf;
88 inbuf.size = p.get_ptr_and_advance(compressed_len, (const char**)&inbuf.src);
89 ZSTD_decompressStream(s, &outbuf, &inbuf);
90 compressed_len -= inbuf.size;
94 dst.append(dstptr, 0, outbuf.pos);