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_SNAPPYCOMPRESSOR_H
16 #define CEPH_SNAPPYCOMPRESSOR_H
19 #include <snappy-sinksource.h>
20 #include "compressor/Compressor.h"
21 #include "include/buffer.h"
23 class CEPH_BUFFER_API BufferlistSource : public snappy::Source {
24 bufferlist::iterator pb;
28 explicit BufferlistSource(bufferlist::iterator _pb, size_t _input_len)
30 remaining(_input_len) {
31 remaining = std::min(remaining, (size_t)pb.get_remaining());
33 size_t Available() const override {
36 const char *Peek(size_t *len) override {
37 const char *data = NULL;
39 size_t avail = Available();
42 *len = ptmp.get_ptr_and_advance(avail, &data);
46 void Skip(size_t n) override {
47 assert(n <= remaining);
52 bufferlist::iterator get_pos() const {
57 class SnappyCompressor : public Compressor {
59 SnappyCompressor() : Compressor(COMP_ALG_SNAPPY, "snappy") {}
61 int compress(const bufferlist &src, bufferlist &dst) override {
62 BufferlistSource source(const_cast<bufferlist&>(src).begin(), src.length());
63 bufferptr ptr = buffer::create_page_aligned(
64 snappy::MaxCompressedLength(src.length()));
65 snappy::UncheckedByteArraySink sink(ptr.c_str());
66 snappy::Compress(&source, &sink);
67 dst.append(ptr, 0, sink.CurrentDestination() - ptr.c_str());
71 int decompress(const bufferlist &src, bufferlist &dst) override {
72 bufferlist::iterator i = const_cast<bufferlist&>(src).begin();
73 return decompress(i, src.length(), dst);
76 int decompress(bufferlist::iterator &p,
77 size_t compressed_len,
78 bufferlist &dst) override {
79 snappy::uint32 res_len = 0;
80 BufferlistSource source_1(p, compressed_len);
81 if (!snappy::GetUncompressedLength(&source_1, &res_len)) {
84 BufferlistSource source_2(p, compressed_len);
85 bufferptr ptr(res_len);
86 if (snappy::RawUncompress(&source_2, ptr.c_str())) {
87 p = source_2.get_pos();