From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/cls/cas/cls_cas_internal.cc | 135 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/cls/cas/cls_cas_internal.cc (limited to 'src/cls/cas/cls_cas_internal.cc') diff --git a/src/cls/cas/cls_cas_internal.cc b/src/cls/cas/cls_cas_internal.cc new file mode 100644 index 000000000..edaa96d27 --- /dev/null +++ b/src/cls/cas/cls_cas_internal.cc @@ -0,0 +1,135 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "cls_cas_internal.h" + + +chunk_refs_t::chunk_refs_t(const chunk_refs_t& other) +{ + *this = other; +} + +chunk_refs_t& chunk_refs_t::operator=(const chunk_refs_t& other) +{ + // this is inefficient, but easy. + bufferlist bl; + other.encode(bl); + auto p = bl.cbegin(); + decode(p); + return *this; +} + +void chunk_refs_t::clear() +{ + // default to most precise impl + r.reset(new chunk_refs_by_object_t); +} + + +void chunk_refs_t::encode(ceph::buffer::list& bl) const +{ + bufferlist t; + _encode_r(t); + _encode_final(bl, t); +} + +void chunk_refs_t::_encode_r(ceph::bufferlist& bl) const +{ + using ceph::encode; + switch (r->get_type()) { + case TYPE_BY_OBJECT: + encode(*(chunk_refs_by_object_t*)r.get(), bl); + break; + case TYPE_BY_HASH: + encode(*(chunk_refs_by_hash_t*)r.get(), bl); + break; + case TYPE_BY_POOL: + encode(*(chunk_refs_by_pool_t*)r.get(), bl); + break; + case TYPE_COUNT: + encode(*(chunk_refs_count_t*)r.get(), bl); + break; + default: + ceph_abort("unrecognized ref type"); + } +} + +void chunk_refs_t::dynamic_encode(ceph::buffer::list& bl, size_t max) +{ + bufferlist t; + while (true) { + _encode_r(t); + // account for the additional overhead in _encode_final + if (t.length() + 8 <= max) { + break; + } + // downgrade resolution + std::unique_ptr n; + switch (r->get_type()) { + case TYPE_BY_OBJECT: + r.reset(new chunk_refs_by_hash_t( + static_cast(r.get()))); + break; + case TYPE_BY_HASH: + if (!static_cast(r.get())->shrink()) { + r.reset(new chunk_refs_by_pool_t( + static_cast(r.get()))); + } + break; + case TYPE_BY_POOL: + r.reset(new chunk_refs_count_t(r.get())); + break; + } + t.clear(); + } + _encode_final(bl, t); +} + +void chunk_refs_t::_encode_final(bufferlist& bl, bufferlist& t) const +{ + ENCODE_START(1, 1, bl); + encode(r->get_type(), bl); + bl.claim_append(t); + ENCODE_FINISH(bl); +} + +void chunk_refs_t::decode(ceph::buffer::list::const_iterator& p) +{ + DECODE_START(1, p); + uint8_t t; + decode(t, p); + switch (t) { + case TYPE_BY_OBJECT: + { + auto n = new chunk_refs_by_object_t(); + decode(*n, p); + r.reset(n); + } + break; + case TYPE_BY_HASH: + { + auto n = new chunk_refs_by_hash_t(); + decode(*n, p); + r.reset(n); + } + break; + case TYPE_BY_POOL: + { + auto n = new chunk_refs_by_pool_t(); + decode(*n, p); + r.reset(n); + } + break; + case TYPE_COUNT: + { + auto n = new chunk_refs_count_t(); + decode(*n, p); + r.reset(n); + } + break; + default: + throw ceph::buffer::malformed_input( + "unrecognized chunk ref encoding type "s + stringify((int)t)); + } + DECODE_FINISH(p); +} -- cgit v1.2.3