]> git.proxmox.com Git - ceph.git/blob - ceph/src/compressor/snappy/SnappyCompressor.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / compressor / snappy / SnappyCompressor.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Haomai Wang <haomaiwang@gmail.com>
7 *
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.
12 *
13 */
14
15 #ifndef CEPH_SNAPPYCOMPRESSOR_H
16 #define CEPH_SNAPPYCOMPRESSOR_H
17
18 #include <snappy.h>
19 #include <snappy-sinksource.h>
20 #include "include/buffer.h"
21 #include "compressor/Compressor.h"
22
23 class CEPH_BUFFER_API BufferlistSource : public snappy::Source {
24 bufferlist::iterator pb;
25 size_t remaining;
26
27 public:
28 explicit BufferlistSource(bufferlist::iterator _pb, size_t _input_len)
29 : pb(_pb),
30 remaining(_input_len) {
31 remaining = std::min(remaining, (size_t)pb.get_remaining());
32 }
33 size_t Available() const override {
34 return remaining;
35 }
36 const char *Peek(size_t *len) override {
37 const char *data = NULL;
38 *len = 0;
39 size_t avail = Available();
40 if (avail) {
41 auto ptmp = pb;
42 *len = ptmp.get_ptr_and_advance(avail, &data);
43 }
44 return data;
45 }
46 void Skip(size_t n) override {
47 assert(n <= remaining);
48 pb.advance(n);
49 remaining -= n;
50 }
51
52 bufferlist::iterator get_pos() const {
53 return pb;
54 }
55 };
56
57 class SnappyCompressor : public Compressor {
58 public:
59 SnappyCompressor() : Compressor(COMP_ALG_SNAPPY, "snappy") {}
60
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());
68 return 0;
69 }
70
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);
74 }
75
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)) {
82 return -1;
83 }
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();
88 dst.append(ptr);
89 return 0;
90 }
91 return -2;
92 }
93 };
94
95 #endif