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();