]>
git.proxmox.com Git - ceph.git/blob - ceph/src/compressor/zlib/ZlibCompressor.cc
beb2f195d40c2453390051c2e77fe9c6f3aab16f
2 * Ceph - scalable distributed file system
4 * Copyright (C) 2015 Mirantis, Inc.
6 * Author: Alyona Kiseleva <akiselyova@mirantis.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
15 // -----------------------------------------------------------------------------
16 #include "common/debug.h"
17 #include "ZlibCompressor.h"
18 #include "osd/osd_types.h"
19 #include "isa-l/include/igzip_lib.h"
20 // -----------------------------------------------------------------------------
24 // -----------------------------------------------------------------------------
25 #define dout_context g_ceph_context
26 #define dout_subsys ceph_subsys_compressor
28 #define dout_prefix _prefix(_dout)
29 // -----------------------------------------------------------------------------
31 // -----------------------------------------------------------------------------
34 _prefix(std::ostream
* _dout
)
36 return *_dout
<< "ZlibCompressor: ";
38 // -----------------------------------------------------------------------------
40 #define MAX_LEN (CEPH_PAGE_SIZE)
42 // default window size for Zlib 1.2.8, negated for raw deflate
43 #define ZLIB_DEFAULT_WIN_SIZE -15
45 // desired memory usage level. increasing to 9 doesn't speed things up
46 // significantly (helps only on >=16K blocks) and sometimes degrades
48 #define ZLIB_MEMORY_LEVEL 8
50 int ZlibCompressor::zlib_compress(const bufferlist
&in
, bufferlist
&out
)
58 /* allocate deflate state */
62 ret
= deflateInit2(&strm
, g_conf
->compressor_zlib_level
, Z_DEFLATED
, ZLIB_DEFAULT_WIN_SIZE
, ZLIB_MEMORY_LEVEL
, Z_DEFAULT_STRATEGY
);
64 dout(1) << "Compression init error: init return "
65 << ret
<< " instead of Z_OK" << dendl
;
69 for (std::list
<buffer::ptr
>::const_iterator i
= in
.buffers().begin();
70 i
!= in
.buffers().end();) {
72 c_in
= (unsigned char*) (*i
).c_str();
73 long unsigned int len
= (*i
).length();
77 int flush
= i
!= in
.buffers().end() ? Z_NO_FLUSH
: Z_FINISH
;
81 bufferptr ptr
= buffer::create_page_aligned(MAX_LEN
);
82 strm
.next_out
= (unsigned char*)ptr
.c_str() + begin
;
83 strm
.avail_out
= MAX_LEN
- begin
;
85 // put a compressor variation mark in front of compressed stream, not used at the moment
89 ret
= deflate(&strm
, flush
); /* no bad return value */
90 if (ret
== Z_STREAM_ERROR
) {
91 dout(1) << "Compression error: compress return Z_STREAM_ERROR("
92 << ret
<< ")" << dendl
;
96 have
= MAX_LEN
- strm
.avail_out
;
97 out
.append(ptr
, 0, have
);
98 } while (strm
.avail_out
== 0);
99 if (strm
.avail_in
!= 0) {
100 dout(10) << "Compression error: unused input" << dendl
;
110 #if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64)
111 int ZlibCompressor::isal_compress(const bufferlist
&in
, bufferlist
&out
)
119 /* allocate deflate state */
120 isal_deflate_init(&strm
);
121 strm
.end_of_stream
= 0;
123 for (std::list
<buffer::ptr
>::const_iterator i
= in
.buffers().begin();
124 i
!= in
.buffers().end();) {
126 c_in
= (unsigned char*) (*i
).c_str();
127 long unsigned int len
= (*i
).length();
131 strm
.end_of_stream
= (i
== in
.buffers().end());
132 strm
.flush
= FINISH_FLUSH
;
137 bufferptr ptr
= buffer::create_page_aligned(MAX_LEN
);
138 strm
.next_out
= (unsigned char*)ptr
.c_str() + begin
;
139 strm
.avail_out
= MAX_LEN
- begin
;
141 // put a compressor variation mark in front of compressed stream, not used at the moment
145 ret
= isal_deflate(&strm
);
146 if (ret
!= COMP_OK
) {
147 dout(1) << "Compression error: isal_deflate return error ("
148 << ret
<< ")" << dendl
;
151 have
= MAX_LEN
- strm
.avail_out
;
152 out
.append(ptr
, 0, have
);
153 } while (strm
.avail_out
== 0);
154 if (strm
.avail_in
!= 0) {
155 dout(10) << "Compression error: unused input" << dendl
;
164 int ZlibCompressor::compress(const bufferlist
&in
, bufferlist
&out
)
166 #if __x86_64__ && defined(HAVE_BETTER_YASM_ELF64)
168 return isal_compress(in
, out
);
170 return zlib_compress(in
, out
);
172 return zlib_compress(in
, out
);
176 int ZlibCompressor::decompress(bufferlist::iterator
&p
, size_t compressed_size
, bufferlist
&out
)
184 /* allocate inflate state */
185 strm
.zalloc
= Z_NULL
;
187 strm
.opaque
= Z_NULL
;
189 strm
.next_in
= Z_NULL
;
191 // choose the variation of compressor
192 ret
= inflateInit2(&strm
, ZLIB_DEFAULT_WIN_SIZE
);
194 dout(1) << "Decompression init error: init return "
195 << ret
<< " instead of Z_OK" << dendl
;
199 size_t remaining
= MIN(p
.get_remaining(), compressed_size
);
202 long unsigned int len
= p
.get_ptr_and_advance(remaining
, &c_in
);
204 strm
.avail_in
= len
- begin
;
205 strm
.next_in
= (unsigned char*)c_in
+ begin
;
209 strm
.avail_out
= MAX_LEN
;
210 bufferptr ptr
= buffer::create_page_aligned(MAX_LEN
);
211 strm
.next_out
= (unsigned char*)ptr
.c_str();
212 ret
= inflate(&strm
, Z_NO_FLUSH
);
213 if (ret
!= Z_OK
&& ret
!= Z_STREAM_END
&& ret
!= Z_BUF_ERROR
) {
214 dout(1) << "Decompression error: decompress return "
219 have
= MAX_LEN
- strm
.avail_out
;
220 out
.append(ptr
, 0, have
);
221 } while (strm
.avail_out
== 0);
224 /* clean up and return */
225 (void)inflateEnd(&strm
);
229 int ZlibCompressor::decompress(const bufferlist
&in
, bufferlist
&out
)
231 bufferlist::iterator i
= const_cast<bufferlist
&>(in
).begin();
232 return decompress(i
, in
.length(), out
);