1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
4 #include "include/encoding.h"
9 const stripe_info_t &sinfo,
10 ErasureCodeInterfaceRef &ec_impl,
11 map<int, bufferlist> &to_decode,
13 assert(to_decode.size());
15 uint64_t total_data_size = to_decode.begin()->second.length();
16 assert(total_data_size % sinfo.get_chunk_size() == 0);
19 assert(out->length() == 0);
21 for (map<int, bufferlist>::iterator i = to_decode.begin();
24 assert(i->second.length() == total_data_size);
27 if (total_data_size == 0)
30 for (uint64_t i = 0; i < total_data_size; i += sinfo.get_chunk_size()) {
31 map<int, bufferlist> chunks;
32 for (map<int, bufferlist>::iterator j = to_decode.begin();
35 chunks[j->first].substr_of(j->second, i, sinfo.get_chunk_size());
38 int r = ec_impl->decode_concat(chunks, &bl);
39 assert(bl.length() == sinfo.get_stripe_width());
41 out->claim_append(bl);
47 const stripe_info_t &sinfo,
48 ErasureCodeInterfaceRef &ec_impl,
49 map<int, bufferlist> &to_decode,
50 map<int, bufferlist*> &out) {
51 assert(to_decode.size());
53 uint64_t total_data_size = to_decode.begin()->second.length();
54 assert(total_data_size % sinfo.get_chunk_size() == 0);
56 for (map<int, bufferlist>::iterator i = to_decode.begin();
59 assert(i->second.length() == total_data_size);
62 if (total_data_size == 0)
66 for (map<int, bufferlist*>::iterator i = out.begin();
70 assert(i->second->length() == 0);
71 need.insert(i->first);
74 for (uint64_t i = 0; i < total_data_size; i += sinfo.get_chunk_size()) {
75 map<int, bufferlist> chunks;
76 for (map<int, bufferlist>::iterator j = to_decode.begin();
79 chunks[j->first].substr_of(j->second, i, sinfo.get_chunk_size());
81 map<int, bufferlist> out_bls;
82 int r = ec_impl->decode(need, chunks, &out_bls);
84 for (map<int, bufferlist*>::iterator j = out.begin();
87 assert(out_bls.count(j->first));
88 assert(out_bls[j->first].length() == sinfo.get_chunk_size());
89 j->second->claim_append(out_bls[j->first]);
92 for (map<int, bufferlist*>::iterator i = out.begin();
95 assert(i->second->length() == total_data_size);
101 const stripe_info_t &sinfo,
102 ErasureCodeInterfaceRef &ec_impl,
104 const set<int> &want,
105 map<int, bufferlist> *out) {
107 uint64_t logical_size = in.length();
109 assert(logical_size % sinfo.get_stripe_width() == 0);
111 assert(out->empty());
113 if (logical_size == 0)
116 for (uint64_t i = 0; i < logical_size; i += sinfo.get_stripe_width()) {
117 map<int, bufferlist> encoded;
119 buf.substr_of(in, i, sinfo.get_stripe_width());
120 int r = ec_impl->encode(want, buf, &encoded);
122 for (map<int, bufferlist>::iterator i = encoded.begin();
125 assert(i->second.length() == sinfo.get_chunk_size());
126 (*out)[i->first].claim_append(i->second);
130 for (map<int, bufferlist>::iterator i = out->begin();
133 assert(i->second.length() % sinfo.get_chunk_size() == 0);
135 sinfo.aligned_chunk_offset_to_logical_offset(i->second.length()) ==
141 void ECUtil::HashInfo::append(uint64_t old_size,
142 map<int, bufferlist> &to_append) {
143 assert(old_size == total_chunk_size);
144 uint64_t size_to_append = to_append.begin()->second.length();
145 if (has_chunk_hash()) {
146 assert(to_append.size() == cumulative_shard_hashes.size());
147 for (map<int, bufferlist>::iterator i = to_append.begin();
148 i != to_append.end();
150 assert(size_to_append == i->second.length());
151 assert((unsigned)i->first < cumulative_shard_hashes.size());
152 uint32_t new_hash = i->second.crc32c(cumulative_shard_hashes[i->first]);
153 cumulative_shard_hashes[i->first] = new_hash;
156 total_chunk_size += size_to_append;
159 void ECUtil::HashInfo::encode(bufferlist &bl) const
161 ENCODE_START(1, 1, bl);
162 ::encode(total_chunk_size, bl);
163 ::encode(cumulative_shard_hashes, bl);
167 void ECUtil::HashInfo::decode(bufferlist::iterator &bl)
170 ::decode(total_chunk_size, bl);
171 ::decode(cumulative_shard_hashes, bl);
172 projected_total_chunk_size = total_chunk_size;
176 void ECUtil::HashInfo::dump(Formatter *f) const
178 f->dump_unsigned("total_chunk_size", total_chunk_size);
179 f->open_object_section("cumulative_shard_hashes");
180 for (unsigned i = 0; i != cumulative_shard_hashes.size(); ++i) {
181 f->open_object_section("hash");
182 f->dump_unsigned("shard", i);
183 f->dump_unsigned("hash", cumulative_shard_hashes[i]);
189 void ECUtil::HashInfo::generate_test_instances(list<HashInfo*>& o)
191 o.push_back(new HashInfo(3));
195 map<int, bufferlist> buffers;
199 o.back()->append(0, buffers);
200 o.back()->append(20, buffers);
202 o.push_back(new HashInfo(4));
205 const string HINFO_KEY = "hinfo_key";
207 bool ECUtil::is_hinfo_key_string(const string &key)
209 return key == HINFO_KEY;
212 const string &ECUtil::get_hinfo_key()