From d9dab11d514a19031c78efc9332c441a111a6fdc 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 | 192 ++++++++++++--------- src/os/bluestore/BlueStore.h | 45 +++-- src/os/bluestore/bluestore_types.cc | 223 ------------------------- src/os/bluestore/bluestore_types.h | 247 +++++++++++++++++++++------- 4 files changed, 336 insertions(+), 371 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index ce8ab1c9f555c..d49f6fa6381e4 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -1613,6 +1613,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) { @@ -1623,57 +1625,66 @@ 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; - } - 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); + { + auto app = bl.get_contiguous_appender(bound); + denc_varint(n, app); + if (pn) { + *pn = n; } - pos = p->logical_offset + p->length; - 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; + } + 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); + } + pos = p->logical_offset + p->length; + if (include_blob) { + p->blob->encode(app); + } } } - /* + /*derr << __func__ << bl << dendl; derr << __func__ << ":"; bl.hexdump(*_dout); *_dout << dendl; @@ -1683,13 +1694,16 @@ bool BlueStore::ExtentMap::encode_some(uint32_t offset, uint32_t length, void BlueStore::ExtentMap::decode_some(bufferlist& bl) { -/* derr << __func__ << ":"; + /* + derr << __func__ << ":"; bl.hexdump(*_dout); *_dout << dendl; */ - bufferlist::iterator p = bl.begin(); + + 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; @@ -1697,20 +1711,20 @@ 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_SPANNING) { @@ -1737,26 +1751,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.bound_encode(p); + i.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& b : spanning_blob_map) { - small_encode_varint(b.id, bl); - b.encode(bl); - b.ref_map.encode(bl); + denc_varint(b.id, p); + b.encode(p); + b.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.insert(*b); b->get(); b->decode(p); @@ -2133,13 +2159,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); @@ -4172,7 +4198,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 @@ -5958,20 +5984,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); @@ -5987,7 +6025,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 a734c023d7beb..be51ef6e69c51 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -440,9 +440,6 @@ class BlueStore : public ObjectStore, } return blob; } - size_t get_encoded_length() const { - return blob_bl.length(); - } bool is_dirty() const { return dirty; } @@ -468,24 +465,45 @@ class BlueStore : public ObjectStore, 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.push_back(p.get_preceding_ptr(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 boost::intrusive::set blob_map_t; @@ -553,8 +571,9 @@ class BlueStore : public ObjectStore, 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); diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc index 3e1a0f3547155..c1db12f98ffc0 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 @@ -333,41 +296,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); - int32_t pos = p->first; - while (--n) { - ++p; - small_encode_varint_lowz((int64_t)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"); @@ -458,59 +386,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"); @@ -642,28 +517,10 @@ 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 { f->dump_object("ref_map", ref_map); - f->open_array_section("objects"); - /*for (auto &o : objects) { - f->dump_object("object", o); - }*/ - f->close_section(); } void bluestore_shared_blob_t::generate_test_instances( @@ -693,34 +550,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); @@ -765,24 +594,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); @@ -804,24 +615,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); @@ -853,22 +646,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 15a5925cabdbc..fe5a922078188 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,23 +131,47 @@ 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(uint32_t offset, uint32_t len) const; bool intersects(uint32_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); + int32_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,13 +353,64 @@ 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 + 48; + 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); } - void encode(bufferlist& bl) const; - void decode(bufferlist::iterator& p); void dump(Formatter *f) const; static void generate_test_instances(list& ls); @@ -567,7 +677,7 @@ struct bluestore_blob_t { uint64_t *bad_csum) const; }; -WRITE_CLASS_ENCODER(bluestore_blob_t) +WRITE_CLASS_DENC(bluestore_blob_t) ostream& operator<<(ostream& out, const bluestore_blob_t& o); @@ -575,10 +685,13 @@ ostream& operator<<(ostream& out, const bluestore_blob_t& o); /// shared blob state struct bluestore_shared_blob_t { bluestore_extent_ref_map_t ref_map; ///< shared blob extents - //set objects; ///< objects referencing these shared blocks (debug) - 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); @@ -586,7 +699,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); @@ -601,19 +714,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; @@ -623,13 +730,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); @@ -643,12 +760,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 @@ -659,12 +781,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; @@ -674,12 +801,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