]> git.proxmox.com Git - ceph.git/blame - ceph/src/cls/cas/cls_cas_internal.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / cls / cas / cls_cas_internal.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "cls_cas_internal.h"
5
6
7chunk_refs_t::chunk_refs_t(const chunk_refs_t& other)
8{
9 *this = other;
10}
11
12chunk_refs_t& chunk_refs_t::operator=(const chunk_refs_t& other)
13{
14 // this is inefficient, but easy.
15 bufferlist bl;
16 other.encode(bl);
17 auto p = bl.cbegin();
18 decode(p);
19 return *this;
20}
21
22void chunk_refs_t::clear()
23{
24 // default to most precise impl
25 r.reset(new chunk_refs_by_object_t);
26}
27
28
29void chunk_refs_t::encode(ceph::buffer::list& bl) const
30{
31 bufferlist t;
32 _encode_r(t);
33 _encode_final(bl, t);
34}
35
36void chunk_refs_t::_encode_r(ceph::bufferlist& bl) const
37{
38 using ceph::encode;
39 switch (r->get_type()) {
40 case TYPE_BY_OBJECT:
41 encode(*(chunk_refs_by_object_t*)r.get(), bl);
42 break;
43 case TYPE_BY_HASH:
44 encode(*(chunk_refs_by_hash_t*)r.get(), bl);
45 break;
46 case TYPE_BY_POOL:
47 encode(*(chunk_refs_by_pool_t*)r.get(), bl);
48 break;
49 case TYPE_COUNT:
50 encode(*(chunk_refs_count_t*)r.get(), bl);
51 break;
52 default:
53 ceph_abort("unrecognized ref type");
54 }
55}
56
57void chunk_refs_t::dynamic_encode(ceph::buffer::list& bl, size_t max)
58{
59 bufferlist t;
60 while (true) {
61 _encode_r(t);
62 // account for the additional overhead in _encode_final
63 if (t.length() + 8 <= max) {
64 break;
65 }
66 // downgrade resolution
67 std::unique_ptr<refs_t> n;
68 switch (r->get_type()) {
69 case TYPE_BY_OBJECT:
70 r.reset(new chunk_refs_by_hash_t(
71 static_cast<chunk_refs_by_object_t*>(r.get())));
72 break;
73 case TYPE_BY_HASH:
74 if (!static_cast<chunk_refs_by_hash_t*>(r.get())->shrink()) {
75 r.reset(new chunk_refs_by_pool_t(
76 static_cast<chunk_refs_by_hash_t*>(r.get())));
77 }
78 break;
79 case TYPE_BY_POOL:
80 r.reset(new chunk_refs_count_t(r.get()));
81 break;
82 }
83 t.clear();
84 }
85 _encode_final(bl, t);
86}
87
88void chunk_refs_t::_encode_final(bufferlist& bl, bufferlist& t) const
89{
90 ENCODE_START(1, 1, bl);
91 encode(r->get_type(), bl);
92 bl.claim_append(t);
93 ENCODE_FINISH(bl);
94}
95
96void chunk_refs_t::decode(ceph::buffer::list::const_iterator& p)
97{
98 DECODE_START(1, p);
99 uint8_t t;
100 decode(t, p);
101 switch (t) {
102 case TYPE_BY_OBJECT:
103 {
104 auto n = new chunk_refs_by_object_t();
105 decode(*n, p);
106 r.reset(n);
107 }
108 break;
109 case TYPE_BY_HASH:
110 {
111 auto n = new chunk_refs_by_hash_t();
112 decode(*n, p);
113 r.reset(n);
114 }
115 break;
116 case TYPE_BY_POOL:
117 {
118 auto n = new chunk_refs_by_pool_t();
119 decode(*n, p);
120 r.reset(n);
121 }
122 break;
123 case TYPE_COUNT:
124 {
125 auto n = new chunk_refs_count_t();
126 decode(*n, p);
127 r.reset(n);
128 }
129 break;
130 default:
131 throw ceph::buffer::malformed_input(
20effc67
TL
132 std::string("unrecognized chunk ref encoding type ") +
133 stringify((int)t));
f67539c2
TL
134 }
135 DECODE_FINISH(p);
136}