From 058caea370c2594bb71d24f54441206b82b12ad4 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 15 Sep 2016 11:49:32 -0400 Subject: [PATCH] os/bluestore: convert internal types to denc Signed-off-by: Sage Weil --- src/os/bluestore/BlueStore.cc | 211 ++++++++++++++--------- src/os/bluestore/BlueStore.h | 45 +++-- src/os/bluestore/bluestore_types.cc | 218 ------------------------ src/os/bluestore/bluestore_types.h | 248 +++++++++++++++++++++------- 4 files changed, 351 insertions(+), 371 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index aefa266ed21..697b2a5e1d8 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -1704,6 +1704,8 @@ bool BlueStore::ExtentMap::encode_some(uint32_t offset, uint32_t length, uint32_t end = offset + length; unsigned n = 0; + size_t bound = 0; + denc_varint(0, bound); for (auto p = start; p != extent_map.end() && p->logical_offset < end; ++p, ++n) { @@ -1714,70 +1716,91 @@ bool BlueStore::ExtentMap::encode_some(uint32_t offset, uint32_t length, << std::dec << " hit new spanning blob " << *p << dendl; return true; } - } - small_encode_varint(n, bl); - if (pn) { - *pn = n; + denc_varint(0, bound); // blobid + denc_varint(0, bound); // logical_offset + denc_varint(0, bound); // len + denc_varint(0, bound); // blob_offset + p->blob->bound_encode(bound); } - n = 0; - uint64_t pos = 0; - uint64_t prev_len = 0; - for (auto p = start; - p != extent_map.end() && p->logical_offset < end; - ++p, ++n) { - unsigned blobid; - bool include_blob = false; - if (p->blob->id >= 0) { - blobid = p->blob->id << BLOBID_SHIFT_BITS; - blobid |= BLOBID_FLAG_SPANNING; - } else if (p->blob->last_encoded_id < 0) { - p->blob->last_encoded_id = n + 1; // so it is always non-zero - include_blob = true; - blobid = 0; // the decoder will infer the id from n - } else { - blobid = p->blob->last_encoded_id << BLOBID_SHIFT_BITS; - } - if (p->logical_offset == pos) { - blobid |= BLOBID_FLAG_CONTIGUOUS; - } - if (p->blob_offset == 0) { - blobid |= BLOBID_FLAG_ZEROOFFSET; - } - if (p->length == prev_len) { - blobid |= BLOBID_FLAG_SAMELENGTH; - } else { - prev_len = p->length; - } - if (p->blob_depth != 1) { - blobid |= BLOBID_FLAG_DEPTH; - } - small_encode_varint(blobid, bl); - if ((blobid & BLOBID_FLAG_CONTIGUOUS) == 0) { - small_encode_varint_lowz(p->logical_offset - pos, bl); - } - if ((blobid & BLOBID_FLAG_ZEROOFFSET) == 0) { - small_encode_varint_lowz(p->blob_offset, bl); - } - if ((blobid & BLOBID_FLAG_SAMELENGTH) == 0) { - small_encode_varint_lowz(p->length, bl); - } - pos = p->logical_offset + p->length; - if (blobid & BLOBID_FLAG_DEPTH) { - ::encode(p->blob_depth, bl); + { + auto app = bl.get_contiguous_appender(bound); + denc_varint(n, app); + if (pn) { + *pn = n; } - if (include_blob) { - p->blob->encode(bl); + + n = 0; + uint64_t pos = 0; + uint64_t prev_len = 0; + for (auto p = start; + p != extent_map.end() && p->logical_offset < end; + ++p, ++n) { + unsigned blobid; + bool include_blob = false; + if (p->blob->id >= 0) { + blobid = p->blob->id << BLOBID_SHIFT_BITS; + blobid |= BLOBID_FLAG_SPANNING; + } else if (p->blob->last_encoded_id < 0) { + p->blob->last_encoded_id = n + 1; // so it is always non-zero + include_blob = true; + blobid = 0; // the decoder will infer the id from n + } else { + blobid = p->blob->last_encoded_id << BLOBID_SHIFT_BITS; + } + if (p->logical_offset == pos) { + blobid |= BLOBID_FLAG_CONTIGUOUS; + } + if (p->blob_offset == 0) { + blobid |= BLOBID_FLAG_ZEROOFFSET; + } + if (p->length == prev_len) { + blobid |= BLOBID_FLAG_SAMELENGTH; + } else { + prev_len = p->length; + } + if (p->blob_depth != 1) { + blobid |= BLOBID_FLAG_DEPTH; + } + denc_varint(blobid, app); + if ((blobid & BLOBID_FLAG_CONTIGUOUS) == 0) { + denc_varint_lowz(p->logical_offset - pos, app); + } + if ((blobid & BLOBID_FLAG_ZEROOFFSET) == 0) { + denc_varint_lowz(p->blob_offset, app); + } + if ((blobid & BLOBID_FLAG_SAMELENGTH) == 0) { + denc_varint_lowz(p->length, app); + } + if (blobid & BLOBID_FLAG_DEPTH) { + denc(p->blob_depth, app); + } + pos = p->logical_offset + p->length; + if (include_blob) { + p->blob->encode(app); + } } } + /*derr << __func__ << bl << dendl; + derr << __func__ << ":"; + bl.hexdump(*_dout); + *_dout << dendl; + */ return false; } void BlueStore::ExtentMap::decode_some(bufferlist& bl) { - bufferlist::iterator p = bl.begin(); + /* + derr << __func__ << ":"; + bl.hexdump(*_dout); + *_dout << dendl; + */ + + assert(bl.get_num_buffers() <= 1); + auto p = bl.front().begin_deep(); uint32_t num; - small_decode_varint(num, p); + denc_varint(num, p); vector blobs(num); uint64_t pos = 0; uint64_t prev_len = 0; @@ -1785,25 +1808,25 @@ void BlueStore::ExtentMap::decode_some(bufferlist& bl) while (!p.end()) { Extent *le = new Extent(); uint64_t blobid; - small_decode_varint(blobid, p); + denc_varint(blobid, p); if ((blobid & BLOBID_FLAG_CONTIGUOUS) == 0) { uint64_t gap; - small_decode_varint_lowz(gap, p); + denc_varint_lowz(gap, p); pos += gap; } le->logical_offset = pos; if ((blobid & BLOBID_FLAG_ZEROOFFSET) == 0) { - small_decode_varint_lowz(le->blob_offset, p); + denc_varint_lowz(le->blob_offset, p); } else { le->blob_offset = 0; } if ((blobid & BLOBID_FLAG_SAMELENGTH) == 0) { - small_decode_varint_lowz(prev_len, p); + denc_varint_lowz(prev_len, p); } le->length = prev_len; if (blobid & BLOBID_FLAG_DEPTH) { - ::decode(le->blob_depth, p); + denc(le->blob_depth, p); } else { le->blob_depth = 1; } @@ -1832,26 +1855,38 @@ void BlueStore::ExtentMap::decode_some(bufferlist& bl) assert(n == num); } -void BlueStore::ExtentMap::encode_spanning_blobs(bufferlist& bl) +void BlueStore::ExtentMap::bound_encode_spanning_blobs(size_t& p) +{ + denc_varint((uint32_t)0, p); + size_t key_size = 0; + denc_varint((uint32_t)0, key_size); + p += spanning_blob_map.size() * key_size; + for (const auto& i : spanning_blob_map) { + i.second->bound_encode(p); + i.second->ref_map.bound_encode(p); + } +} + +void BlueStore::ExtentMap::encode_spanning_blobs( + bufferlist::contiguous_appender& p) { - unsigned n = spanning_blob_map.size(); - small_encode_varint(n, bl); + denc_varint(spanning_blob_map.size(), p); for (auto& i : spanning_blob_map) { - small_encode_varint(i.second->id, bl); - i.second->encode(bl); - i.second->ref_map.encode(bl); + denc_varint(i.second->id, p); + i.second->encode(p); + i.second->ref_map.encode(p); } } void BlueStore::ExtentMap::decode_spanning_blobs( Collection *c, - bufferlist::iterator& p) + bufferptr::iterator& p) { unsigned n; - small_decode_varint(n, p); + denc_varint(n, p); while (n--) { BlobRef b(new Blob()); - small_decode_varint(b->id, p); + denc_varint(b->id, p); spanning_blob_map[b->id] = b; b->decode(p); b->ref_map.decode(p); @@ -2368,13 +2403,13 @@ BlueStore::OnodeRef BlueStore::Collection::get_onode( assert(r >= 0); on = new Onode(&onode_map, this, oid, key); on->exists = true; - bufferlist::iterator p = v.begin(); - ::decode(on->onode, p); + bufferptr::iterator p = v.front().begin(); + on->onode.decode(p); // initialize extent_map on->extent_map.decode_spanning_blobs(this, p); if (on->onode.extent_map_shards.empty()) { - ::decode(on->extent_map.inline_bl, p); + denc(on->extent_map.inline_bl, p); on->extent_map.decode_some(on->extent_map.inline_bl); } else { on->extent_map.init_shards(on, false, false); @@ -4441,7 +4476,7 @@ int BlueStore::fsck() bluestore_shared_blob_t shared_blob; bufferlist bl = it->value(); bufferlist::iterator blp = bl.begin(); - shared_blob.decode(blp); + ::decode(shared_blob, blp); dout(20) << __func__ << " " << *sbi.sb << " " << shared_blob << dendl; if (shared_blob.ref_map != sbi.ref_map) { derr << __func__ << " shared blob 0x" << std::hex << sbid << std::dec @@ -6260,20 +6295,32 @@ void BlueStore::_txc_write_nodes(TransContext *txc, KeyValueDB::Transaction t) logger->inc(l_bluestore_onode_reshard); } - bufferlist bl; - ::encode(o->onode, bl); - unsigned onode_part = bl.length(); - o->extent_map.encode_spanning_blobs(bl); - unsigned blob_part = bl.length() - onode_part; + // bound encode + size_t bound = 0; + denc(o->onode, bound); + o->extent_map.bound_encode_spanning_blobs(bound); if (o->onode.extent_map_shards.empty()) { - ::encode(o->extent_map.inline_bl, bl); + denc(o->extent_map.inline_bl, bound); + } + + // encode + bufferlist bl; + { + auto p = bl.get_contiguous_appender(bound); + denc(o->onode, p); + //unsigned onode_part = bl.length(); + o->extent_map.encode_spanning_blobs(p); + //unsigned blob_part = bl.length() - onode_part; + if (o->onode.extent_map_shards.empty()) { + denc(o->extent_map.inline_bl, p); + } + //unsigned extent_part = bl.length() - onode_part - blob_part; } - unsigned extent_part = bl.length() - onode_part - blob_part; dout(20) << " onode " << o->oid << " is " << bl.length() - << " (" << onode_part << " bytes onode + " - << blob_part << " bytes spanning blobs + " - << extent_part << " bytes inline extents)" + //<< " (" << onode_part << " bytes onode + " + //<< blob_part << " bytes spanning blobs + " + //<< extent_part << " bytes inline extents)" << dendl; t->set(PREFIX_OBJ, o->key, bl); @@ -6289,7 +6336,7 @@ void BlueStore::_txc_write_nodes(TransContext *txc, KeyValueDB::Transaction t) t->rmkey(PREFIX_SHARED_BLOB, sb->key); } else { bufferlist bl; - sb->shared_blob.encode(bl); + ::encode(sb->shared_blob, bl); dout(20) << " shared_blob 0x" << std::hex << sb->sbid << std::dec << " is " << bl.length() << dendl; t->set(PREFIX_SHARED_BLOB, sb->key, bl); diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index e93a5088a19..39ddef7a712 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -446,9 +446,6 @@ public: } return blob; } - size_t get_encoded_length() const { - return blob_bl.length(); - } bool is_dirty() const { return dirty; } @@ -477,24 +474,45 @@ public: delete this; } - void encode(bufferlist& bl) const { +//#define CACHE_BLOB_BL // not sure if this is a win yet or not... :/ + +#ifdef CACHE_BLOB_BL + void _encode() const { if (dirty) { - // manage blob_bl memory carefully blob_bl.clear(); - blob_bl.reserve(blob.estimate_encoded_size()); ::encode(blob, blob_bl); dirty = false; } else { assert(blob_bl.length()); } - bl.append(blob_bl); } - void decode(bufferlist::iterator& p) { - bufferlist::iterator s = p; - ::decode(blob, p); - s.copy(p.get_off() - s.get_off(), blob_bl); + void bound_encode(size_t& p) const { + _encode(); + p += blob_bl.length(); + } + void encode(bufferlist::contiguous_appender& p) const { + _encode(); + p.append(blob_bl); + } + void decode(bufferptr::iterator& p) { + const char *start = p.get_pos(); + denc(blob, p); + const char *end = p.get_pos(); + blob_bl.clear(); + blob_bl.append(start, end - start); dirty = false; } +#else + void bound_encode(size_t& p) const { + denc(blob, p); + } + void encode(bufferlist::contiguous_appender& p) const { + denc(blob, p); + } + void decode(bufferptr::iterator& p) { + denc(blob, p); + } +#endif }; typedef boost::intrusive_ptr BlobRef; typedef std::map blob_map_t; @@ -590,8 +608,9 @@ public: unsigned *pn); void decode_some(bufferlist& bl); - void encode_spanning_blobs(bufferlist& bl); - void decode_spanning_blobs(Collection *c, bufferlist::iterator& p); + void bound_encode_spanning_blobs(size_t& p); + void encode_spanning_blobs(bufferlist::contiguous_appender& p); + void decode_spanning_blobs(Collection *c, bufferptr::iterator& p); BlobRef get_spanning_blob(int id) { auto p = spanning_blob_map.find(id); diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc index 3976bad5ab3..c7be9a2f5f7 100644 --- a/src/os/bluestore/bluestore_types.cc +++ b/src/os/bluestore/bluestore_types.cc @@ -98,20 +98,6 @@ ostream& operator<<(ostream& out, const bluestore_bdev_label_t& l) // cnode_t -void bluestore_cnode_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(bits, bl); - ENCODE_FINISH(bl); -} - -void bluestore_cnode_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(bits, p); - DECODE_FINISH(p); -} - void bluestore_cnode_t::dump(Formatter *f) const { f->dump_unsigned("bits", bits); @@ -124,29 +110,6 @@ void bluestore_cnode_t::generate_test_instances(list& o) o.push_back(new bluestore_cnode_t(123)); } -// bluestore_pextent_t - -void small_encode(const vector& v, bufferlist& bl) -{ - size_t n = v.size(); - small_encode_varint(n, bl); - for (auto e : v) { - e.encode(bl); - } -} - -void small_decode(vector& v, bufferlist::iterator& p) -{ - size_t n; - small_decode_varint(n, p); - v.clear(); - v.reserve(n); - while (n--) { - v.push_back(bluestore_pextent_t()); - ::decode(v.back(), p); - } -} - // bluestore_extent_ref_map_t void bluestore_extent_ref_map_t::_check() const @@ -334,41 +297,6 @@ bool bluestore_extent_ref_map_t::intersects( return true; // intersects p! } -void bluestore_extent_ref_map_t::encode(bufferlist& bl) const -{ - uint32_t n = ref_map.size(); - small_encode_varint(n, bl); - if (n) { - auto p = ref_map.begin(); - small_encode_varint_lowz(p->first, bl); - p->second.encode(bl); - int64_t pos = p->first; - while (--n) { - ++p; - small_encode_varint_lowz(p->first - pos, bl); - p->second.encode(bl); - pos = p->first; - } - } -} - -void bluestore_extent_ref_map_t::decode(bufferlist::iterator& p) -{ - uint32_t n; - small_decode_varint(n, p); - if (n) { - int64_t pos; - small_decode_varint_lowz(pos, p); - ref_map[pos].decode(p); - while (--n) { - int64_t delta; - small_decode_varint_lowz(delta, p); - pos += delta; - ref_map[pos].decode(p); - } - } -} - void bluestore_extent_ref_map_t::dump(Formatter *f) const { f->open_array_section("ref_map"); @@ -460,59 +388,6 @@ string bluestore_blob_t::get_flags_string(unsigned flags) return s; } -void bluestore_blob_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - small_encode(extents, bl); - small_encode_varint(flags, bl); - if (is_shared()) { - small_encode_varint(sbid, bl); - } - if (is_compressed()) { - small_encode_varint_lowz(compressed_length_orig, bl); - small_encode_varint_lowz(compressed_length, bl); - } - if (has_csum()) { - ::encode(csum_type, bl); - ::encode(csum_chunk_order, bl); - small_encode_buf_lowz(csum_data, bl); - } - if (has_unused()) { - ::encode(unused_uint_t(unused.to_ullong()), bl); - } - ENCODE_FINISH(bl); -} - -void bluestore_blob_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - small_decode(extents, p); - small_decode_varint(flags, p); - if (is_shared()) { - small_decode_varint(sbid, p); - } - if (is_compressed()) { - small_decode_varint_lowz(compressed_length_orig, p); - small_decode_varint_lowz(compressed_length, p); - } else { - compressed_length_orig = compressed_length = 0; - } - if (has_csum()) { - ::decode(csum_type, p); - ::decode(csum_chunk_order, p); - small_decode_buf_lowz(csum_data, p); - } else { - csum_type = CSUM_NONE; - csum_chunk_order = 0; - } - if (has_unused()) { - unused_uint_t val; - ::decode(val, p); - unused = unused_t(val); - } - DECODE_FINISH(p); -} - void bluestore_blob_t::dump(Formatter *f) const { f->open_array_section("extents"); @@ -646,19 +521,6 @@ int bluestore_blob_t::verify_csum(uint64_t b_off, const bufferlist& bl, } // bluestore_shared_blob_t -void bluestore_shared_blob_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(ref_map, bl); - ENCODE_FINISH(bl); -} - -void bluestore_shared_blob_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(ref_map, p); - DECODE_FINISH(p); -} void bluestore_shared_blob_t::dump(Formatter *f) const { @@ -692,34 +554,6 @@ ostream& operator<<(ostream& out, const bluestore_onode_t::shard_info& si) << std::dec << si.extents << " extents)"; } -void bluestore_onode_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(nid, bl); - ::encode(size, bl); - ::encode(attrs, bl); - ::encode(omap_head, bl); - ::encode(extent_map_shards, bl); - ::encode(expected_object_size, bl); - ::encode(expected_write_size, bl); - ::encode(alloc_hint_flags, bl); - ENCODE_FINISH(bl); -} - -void bluestore_onode_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(nid, p); - ::decode(size, p); - ::decode(attrs, p); - ::decode(omap_head, p); - ::decode(extent_map_shards, p); - ::decode(expected_object_size, p); - ::decode(expected_write_size, p); - ::decode(alloc_hint_flags, p); - DECODE_FINISH(p); -} - void bluestore_onode_t::dump(Formatter *f) const { f->dump_unsigned("nid", nid); @@ -764,24 +598,6 @@ size_t bluestore_onode_t::get_preferred_csum_order() const // bluestore_wal_op_t -void bluestore_wal_op_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(op, bl); - ::encode(extents, bl); - ::encode(data, bl); - ENCODE_FINISH(bl); -} - -void bluestore_wal_op_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(op, p); - ::decode(extents, p); - ::decode(data, p); - DECODE_FINISH(p); -} - void bluestore_wal_op_t::dump(Formatter *f) const { f->dump_unsigned("op", (int)op); @@ -803,24 +619,6 @@ void bluestore_wal_op_t::generate_test_instances(list& o) o.back()->data.append("my data"); } -void bluestore_wal_transaction_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(seq, bl); - ::encode(ops, bl); - ::encode(released, bl); - ENCODE_FINISH(bl); -} - -void bluestore_wal_transaction_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(seq, p); - ::decode(ops, p); - ::decode(released, p); - DECODE_FINISH(p); -} - void bluestore_wal_transaction_t::dump(Formatter *f) const { f->dump_unsigned("seq", seq); @@ -852,22 +650,6 @@ void bluestore_wal_transaction_t::generate_test_instances(listops.back().data.append("foodata"); } -void bluestore_compression_header_t::encode(bufferlist& bl) const -{ - ENCODE_START(1, 1, bl); - ::encode(type, bl); - ::encode(length, bl); - ENCODE_FINISH(bl); -} - -void bluestore_compression_header_t::decode(bufferlist::iterator& p) -{ - DECODE_START(1, p); - ::decode(type, p); - ::decode(length, p); - DECODE_FINISH(p); -} - void bluestore_compression_header_t::dump(Formatter *f) const { f->dump_unsigned("type", type); diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index e953a39d286..e1babc66ba4 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -49,12 +49,15 @@ struct bluestore_cnode_t { explicit bluestore_cnode_t(int b=0) : bits(b) {} - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_cnode_t, v, p) { + DENC_START(1, 1, p); + denc(v.bits, p); + DENC_FINISH(p); + } void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_cnode_t) +WRITE_CLASS_DENC(bluestore_cnode_t) class AllocExtent { public: @@ -128,40 +131,59 @@ struct bluestore_pextent_t : public AllocExtent{ return offset != INVALID_OFFSET; } - void encode(bufferlist& bl) const { - small_encode_lba(offset, bl); - small_encode_varint_lowz(length, bl); - } - void decode(bufferlist::iterator& p) { - small_decode_lba(offset, p); - small_decode_varint_lowz(length, p); + DENC(bluestore_pextent_t, v, p) { + denc(v.offset, p); + denc(v.length, p); } + void dump(Formatter *f) const; static void generate_test_instances(list& ls); }; -WRITE_CLASS_ENCODER(bluestore_pextent_t) +WRITE_CLASS_DENC(bluestore_pextent_t) ostream& operator<<(ostream& out, const bluestore_pextent_t& o); -void small_encode(const vector& v, bufferlist& bl); -void small_decode(vector& v, bufferlist::iterator& p); +template<> +struct denc_traits> { + enum { supported = true }; + enum { bounded = false }; + enum { featured = false }; + static void bound_encode(const vector& v, size_t& p) { + p += sizeof(uint32_t); + size_t per = 0; + denc(*(bluestore_pextent_t*)nullptr, per); + p += per * v.size(); + } + static void encode(const vector& v, + bufferlist::contiguous_appender& p) { + denc_varint(v.size(), p); + for (auto& i : v) { + denc(i, p); + } + } + static void decode(vector& v, bufferptr::iterator& p) { + unsigned num; + denc_varint(num, p); + v.clear(); + v.resize(num); + for (unsigned i=0; i ref_map; @@ -181,13 +203,50 @@ struct bluestore_extent_ref_map_t { bool contains(uint64_t offset, uint32_t len) const; bool intersects(uint64_t offset, uint32_t len) const; - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + void bound_encode(size_t& p) const { + denc((uint32_t)0, p); + size_t elem_size = 0; + denc_varint_lowz((uint32_t)0, p); + ((const record_t*)nullptr)->bound_encode(elem_size); + p += elem_size * ref_map.size(); + } + void encode(bufferlist::contiguous_appender& p) const { + uint32_t n = ref_map.size(); + denc_varint(n, p); + if (n) { + auto i = ref_map.begin(); + denc_varint_lowz(i->first, p); + i->second.encode(p); + int64_t pos = i->first; + while (--n) { + ++i; + denc_varint_lowz((int64_t)i->first - pos, p); + i->second.encode(p); + pos = i->first; + } + } + } + void decode(bufferptr::iterator& p) { + uint32_t n; + denc_varint(n, p); + if (n) { + int64_t pos; + denc_varint_lowz(pos, p); + ref_map[pos].decode(p); + while (--n) { + int64_t delta; + denc_varint_lowz(delta, p); + pos += delta; + ref_map[pos].decode(p); + } + } + } + void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_extent_ref_map_t::record_t) -WRITE_CLASS_ENCODER(bluestore_extent_ref_map_t) +WRITE_CLASS_DENC(bluestore_extent_ref_map_t) + ostream& operator<<(ostream& out, const bluestore_extent_ref_map_t& rm); static inline bool operator==(const bluestore_extent_ref_map_t::record_t& l, @@ -294,9 +353,62 @@ struct bluestore_blob_t { bluestore_blob_t(uint32_t f = 0) : flags(f) {} - int estimate_encoded_size() const { - // conservative upper bound... fixme - return csum_data.length() + extents.size() * 16 + 24; + DENC_HELPERS; + void bound_encode(size_t& p) const { + p += 2 + 4; + denc(extents, p); + denc_varint(flags, p); + denc_varint(sbid, p); + denc_varint_lowz(compressed_length_orig, p); + denc_varint_lowz(compressed_length, p); + denc(csum_type, p); + denc(csum_chunk_order, p); + denc(csum_data, p); + p += sizeof(unsigned long long); + } + void encode(bufferlist::contiguous_appender& p) const { + DENC_START(1, 1, p); + denc(extents, p); + denc_varint(flags, p); + if (is_shared()) { + denc_varint(sbid, p); + } + if (is_compressed()) { + denc_varint_lowz(compressed_length_orig, p); + denc_varint_lowz(compressed_length, p); + } + if (has_csum()) { + denc(csum_type, p); + denc(csum_chunk_order, p); + denc(csum_data, p); + } + if (has_unused()) { + denc(unused_uint_t(unused.to_ullong()), p); + } + DENC_FINISH(p); + } + void decode(bufferptr::iterator& p) { + DENC_START(1, 1, p); + denc(extents, p); + denc_varint(flags, p); + if (is_shared()) { + denc_varint(sbid, p); + } + if (is_compressed()) { + denc_varint_lowz(compressed_length_orig, p); + denc_varint_lowz(compressed_length, p); + } + if (has_csum()) { + denc(csum_type, p); + denc(csum_chunk_order, p); + denc(csum_data, p); + } + if (has_unused()) { + unused_uint_t val; + denc(val, p); + unused = unused_t(val); + } + DENC_FINISH(p); } bool can_split() const { @@ -312,8 +424,6 @@ struct bluestore_blob_t { return true; } - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); void dump(Formatter *f) const; static void generate_test_instances(list& ls); @@ -596,7 +706,7 @@ struct bluestore_blob_t { } } }; -WRITE_CLASS_ENCODER(bluestore_blob_t) +WRITE_CLASS_DENC(bluestore_blob_t) ostream& operator<<(ostream& out, const bluestore_blob_t& o); @@ -605,8 +715,12 @@ ostream& operator<<(ostream& out, const bluestore_blob_t& o); struct bluestore_shared_blob_t { bluestore_extent_ref_map_t ref_map; ///< shared blob extents - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_shared_blob_t, v, p) { + DENC_START(1, 1, p); + denc(v.ref_map, p); + DENC_FINISH(p); + } + void dump(Formatter *f) const; static void generate_test_instances(list& ls); @@ -614,7 +728,7 @@ struct bluestore_shared_blob_t { return ref_map.empty(); } }; -WRITE_CLASS_ENCODER(bluestore_shared_blob_t) +WRITE_CLASS_DENC(bluestore_shared_blob_t) ostream& operator<<(ostream& out, const bluestore_shared_blob_t& o); @@ -629,19 +743,13 @@ struct bluestore_onode_t { uint32_t offset = 0; ///< logical offset for start of shard uint32_t bytes = 0; ///< encoded bytes uint32_t extents = 0; ///< extents - void encode(bufferlist& bl) const { - ::encode(offset, bl); - ::encode(bytes, bl); - ::encode(extents, bl); - } - void decode(bufferlist::iterator& p) { - ::decode(offset, p); - ::decode(bytes, p); - ::decode(extents, p); + DENC(shard_info, v, p) { + denc(v.offset, p); + denc(v.bytes, p); + denc(v.extents, p); } void dump(Formatter *f) const; }; - WRITE_CLASS_ENCODER(shard_info) vector extent_map_shards; ///< extent map shards (if any) uint32_t expected_object_size = 0; @@ -651,13 +759,23 @@ struct bluestore_onode_t { /// get preferred csum chunk size size_t get_preferred_csum_order() const; - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_onode_t, v, p) { + DENC_START(1, 1, p); + denc(v.nid, p); + denc(v.size, p); + denc(v.attrs, p); + denc(v.omap_head, p); + denc(v.extent_map_shards, p); + denc(v.expected_object_size, p); + denc(v.expected_write_size, p); + denc(v.alloc_hint_flags, p); + DENC_FINISH(p); + } void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_onode_t::shard_info) -WRITE_CLASS_ENCODER(bluestore_onode_t) +WRITE_CLASS_DENC(bluestore_onode_t::shard_info) +WRITE_CLASS_DENC(bluestore_onode_t) ostream& operator<<(ostream& out, const bluestore_onode_t::shard_info& si); @@ -671,12 +789,17 @@ struct bluestore_wal_op_t { vector extents; bufferlist data; - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_wal_op_t, v, p) { + DENC_START(1, 1, p); + denc(v.op, p); + denc(v.extents, p); + denc(v.data, p); + DENC_FINISH(p); + } void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_wal_op_t) +WRITE_CLASS_DENC(bluestore_wal_op_t) /// writeahead-logged transaction @@ -687,12 +810,17 @@ struct bluestore_wal_transaction_t { bluestore_wal_transaction_t() : seq(0) {} - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_wal_transaction_t, v, p) { + DENC_START(1, 1, p); + denc(v.seq, p); + denc(v.ops, p); + denc(v.released, p); + DENC_FINISH(p); + } void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_wal_transaction_t) +WRITE_CLASS_DENC(bluestore_wal_transaction_t) struct bluestore_compression_header_t { uint8_t type = bluestore_blob_t::COMP_ALG_NONE; @@ -702,12 +830,16 @@ struct bluestore_compression_header_t { bluestore_compression_header_t(uint8_t _type) : type(_type) {} - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); + DENC(bluestore_compression_header_t, v, p) { + DENC_START(1, 1, p); + denc(v.type, p); + denc(v.length, p); + DENC_FINISH(p); + } void dump(Formatter *f) const; static void generate_test_instances(list& o); }; -WRITE_CLASS_ENCODER(bluestore_compression_header_t) +WRITE_CLASS_DENC(bluestore_compression_header_t) #endif -- 2.39.5