]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_compression.cc
2 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
3 // vim: ts=8 sw=2 smarttab
5 #include "rgw_compression.h"
7 #define dout_subsys ceph_subsys_rgw
9 //------------RGWPutObj_Compress---------------
11 int RGWPutObj_Compress::handle_data(bufferlist
& bl
, off_t ofs
, void **phandle
, rgw_raw_obj
*pobj
, bool *again
)
15 return next
->handle_data(in_bl
, ofs
, phandle
, pobj
, again
);
17 if (bl
.length() > 0) {
19 if ((ofs
> 0 && compressed
) || // if previous part was compressed
20 (ofs
== 0)) { // or it's the first part
21 ldout(cct
, 10) << "Compression for rgw is enabled, compress part " << bl
.length() << dendl
;
22 int cr
= compressor
->compress(bl
, in_bl
);
25 lderr(cct
) << "Compression failed with exit code " << cr
26 << " for next part, compression process failed" << dendl
;
30 ldout(cct
, 5) << "Compression failed with exit code " << cr
31 << " for first part, storing uncompressed" << dendl
;
36 compression_block newbl
;
37 size_t bs
= blocks
.size();
39 newbl
.new_ofs
= bs
> 0 ? blocks
[bs
-1].len
+ blocks
[bs
-1].new_ofs
: 0;
40 newbl
.len
= in_bl
.length();
41 blocks
.push_back(newbl
);
47 // end of compression stuff
49 return next
->handle_data(in_bl
, ofs
, phandle
, pobj
, again
);
52 //----------------RGWGetObj_Decompress---------------------
53 RGWGetObj_Decompress::RGWGetObj_Decompress(CephContext
* cct_
,
54 RGWCompressionInfo
* cs_info_
,
55 bool partial_content_
,
56 RGWGetDataCB
* next
): RGWGetObj_Filter(next
),
59 partial_content(partial_content_
),
64 compressor
= Compressor::create(cct
, cs_info
->compression_type
);
65 if (!compressor
.get())
66 lderr(cct
) << "Cannot load compressor of type " << cs_info
->compression_type
<< dendl
;
69 int RGWGetObj_Decompress::handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
)
71 ldout(cct
, 10) << "Compression for rgw is enabled, decompress part "
72 << "bl_ofs="<< bl_ofs
<< bl_len
<< dendl
;
74 if (!compressor
.get()) {
75 // if compressor isn't available - error, because cannot return decompressed data?
76 lderr(cct
) << "Cannot load compressor of type " << cs_info
->compression_type
<< dendl
;
79 bufferlist out_bl
, in_bl
, temp_in_bl
;
80 bl
.copy(bl_ofs
, bl_len
, temp_in_bl
);
83 if (waiting
.length() != 0) {
84 in_bl
.append(waiting
);
85 in_bl
.append(temp_in_bl
);
88 in_bl
.claim(temp_in_bl
);
90 bl_len
= in_bl
.length();
92 while (first_block
<= last_block
) {
94 off_t ofs_in_bl
= first_block
->new_ofs
- cur_ofs
;
95 if (ofs_in_bl
+ (off_t
)first_block
->len
> bl_len
) {
96 // not complete block, put it to waiting
97 unsigned tail
= bl_len
- ofs_in_bl
;
98 in_bl
.copy(ofs_in_bl
, tail
, waiting
);
102 in_bl
.copy(ofs_in_bl
, first_block
->len
, tmp
);
103 int cr
= compressor
->decompress(tmp
, out_bl
);
105 lderr(cct
) << "Compression failed with exit code " << cr
<< dendl
;
109 while (out_bl
.length() - q_ofs
>= cct
->_conf
->rgw_max_chunk_size
)
111 off_t ch_len
= std::min
<off_t
>(cct
->_conf
->rgw_max_chunk_size
, q_len
);
113 r
= next
->handle_data(out_bl
, q_ofs
, ch_len
);
115 lderr(cct
) << "handle_data failed with exit code " << r
<< dendl
;
118 out_bl
.splice(0, q_ofs
+ ch_len
);
124 off_t ch_len
= std::min
<off_t
>(out_bl
.length() - q_ofs
, q_len
);
126 r
= next
->handle_data(out_bl
, q_ofs
, ch_len
);
128 lderr(cct
) << "handle_data failed with exit code " << r
<< dendl
;
131 out_bl
.splice(0, q_ofs
+ ch_len
);
138 int RGWGetObj_Decompress::fixup_range(off_t
& ofs
, off_t
& end
)
140 if (partial_content
) {
141 // if user set range, we need to calculate it in decompressed data
142 first_block
= cs_info
->blocks
.begin(); last_block
= cs_info
->blocks
.begin();
143 if (cs_info
->blocks
.size() > 1) {
144 vector
<compression_block
>::iterator fb
, lb
;
145 // not bad to use auto for lambda, I think
146 auto cmp_u
= [] (off_t ofs
, const compression_block
& e
) { return (uint64_t)ofs
< e
.old_ofs
; };
147 auto cmp_l
= [] (const compression_block
& e
, off_t ofs
) { return e
.old_ofs
<= (uint64_t)ofs
; };
148 fb
= upper_bound(cs_info
->blocks
.begin()+1,
149 cs_info
->blocks
.end(),
152 first_block
= fb
- 1;
154 cs_info
->blocks
.end(),
160 first_block
= cs_info
->blocks
.begin(); last_block
= cs_info
->blocks
.end() - 1;
163 q_ofs
= ofs
- first_block
->old_ofs
;
164 q_len
= end
+ 1 - ofs
;
166 ofs
= first_block
->new_ofs
;
167 end
= last_block
->new_ofs
+ last_block
->len
- 1;
172 return next
->fixup_range(ofs
, end
);