]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | ||
6 | #include "crimson/os/seastore/seastore_types.h" | |
7 | #include "crimson/os/seastore/transaction_manager.h" | |
8 | #include "crimson/os/seastore/collection_manager.h" | |
9 | ||
10 | namespace crimson::os::seastore::collection_manager { | |
11 | struct coll_context_t { | |
12 | TransactionManager &tm; | |
13 | Transaction &t; | |
14 | }; | |
15 | ||
16 | using base_coll_map_t = std::map<denc_coll_t, uint32_t>; | |
17 | struct coll_map_t : base_coll_map_t { | |
18 | auto insert(coll_t coll, unsigned bits) { | |
19 | return emplace( | |
20 | std::make_pair(denc_coll_t{coll}, bits) | |
21 | ); | |
22 | } | |
23 | ||
24 | void update(coll_t coll, unsigned bits) { | |
25 | (*this)[denc_coll_t{coll}] = bits; | |
26 | } | |
27 | ||
28 | void remove(coll_t coll) { | |
29 | erase(denc_coll_t{coll}); | |
30 | } | |
31 | }; | |
32 | ||
33 | struct delta_t { | |
34 | enum class op_t : uint_fast8_t { | |
35 | INSERT, | |
36 | UPDATE, | |
37 | REMOVE, | |
38 | INVALID | |
39 | } op = op_t::INVALID; | |
40 | ||
41 | denc_coll_t coll; | |
42 | uint32_t bits = 0; | |
43 | ||
20effc67 TL |
44 | DENC(delta_t, v, p) { |
45 | DENC_START(1, 1, p); | |
46 | denc(v.op, p); | |
47 | denc(v.coll, p); | |
48 | denc(v.bits, p); | |
49 | DENC_FINISH(p); | |
50 | } | |
51 | ||
52 | void replay(coll_map_t &l) const; | |
53 | }; | |
54 | } | |
55 | WRITE_CLASS_DENC(crimson::os::seastore::collection_manager::delta_t) | |
56 | ||
57 | namespace crimson::os::seastore::collection_manager { | |
58 | class delta_buffer_t { | |
59 | std::vector<delta_t> buffer; | |
60 | public: | |
61 | bool empty() const { | |
62 | return buffer.empty(); | |
63 | } | |
64 | ||
65 | void insert(coll_t coll, uint32_t bits) { | |
66 | buffer.push_back(delta_t{delta_t::op_t::INSERT, denc_coll_t(coll), bits}); | |
67 | } | |
68 | void update(coll_t coll, uint32_t bits) { | |
69 | buffer.push_back(delta_t{delta_t::op_t::UPDATE, denc_coll_t(coll), bits}); | |
70 | } | |
71 | void remove(coll_t coll) { | |
72 | buffer.push_back(delta_t{delta_t::op_t::REMOVE, denc_coll_t(coll), 0}); | |
73 | } | |
74 | void replay(coll_map_t &l) { | |
75 | for (auto &i: buffer) { | |
76 | i.replay(l); | |
77 | } | |
78 | } | |
79 | ||
80 | void clear() { buffer.clear(); } | |
81 | ||
82 | DENC(delta_buffer_t, v, p) { | |
83 | DENC_START(1, 1, p); | |
84 | denc(v.buffer, p); | |
85 | DENC_FINISH(p); | |
86 | } | |
87 | }; | |
88 | } | |
89 | WRITE_CLASS_DENC(crimson::os::seastore::collection_manager::delta_buffer_t) | |
90 | ||
91 | namespace crimson::os::seastore::collection_manager { | |
92 | ||
93 | struct CollectionNode | |
94 | : LogicalCachedExtent { | |
95 | using CollectionNodeRef = TCachedExtentRef<CollectionNode>; | |
96 | ||
aee94f69 TL |
97 | explicit CollectionNode(ceph::bufferptr &&ptr) |
98 | : LogicalCachedExtent(std::move(ptr)) {} | |
99 | explicit CollectionNode(const CollectionNode &other) | |
100 | : LogicalCachedExtent(other), | |
101 | decoded(other.decoded) {} | |
20effc67 TL |
102 | |
103 | static constexpr extent_types_t type = extent_types_t::COLL_BLOCK; | |
104 | ||
105 | coll_map_t decoded; | |
106 | delta_buffer_t delta_buffer; | |
107 | ||
1e59de90 | 108 | CachedExtentRef duplicate_for_write(Transaction&) final { |
20effc67 TL |
109 | assert(delta_buffer.empty()); |
110 | return CachedExtentRef(new CollectionNode(*this)); | |
111 | } | |
112 | delta_buffer_t *maybe_get_delta_buffer() { | |
113 | return is_mutation_pending() ? &delta_buffer : nullptr; | |
114 | } | |
115 | ||
116 | using list_iertr = CollectionManager::list_iertr; | |
117 | using list_ret = CollectionManager::list_ret; | |
118 | list_ret list(); | |
119 | ||
120 | ||
121 | enum class create_result_t : uint8_t { | |
122 | SUCCESS, | |
123 | OVERFLOW | |
124 | }; | |
125 | using create_iertr = CollectionManager::create_iertr; | |
126 | using create_ret = create_iertr::future<create_result_t>; | |
127 | create_ret create(coll_context_t cc, coll_t coll, unsigned bits); | |
128 | ||
129 | using remove_iertr = CollectionManager::remove_iertr; | |
130 | using remove_ret = CollectionManager::remove_ret; | |
131 | remove_ret remove(coll_context_t cc, coll_t coll); | |
132 | ||
133 | using update_iertr = CollectionManager::update_iertr; | |
134 | using update_ret = CollectionManager::update_ret; | |
135 | update_ret update(coll_context_t cc, coll_t coll, unsigned bits); | |
136 | ||
aee94f69 | 137 | void on_clean_read() final { |
20effc67 TL |
138 | bufferlist bl; |
139 | bl.append(get_bptr()); | |
140 | auto iter = bl.cbegin(); | |
141 | decode((base_coll_map_t&)decoded, iter); | |
20effc67 TL |
142 | } |
143 | ||
144 | void copy_to_node() { | |
145 | bufferlist bl; | |
146 | encode((base_coll_map_t&)decoded, bl); | |
147 | auto iter = bl.begin(); | |
148 | auto size = encoded_sizeof((base_coll_map_t&)decoded); | |
149 | assert(size <= get_bptr().length()); | |
150 | get_bptr().zero(); | |
151 | iter.copy(size, get_bptr().c_str()); | |
152 | ||
153 | } | |
154 | ||
155 | ceph::bufferlist get_delta() final { | |
156 | assert(!delta_buffer.empty()); | |
157 | ceph::bufferlist bl; | |
158 | encode(delta_buffer, bl); | |
159 | delta_buffer.clear(); | |
160 | return bl; | |
161 | } | |
162 | ||
163 | void apply_delta(const ceph::bufferlist &bl) final { | |
164 | assert(bl.length()); | |
165 | delta_buffer_t buffer; | |
166 | auto bptr = bl.begin(); | |
167 | decode(buffer, bptr); | |
168 | buffer.replay(decoded); | |
169 | copy_to_node(); | |
170 | } | |
171 | ||
172 | static constexpr extent_types_t TYPE = extent_types_t::COLL_BLOCK; | |
173 | extent_types_t get_type() const final { | |
174 | return TYPE; | |
175 | } | |
176 | ||
177 | std::ostream &print_detail_l(std::ostream &out) const final; | |
178 | }; | |
179 | using CollectionNodeRef = CollectionNode::CollectionNodeRef; | |
180 | } | |
1e59de90 TL |
181 | |
182 | #if FMT_VERSION >= 90000 | |
183 | template <> struct fmt::formatter<crimson::os::seastore::collection_manager::CollectionNode> : fmt::ostream_formatter {}; | |
184 | #endif |