]>
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 | ||
44 | delta_t() = default; | |
45 | ||
46 | DENC(delta_t, v, p) { | |
47 | DENC_START(1, 1, p); | |
48 | denc(v.op, p); | |
49 | denc(v.coll, p); | |
50 | denc(v.bits, p); | |
51 | DENC_FINISH(p); | |
52 | } | |
53 | ||
54 | void replay(coll_map_t &l) const; | |
55 | }; | |
56 | } | |
57 | WRITE_CLASS_DENC(crimson::os::seastore::collection_manager::delta_t) | |
58 | ||
59 | namespace crimson::os::seastore::collection_manager { | |
60 | class delta_buffer_t { | |
61 | std::vector<delta_t> buffer; | |
62 | public: | |
63 | bool empty() const { | |
64 | return buffer.empty(); | |
65 | } | |
66 | ||
67 | void insert(coll_t coll, uint32_t bits) { | |
68 | buffer.push_back(delta_t{delta_t::op_t::INSERT, denc_coll_t(coll), bits}); | |
69 | } | |
70 | void update(coll_t coll, uint32_t bits) { | |
71 | buffer.push_back(delta_t{delta_t::op_t::UPDATE, denc_coll_t(coll), bits}); | |
72 | } | |
73 | void remove(coll_t coll) { | |
74 | buffer.push_back(delta_t{delta_t::op_t::REMOVE, denc_coll_t(coll), 0}); | |
75 | } | |
76 | void replay(coll_map_t &l) { | |
77 | for (auto &i: buffer) { | |
78 | i.replay(l); | |
79 | } | |
80 | } | |
81 | ||
82 | void clear() { buffer.clear(); } | |
83 | ||
84 | DENC(delta_buffer_t, v, p) { | |
85 | DENC_START(1, 1, p); | |
86 | denc(v.buffer, p); | |
87 | DENC_FINISH(p); | |
88 | } | |
89 | }; | |
90 | } | |
91 | WRITE_CLASS_DENC(crimson::os::seastore::collection_manager::delta_buffer_t) | |
92 | ||
93 | namespace crimson::os::seastore::collection_manager { | |
94 | ||
95 | struct CollectionNode | |
96 | : LogicalCachedExtent { | |
97 | using CollectionNodeRef = TCachedExtentRef<CollectionNode>; | |
98 | ||
99 | bool loaded = false; | |
100 | ||
101 | template <typename... T> | |
102 | CollectionNode(T&&... t) | |
103 | : LogicalCachedExtent(std::forward<T>(t)...) {} | |
104 | ||
105 | static constexpr extent_types_t type = extent_types_t::COLL_BLOCK; | |
106 | ||
107 | coll_map_t decoded; | |
108 | delta_buffer_t delta_buffer; | |
109 | ||
110 | CachedExtentRef duplicate_for_write() final { | |
111 | assert(delta_buffer.empty()); | |
112 | return CachedExtentRef(new CollectionNode(*this)); | |
113 | } | |
114 | delta_buffer_t *maybe_get_delta_buffer() { | |
115 | return is_mutation_pending() ? &delta_buffer : nullptr; | |
116 | } | |
117 | ||
118 | using list_iertr = CollectionManager::list_iertr; | |
119 | using list_ret = CollectionManager::list_ret; | |
120 | list_ret list(); | |
121 | ||
122 | ||
123 | enum class create_result_t : uint8_t { | |
124 | SUCCESS, | |
125 | OVERFLOW | |
126 | }; | |
127 | using create_iertr = CollectionManager::create_iertr; | |
128 | using create_ret = create_iertr::future<create_result_t>; | |
129 | create_ret create(coll_context_t cc, coll_t coll, unsigned bits); | |
130 | ||
131 | using remove_iertr = CollectionManager::remove_iertr; | |
132 | using remove_ret = CollectionManager::remove_ret; | |
133 | remove_ret remove(coll_context_t cc, coll_t coll); | |
134 | ||
135 | using update_iertr = CollectionManager::update_iertr; | |
136 | using update_ret = CollectionManager::update_ret; | |
137 | update_ret update(coll_context_t cc, coll_t coll, unsigned bits); | |
138 | ||
139 | void read_to_local() { | |
140 | if (loaded) return; | |
141 | bufferlist bl; | |
142 | bl.append(get_bptr()); | |
143 | auto iter = bl.cbegin(); | |
144 | decode((base_coll_map_t&)decoded, iter); | |
145 | loaded = true; | |
146 | } | |
147 | ||
148 | void copy_to_node() { | |
149 | bufferlist bl; | |
150 | encode((base_coll_map_t&)decoded, bl); | |
151 | auto iter = bl.begin(); | |
152 | auto size = encoded_sizeof((base_coll_map_t&)decoded); | |
153 | assert(size <= get_bptr().length()); | |
154 | get_bptr().zero(); | |
155 | iter.copy(size, get_bptr().c_str()); | |
156 | ||
157 | } | |
158 | ||
159 | ceph::bufferlist get_delta() final { | |
160 | assert(!delta_buffer.empty()); | |
161 | ceph::bufferlist bl; | |
162 | encode(delta_buffer, bl); | |
163 | delta_buffer.clear(); | |
164 | return bl; | |
165 | } | |
166 | ||
167 | void apply_delta(const ceph::bufferlist &bl) final { | |
168 | assert(bl.length()); | |
169 | delta_buffer_t buffer; | |
170 | auto bptr = bl.begin(); | |
171 | decode(buffer, bptr); | |
172 | buffer.replay(decoded); | |
173 | copy_to_node(); | |
174 | } | |
175 | ||
176 | static constexpr extent_types_t TYPE = extent_types_t::COLL_BLOCK; | |
177 | extent_types_t get_type() const final { | |
178 | return TYPE; | |
179 | } | |
180 | ||
181 | std::ostream &print_detail_l(std::ostream &out) const final; | |
182 | }; | |
183 | using CollectionNodeRef = CollectionNode::CollectionNodeRef; | |
184 | } |