From: chunmei-liu Date: Thu, 17 Dec 2020 01:21:43 +0000 (-0800) Subject: crimson/seastore: fix string_kv_node_layout.h comments X-Git-Tag: v17.0.0~31^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=833feb9a5aef710faab3bf0565e5457f738be4d0;p=ceph.git crimson/seastore: fix string_kv_node_layout.h comments Signed-off-by: chunmei-liu Signed-off-by: Samuel Just --- diff --git a/src/crimson/os/seastore/omap_manager/btree/omap_types.h b/src/crimson/os/seastore/omap_manager/btree/omap_types.h index d1bbb4c2ed17..321d8eb4bcf6 100644 --- a/src/crimson/os/seastore/omap_manager/btree/omap_types.h +++ b/src/crimson/os/seastore/omap_manager/btree/omap_types.h @@ -51,6 +51,17 @@ struct omap_inner_key_t { omap_inner_key_t() = default; omap_inner_key_t(uint16_t off, uint16_t len, laddr_t addr) : key_off(off), key_len(len), laddr(addr) {} + + inline bool operator==(const omap_inner_key_t b) const { + return key_off == b.key_off && key_len == b.key_len && laddr == b.laddr; + } + DENC(omap_inner_key_t, v, p) { + DENC_START(1, 1, p); + denc(v.key_off, p); + denc(v.key_len, p); + denc(v.laddr, p); + DENC_FINISH(p); + } }; struct omap_inner_key_le_t { @@ -90,6 +101,20 @@ struct omap_leaf_key_t { omap_leaf_key_t() = default; omap_leaf_key_t(uint16_t k_off, uint16_t k_len, uint16_t v_off, uint16_t v_len) : key_off(k_off), key_len(k_len), val_off(v_off), val_len(v_len) {} + + inline bool operator==(const omap_leaf_key_t b) const { + return key_off == b.key_off && key_len == b.key_len && + val_off == b.val_off && val_len == b.val_len; + } + + DENC(omap_leaf_key_t, v, p) { + DENC_START(1, 1, p); + denc(v.key_off, p); + denc(v.key_len, p); + denc(v.val_off, p); + denc(v.val_len, p); + DENC_FINISH(p); + } }; struct omap_leaf_key_le_t { @@ -126,3 +151,5 @@ struct omap_leaf_key_le_t { }; } +WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::omap_manager::omap_inner_key_t) +WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::omap_manager::omap_leaf_key_t) diff --git a/src/crimson/os/seastore/omap_manager/btree/string_kv_node_layout.h b/src/crimson/os/seastore/omap_manager/btree/string_kv_node_layout.h index bf5bac5352a1..1a278bc7a77b 100644 --- a/src/crimson/os/seastore/omap_manager/btree/string_kv_node_layout.h +++ b/src/crimson/os/seastore/omap_manager/btree/string_kv_node_layout.h @@ -7,12 +7,13 @@ #include #include "include/byteorder.h" +#include "include/denc.h" #include "crimson/common/layout.h" #include "crimson/common/fixed_kv_node_layout.h" #include "crimson/os/seastore/omap_manager/btree/omap_types.h" -#define BlockSize 4096 +#define BLOCK_SIZE 4096 namespace crimson::os::seastore::omap_manager { template < @@ -26,6 +27,70 @@ template < bool VALIDATE_INVARIANTS=true> class StringKVLeafNodeLayout; +/** + * copy_from_foreign + * + * Copy from another node entries to this node. + * [from_src, to_src) is another node entry range. + * tgt is this node entry to copy to. + * tgt and from_src must be from different nodes. + * from_src and to_src must be in the same node. + */ +template +static void copy_from_foreign( + iterator tgt, + const_iterator from_src, + const_iterator to_src) { + assert(tgt->node != from_src->node); + assert(to_src->node == from_src->node); + if (from_src == to_src) + return; + + auto to_copy = from_src->get_right_ptr_end() - to_src->get_right_ptr_end(); + assert(to_copy > 0); + memcpy( + tgt->get_right_ptr_end() - to_copy, + to_src->get_right_ptr_end(), + to_copy); + memcpy( + tgt->get_node_key_ptr(), + from_src->get_node_key_ptr(), + to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); + + auto offset_diff = tgt->get_right_offset_end() - from_src->get_right_offset_end(); + for (auto i = tgt; i != tgt + (to_src - from_src); ++i) { + i->update_offset(offset_diff); + } +} +/* copy_from_local + * + * Copies entries from [from_src, to_src) to tgt. + * tgt, from_src, and to_src must be from the same node. + */ +template +static void copy_from_local( + unsigned len, + iterator tgt, + iterator from_src, + iterator to_src) { + assert(tgt->node == from_src->node); + assert(to_src->node == from_src->node); + + auto to_copy = from_src->get_right_ptr_end() - to_src->get_right_ptr_end(); + assert(to_copy > 0); + int adjust_offset = tgt > from_src? -len : len; + memmove(to_src->get_right_ptr_end() + adjust_offset, + to_src->get_right_ptr_end(), + to_copy); + + for ( auto ite = from_src; ite < to_src; ite++) { + ite->update_offset(-adjust_offset); + } + memmove( + tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), + to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); + } + /** * StringKVInnerNodeLayout * @@ -53,6 +118,12 @@ public: template struct iter_t { friend class StringKVInnerNodeLayout; + + template + friend void copy_from_foreign(iterator, const_iterator, const_iterator); + template + friend void copy_from_local(unsigned, iterator, iterator, iterator); + using parent_t = typename crimson::common::maybe_const_t::type; parent_t node; @@ -72,7 +143,6 @@ public: return iter_t(node, index); } - // Work nicely with for loops without requiring a nested type. iter_t &operator*() { return *this; } iter_t *operator->() { return this; } @@ -108,6 +178,11 @@ public: return index < rhs.index; } + uint16_t operator>(const iter_t &rhs) const { + assert(rhs.node == node); + return index > rhs.index; + } + bool operator==(const iter_t &rhs) const { assert(node == rhs.node); return rhs.index == index; @@ -123,7 +198,7 @@ public: } char *get_node_val_ptr() { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; if (*this == node->iter_end()) return tail; else { @@ -132,7 +207,7 @@ public: } const char *get_node_val_ptr() const { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; if ( *this == node->iter_end()) return tail; else { @@ -140,9 +215,9 @@ public: } } - void set_node_val(const std::string &val) { + void set_node_val(std::string_view val) { static_assert(!is_const); - std::strcpy((char*)get_node_val_ptr(), val.c_str()); //copy char* to char* include "\0" + std::strcpy((char*)get_node_val_ptr(), std::string(val).c_str()); //copy char* to char* include "\0" } std::string get_node_val(){ @@ -154,7 +229,7 @@ public: return s; } - bool contains(const std::string &key) const { + bool contains(std::string_view key) const { auto next = *this + 1; if (next == node->iter_end()) return get_node_val() <= key; @@ -167,6 +242,47 @@ public: } private: + int get_right_offset() const { + return get_node_key().key_off; + } + + int get_right_offset_end() const { + if (index == 0) + return 0; + else + return (*this - 1)->get_right_offset(); + } + + char *get_right_ptr() { + return node->buf + BLOCK_SIZE - get_right_offset(); + } + + const char *get_right_ptr() const { + static_assert(!is_const); + return node->buf + BLOCK_SIZE - get_right_offset(); + } + + char *get_right_ptr_end() { + if (index == 0) + return node->buf + BLOCK_SIZE; + else + return (*this - 1)->get_right_ptr(); + } + + const char *get_right_ptr_end() const { + if (index == 0) + return node->buf + BLOCK_SIZE; + else + return (*this - 1)->get_right_ptr(); + } + + void update_offset(int offset) { + auto key = get_node_key(); + assert(offset + key.key_off >= 0); + key.key_off += offset; + set_node_key(key); + } + void set_node_key(omap_inner_key_t _lb) const { static_assert(!is_const); omap_inner_key_le_t lb; @@ -177,7 +293,7 @@ public: typename crimson::common::maybe_const_t::type get_node_key_ptr() const { return reinterpret_cast< typename crimson::common::maybe_const_t::type>( - node->get_node_key_ptr() + index); + node->get_node_key_ptr() + index); } }; @@ -190,29 +306,37 @@ public: UPDATE, REMOVE, } op; - omap_inner_key_le_t key; + omap_inner_key_t key; std::string val; + DENC(delta_inner_t, v, p) { + DENC_START(1, 1, p); + denc(v.op, p); + denc(v.key, p); + denc(v.val, p); + DENC_FINISH(p); + } + void replay(StringKVInnerNodeLayout &l) { switch (op) { case op_t::INSERT: { - l.inner_insert(l.string_lower_bound(val), key, val); - break; + l.inner_insert(l.string_lower_bound(val), key, val); + break; } case op_t::UPDATE: { - auto iter = l.find_string_key(val); - assert(iter != l.iter_end()); - l.inner_update(iter, key); - break; + auto iter = l.find_string_key(val); + assert(iter != l.iter_end()); + l.inner_update(iter, key); + break; } case op_t::REMOVE: { - auto iter = l.find_string_key(val); - assert(iter != l.iter_end()); - l.inner_remove(iter); - break; + auto iter = l.find_string_key(val); + assert(iter != l.iter_end()); + l.inner_remove(iter); + break; } default: - assert(0 == "Impossible"); + assert(0 == "Impossible"); } } @@ -231,36 +355,36 @@ public: return buffer.empty(); } void insert( - const omap_inner_key_t &key, - const std::string val) { + const omap_inner_key_t key, + std::string_view val) { omap_inner_key_le_t k; k = key; buffer.push_back( delta_inner_t{ delta_inner_t::op_t::INSERT, k, - val + val.data() }); } void update( const omap_inner_key_t &key, - const std::string &val) { + std::string_view val) { omap_inner_key_le_t k; k = key; buffer.push_back( delta_inner_t{ delta_inner_t::op_t::UPDATE, k, - val + val.data() }); } - void remove(std::string val) { + void remove(std::string_view val) { buffer.push_back( - delta_inner_t{ - delta_inner_t::op_t::REMOVE, - omap_inner_key_le_t(), - val - }); + delta_inner_t{ + delta_inner_t::op_t::REMOVE, + omap_inner_key_le_t(), + val.data() + }); } void replay(StringKVInnerNodeLayout &node) { @@ -277,29 +401,21 @@ public: } //copy out void encode(ceph::bufferlist &bl) { - using ceph::encode; uint32_t num = buffer.size(); - encode(num, bl); + ::encode(num, bl); for (auto &&i: buffer) { - encode(i.op, bl); - bl.append((char*)&(i.key), sizeof(i.key)); - encode(i.val, bl); + ::encode(i, bl); } buffer.clear(); } //copy in void decode(const ceph::bufferlist &bl) { - using ceph::decode; auto p = bl.cbegin(); uint32_t num; - decode (num, p); + ::decode(num, p); while (num--) { delta_inner_t delta; - decode(delta.op, p); - omap_inner_key_le_t key; - p.copy(sizeof(key), (char*)&(key)); - delta.key = key; - decode(delta.val, p); + ::decode(delta, p); buffer.push_back(delta); } } @@ -312,21 +428,21 @@ public: void journal_inner_insert( const_iterator _iter, const laddr_t laddr, - const std::string val, + std::string_view key, delta_inner_buffer_t *recorder) { auto iter = iterator(this, _iter.index); omap_inner_key_t node_key; node_key.laddr = laddr; - node_key.key_len = val.size() + 1; + node_key.key_len = key.size() + 1; node_key.key_off = iter.get_index() == 0 ? node_key.key_len : (iter - 1).get_node_key().key_off + node_key.key_len; if (recorder) { recorder->insert( node_key, - val); + key); } - inner_insert(iter, node_key, val); + inner_insert(iter, node_key, key); } void journal_inner_update( @@ -345,20 +461,20 @@ public: void journal_inner_replace( const_iterator _iter, const laddr_t laddr, - const std::string val, + std::string_view key, delta_inner_buffer_t *recorder) { auto iter = iterator(this, _iter.index); omap_inner_key_t node_key; node_key.laddr = laddr; - node_key.key_len = val.size() + 1; + node_key.key_len = key.size() + 1; node_key.key_off = iter.get_index() == 0? node_key.key_len : (iter - 1).get_node_key().key_off + node_key.key_len; if (recorder) { recorder->remove(iter->get_node_val()); - recorder->insert(node_key, val); + recorder->insert(node_key, key); } - inner_replace(iter, node_key, val); + inner_replace(iter, node_key, key); } void journal_inner_remove( @@ -420,43 +536,44 @@ public: off); } - const_iterator string_lower_bound(std::string str) const { + const_iterator string_lower_bound(std::string_view str) const { uint16_t start = 0, end = get_size(); while (start != end) { unsigned mid = (start + end) / 2; const_iterator iter(this, mid); std::string s = iter->get_node_val(); - if (s < str) + if (s < str) { start = ++mid; - if ( s > str) + } else if ( s > str) { end = mid; - if (s == str) + } else { return iter; + } } return const_iterator(this, start); } - iterator string_lower_bound(std::string str) { + iterator string_lower_bound(std::string_view str) { const auto &tref = *this; return iterator(this, tref.string_lower_bound(str).index); } - const_iterator string_upper_bound(std::string str) const { + const_iterator string_upper_bound(std::string_view str) const { auto ret = iter_begin(); for (; ret != iter_end(); ++ret) { std::string s = ret->get_node_val(); if (s > str) break; } - return ret; + return ret; } - iterator string_upper_bound(std::string str) { + iterator string_upper_bound(std::string_view str) { const auto &tref = *this; return iterator(this, tref.string_upper_bound(str).index); } - const_iterator find_string_key(const std::string &str) const { + const_iterator find_string_key(std::string_view str) const { auto ret = iter_begin(); for (; ret != iter_end(); ++ret) { std::string s = ret->get_node_val(); @@ -465,7 +582,7 @@ public: } return ret; } - iterator find_string_key(const std::string &str) { + iterator find_string_key(std::string_view str) { const auto &tref = *this; return iterator(this, tref.find_string_key(str).index); } @@ -515,14 +632,10 @@ public: } uint16_t capacity() const { - return BlockSize - (reinterpret_cast(layout.template Pointer<2>(buf))- + return BLOCK_SIZE - (reinterpret_cast(layout.template Pointer<2>(buf))- reinterpret_cast(layout.template Pointer<0>(buf))); } - char* from_end(int off) { - return buf + (BlockSize - off); - } - bool is_overflow(size_t ksize) const { return free_space() < (sizeof(omap_inner_key_le_t) + ksize); } @@ -559,10 +672,10 @@ public: auto piviter = get_split_pivot(); assert(piviter != iter_end()); - left.copy_from_foreign_head(left.iter_begin(), iter_begin(), piviter); + copy_from_foreign(left.iter_begin(), iter_begin(), piviter); left.set_size(piviter - iter_begin()); - right.copy_from_foreign_back(right.iter_begin(), piviter, iter_end()); + copy_from_foreign(right.iter_begin(), piviter, iter_end()); right.set_size(iter_end() - piviter); auto [lmeta, rmeta] = get_meta().split_into(); @@ -582,13 +695,13 @@ public: void merge_from( const StringKVInnerNodeLayout &left, const StringKVInnerNodeLayout &right) { - copy_from_foreign_head( + copy_from_foreign( iter_end(), left.iter_begin(), left.iter_end()); set_size(left.get_size()); - append_copy_from_foreign_head( + copy_from_foreign( iter_end(), right.iter_begin(), right.iter_end()); @@ -642,37 +755,37 @@ public: left.iter_idx(pivot_idx)->get_node_val(); if (pivot_size < left_size) { - replacement_left.copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), left.iter_begin(), left.iter_idx(pivot_idx)); replacement_left.set_size(pivot_idx); - replacement_right.copy_from_foreign_back( + copy_from_foreign( replacement_right.iter_end(), left.iter_idx(pivot_idx), left.iter_end()); replacement_right.set_size(left.get_size() - pivot_idx); - replacement_right.append_copy_from_foreign_head( + copy_from_foreign( replacement_right.iter_end(), right.iter_begin(), right.iter_end()); replacement_right.set_size(right.get_size() + left.get_size()- pivot_idx); } else { - replacement_left.copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), left.iter_begin(), left.iter_end()); replacement_left.set_size(left.get_size()); - replacement_left.append_copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), right.iter_begin(), right.iter_idx(pivot_idx - left.get_size())); replacement_left.set_size(pivot_idx); - replacement_right.copy_from_foreign_back( + copy_from_foreign( replacement_right.iter_end(), right.iter_idx(pivot_idx - left.get_size()), right.iter_end()); @@ -690,7 +803,7 @@ private: void inner_insert( iterator iter, const omap_inner_key_t key, - const std::string &val) { + std::string_view val) { if (VALIDATE_INVARIANTS) { if (iter != iter_begin()) { assert((iter - 1)->get_node_val() < val); @@ -701,7 +814,7 @@ private: assert(is_overflow(val.size() + 1) == false); } if (get_size() != 0 && iter != iter_end()) - local_move_back(key, iter + 1, iter, iter_end()); + copy_from_local(key.key_len, iter + 1, iter, iter_end()); iter->set_node_key(key); set_size(get_size() + 1); @@ -718,7 +831,7 @@ private: void inner_replace( iterator iter, const omap_inner_key_t &key, - const std::string &val) { + std::string_view val) { assert(iter != iter_end()); if (VALIDATE_INVARIANTS) { if (iter != iter_begin()) { @@ -736,7 +849,7 @@ private: void inner_remove(iterator iter) { assert(iter != iter_end()); if ((iter + 1) != iter_end()) - local_move_ahead(iter, iter + 1, iter_end()); + copy_from_local(iter->get_node_key().key_len, iter, iter + 1, iter_end()); set_size(get_size() - 1); } @@ -752,160 +865,6 @@ private: return L::Partial(1, 1, get_size()).template Pointer<2>(buf); } - /** - * copy_from_foreign_head - * - * Copy from another node begin entries to this node. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - static void copy_from_foreign_head( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = (to_src -1)->get_node_key().key_off; - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - - /** - * copy_from_foreign_back - * - * Copy from another node back entries to this node. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - void copy_from_foreign_back( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - auto offset = from_src.get_index() == 0? 0: (from_src-1)->get_node_key().key_off; - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off - offset); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = from_src.get_index() == 0? (to_src -1)->get_node_key().key_off: - (from_src-1)->get_node_val_ptr() - (to_src -1)->get_node_val_ptr(); - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - if ( from_src.get_index() == 0) - return; - - omap_inner_key_t key = (from_src - 1)->get_node_key(); - auto end_idx = tgt.get_index() + to_src.get_index() - from_src.get_index(); - for (auto ite = tgt; ite.get_index() != end_idx; ite++) { - omap_inner_key_t node_key = ite->get_node_key(); - node_key.key_off -= key.key_off; - ite->set_node_key(node_key); - } - } - - /** - * append copy_from_foreign_ahead - * - * append another node head entries to this node back. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - void append_copy_from_foreign_head( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - if (from_src == to_src) - return; - - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off + (tgt - 1)->get_node_key().key_off); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = (to_src -1)->get_node_key().key_off; - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - omap_inner_key_t key = (tgt - 1)->get_node_key(); - auto end_idx = tgt.get_index() + to_src.get_index() - from_src.get_index(); - for (auto ite = tgt; ite.get_index() != end_idx; ite++) { - omap_inner_key_t node_key = ite->get_node_key(); - node_key.key_off += key.key_off; - ite->set_node_key(node_key); - } - } - - /** - * local_move_back - * - * move this node entries range [from_src, to_src) back to tgt position. - * - * tgt, from_src, and to_src must be from the same node. - */ - static void local_move_back( - omap_inner_key_t key, - iterator tgt, - iterator from_src, - iterator to_src) { - assert(tgt->node == from_src->node); - assert(to_src->node == from_src->node); - void* des = (to_src-1)->get_node_val_ptr() - key.key_len; - void* src = (to_src-1)->get_node_val_ptr(); - size_t len = from_src.get_index() == 0? - from_src->node->buf + BlockSize - (to_src-1)->get_node_val_ptr(): - (from_src-1)->get_node_val_ptr() - (to_src-1)->get_node_val_ptr(); - - memmove(des, src, len); - for ( auto ite = from_src; ite < to_src; ite++) { - omap_inner_key_t node_key = ite->get_node_key(); - node_key.key_off += key.key_len; - ite->set_node_key(node_key); - } - memmove( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - - /** - * local_move_ahead - * - * move this node entries range [from_src, to_src) ahead to tgt position. - * - * tgt, from_src, and to_src must be from the same node. - */ - static void local_move_ahead( - iterator tgt, - iterator from_src, - iterator to_src) { - assert(tgt->node == from_src->node); - assert(to_src->node == from_src->node); - assert(from_src.get_index() != 0); - omap_inner_key_t key = tgt->get_node_key(); - void* des = (to_src-1)->get_node_val_ptr() + key.key_len; - void* src = (to_src-1)->get_node_val_ptr(); - size_t len = (from_src-1)->get_node_val_ptr() - (to_src-1)->get_node_val_ptr(); - memmove(des, src, len); - for ( auto ite = from_src; ite < to_src; ite++) { - omap_inner_key_t node_key = ite->get_node_key(); - node_key.key_off -= key.key_len; - ite->set_node_key(node_key); - } - memmove( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - }; template < @@ -924,6 +883,11 @@ public: friend class StringKVLeafNodeLayout; using parent_t = typename crimson::common::maybe_const_t::type; + template + friend void copy_from_foreign(iterator, const_iterator, const_iterator); + template + friend void copy_from_local(unsigned, iterator, iterator, iterator); + parent_t node; uint16_t index; @@ -941,7 +905,6 @@ public: return iter_t(node, index); } - // Work nicely with for loops without requiring a nested type. iter_t &operator*() { return *this; } iter_t *operator->() { return this; } @@ -977,6 +940,11 @@ public: return index < rhs.index; } + uint16_t operator>(const iter_t &rhs) const { + assert(rhs.node == node); + return index > rhs.index; + } + bool operator==(const iter_t &rhs) const { assert(node == rhs.node); return rhs.index == index; @@ -993,7 +961,7 @@ public: } char *get_node_val_ptr() { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; if ( *this == node->iter_end()) return tail; else @@ -1001,7 +969,7 @@ public: } const char *get_node_val_ptr() const { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; if ( *this == node->iter_end()) return tail; else @@ -1009,32 +977,32 @@ public: } char *get_string_val_ptr() { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; return tail - static_cast(get_node_key().val_off); } const char *get_string_val_ptr() const { - auto tail = node->buf + BlockSize; + auto tail = node->buf + BLOCK_SIZE; return tail - static_cast(get_node_key().val_off); } - void set_node_val(std::string val) const { + void set_node_val(std::string_view val) const { static_assert(!is_const); - std::strcpy((char*)get_node_val_ptr(), val.c_str()); //copy char* to char* include "\0" + std::strcpy((char*)get_node_val_ptr(), std::string(val).c_str()); //copy char* to char* include "\0" } std::string get_node_val() { - std::string s(get_node_val_ptr()); + std::string s(get_node_val_ptr()); return s; } std::string get_node_val() const{ - std::string s(get_node_val_ptr()); + std::string s(get_node_val_ptr()); return s; } - void set_string_val(std::string val) { + void set_string_val(std::string_view val) { static_assert(!is_const); - std::strcpy((char*)get_string_val_ptr(), val.c_str()); //copy char* to char* include "\0" + std::strcpy((char*)get_string_val_ptr(), std::string(val).c_str()); //copy char* to char* include "\0" } std::string get_string_val() const { @@ -1042,7 +1010,7 @@ public: return s; } - bool contains(const std::string &key) const { + bool contains(std::string_view key) const { auto next = *this + 1; if (*this == node->iter_begin()){ if (next->get_node_val() > key) @@ -1061,6 +1029,49 @@ public: } private: + int get_right_offset() const { + return get_node_key().key_off; + } + + int get_right_offset_end() const { + if (index == 0) + return 0; + else + return (*this - 1)->get_right_offset(); + } + + char *get_right_ptr() { + return node->buf + BLOCK_SIZE - get_right_offset(); + } + + const char *get_right_ptr() const { + static_assert(!is_const); + return node->buf + BLOCK_SIZE - get_right_offset(); + } + + char *get_right_ptr_end() { + if (index == 0) + return node->buf + BLOCK_SIZE; + else + return (*this - 1)->get_right_ptr(); + } + + const char *get_right_ptr_end() const { + if (index == 0) + return node->buf + BLOCK_SIZE; + else + return (*this - 1)->get_right_ptr(); + } + + void update_offset(int offset) { + auto key = get_node_key(); + assert(offset + key.key_off >= 0); + assert(offset + key.val_off >= 0); + key.key_off += offset; + key.val_off += offset; + set_node_key(key); + } + void set_node_key(omap_leaf_key_t _lb) const { static_assert(!is_const); omap_leaf_key_le_t lb; @@ -1086,26 +1097,34 @@ public: std::string key; std::string val; + DENC(delta_leaf_t, v, p) { + DENC_START(1, 1, p); + denc(v.op, p); + denc(v.key, p); + denc(v.val, p); + DENC_FINISH(p); + } + void replay(StringKVLeafNodeLayout &l) { switch (op) { case op_t::INSERT: { - l.leaf_insert(l.string_lower_bound(key), key, val); - break; + l.leaf_insert(l.string_lower_bound(key), key, val); + break; } case op_t::UPDATE: { - auto iter = l.find_string_key(key); - assert(iter != l.iter_end()); - l.leaf_update(iter, key, val); - break; + auto iter = l.find_string_key(key); + assert(iter != l.iter_end()); + l.leaf_update(iter, key, val); + break; } case op_t::REMOVE: { - auto iter = l.find_string_key(key); - assert(iter != l.iter_end()); - l.leaf_remove(iter); - break; + auto iter = l.find_string_key(key); + assert(iter != l.iter_end()); + l.leaf_remove(iter); + break; } default: - assert(0 == "Impossible"); + assert(0 == "Impossible"); } } @@ -1124,30 +1143,30 @@ public: return buffer.empty(); } void insert( - const std::string &key, - const std::string &val) { + std::string_view key, + std::string_view val) { buffer.push_back( delta_leaf_t{ delta_leaf_t::op_t::INSERT, - key, - val + key.data(), + val.data() }); } void update( - const std::string &key, - const std::string &val) { + std::string_view key, + std::string_view val) { buffer.push_back( delta_leaf_t{ delta_leaf_t::op_t::UPDATE, - key, - val + key.data(), + val.data() }); } - void remove(std::string key) { + void remove(std::string_view key) { buffer.push_back( delta_leaf_t{ delta_leaf_t::op_t::REMOVE, - key, + key.data(), "" }); } @@ -1166,28 +1185,21 @@ public: } //copy out void encode(ceph::bufferlist &bl) { - using ceph::encode; uint32_t num = buffer.size(); - encode(num, bl); + ::encode(num, bl); for (auto &&i: buffer) { - encode(i.op, bl); - encode(i.key, bl); - //bl.append((char*)&(i.key), sizeof(i.key)); - encode(i.val, bl); + ::encode(i, bl); } buffer.clear(); } //copy in void decode(const ceph::bufferlist &bl) { - using ceph::decode; auto p = bl.cbegin(); uint32_t num; - decode (num, p); + ::decode(num, p); while (num--) { delta_leaf_t delta; - decode(delta.op, p); - decode(delta.key, p); - decode(delta.val, p); + ::decode(delta, p); buffer.push_back(delta); } } @@ -1199,8 +1211,8 @@ public: void journal_leaf_insert( const_iterator _iter, - const std::string &key, - const std::string &val, + std::string_view key, + std::string_view val, delta_leaf_buffer_t *recorder) { auto iter = iterator(this, _iter.index); if (recorder) { @@ -1213,8 +1225,8 @@ public: void journal_leaf_update( const_iterator _iter, - const std::string &key, - const std::string &val, + std::string_view key, + std::string_view val, delta_leaf_buffer_t *recorder) { auto iter = iterator(this, _iter.index); if (recorder) { @@ -1268,52 +1280,53 @@ public: off); } - const_iterator string_lower_bound(std::string str) const { + const_iterator string_lower_bound(std::string_view str) const { uint16_t start = 0, end = get_size(); while (start != end) { unsigned mid = (start + end) / 2; const_iterator iter(this, mid); std::string s = iter->get_node_val(); - if (s < str) + if (s < str) { start = ++mid; - if (s > str) + } else if (s > str) { end = mid; - if (s == str) + } else { return iter; + } } return const_iterator(this, start); } - iterator string_lower_bound(std::string str) { + iterator string_lower_bound(std::string_view str) { const auto &tref = *this; return iterator(this, tref.string_lower_bound(str).index); } - const_iterator string_upper_bound(std::string str) const { + const_iterator string_upper_bound(std::string_view str) const { auto ret = iter_begin(); for (; ret != iter_end(); ++ret) { - std::string s = ret->get_node_val(); + std::string s = ret->get_node_val(); if (s > str) break; } return ret; } - iterator string_upper_bound(std::string str) { + iterator string_upper_bound(std::string_view str) { const auto &tref = *this; return iterator(this, tref.string_upper_bound(str).index); } - const_iterator find_string_key(const std::string &str) const { + const_iterator find_string_key(std::string_view str) const { auto ret = iter_begin(); for (; ret != iter_end(); ++ret) { - std::string s = ret->get_node_val(); + std::string s = ret->get_node_val(); if (s == str) break; } return ret; } - iterator find_string_key(const std::string &str) { + iterator find_string_key(std::string_view str) { const auto &tref = *this; return iterator(this, tref.find_string_key(str).index); } @@ -1378,12 +1391,9 @@ public: } uint32_t capacity() const { - return BlockSize - (reinterpret_cast(layout.template Pointer<2>(buf))- + return BLOCK_SIZE - (reinterpret_cast(layout.template Pointer<2>(buf))- reinterpret_cast(layout.template Pointer<0>(buf))); } - char* from_end(int off) { - return buf + (BlockSize - off); - } bool is_overflow(size_t ksize, size_t vsize) const { return free_space() < (sizeof(omap_leaf_key_le_t) + ksize + vsize); @@ -1400,9 +1410,9 @@ public: auto iter = iter_begin(); auto iter2 = rhs.iter_begin(); while (iter != iter_end()) { - if (iter->get_node_key() != iter2->get_node_key() || + if(iter->get_node_key() != iter2->get_node_key() || iter->get_node_val() != iter2->get_node_val() || - iter->get_string_val() != iter2->get_string_val()){ + iter->get_string_val() != iter2->get_string_val()){ return false; } iter++; @@ -1422,10 +1432,10 @@ public: auto piviter = get_split_pivot(); assert (piviter != iter_end()); - left.copy_from_foreign_head(left.iter_begin(), iter_begin(), piviter); + copy_from_foreign(left.iter_begin(), iter_begin(), piviter); left.set_size(piviter - iter_begin()); - right.copy_from_foreign_back(right.iter_begin(), piviter, iter_end()); + copy_from_foreign(right.iter_begin(), piviter, iter_end()); right.set_size(iter_end() - piviter); auto [lmeta, rmeta] = get_meta().split_into(); @@ -1446,12 +1456,12 @@ public: const StringKVLeafNodeLayout &left, const StringKVLeafNodeLayout &right) { - copy_from_foreign_head( + copy_from_foreign( iter_end(), left.iter_begin(), left.iter_end()); set_size(left.get_size()); - append_copy_from_foreign_head( + copy_from_foreign( iter_end(), right.iter_begin(), right.iter_end()); @@ -1505,37 +1515,37 @@ public: left.iter_idx(pivot_idx)->get_node_val(); if (pivot_size < left_size) { - replacement_left.copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), left.iter_begin(), left.iter_idx(pivot_idx)); replacement_left.set_size(pivot_idx); - replacement_right.copy_from_foreign_back( + copy_from_foreign( replacement_right.iter_end(), left.iter_idx(pivot_idx), left.iter_end()); replacement_right.set_size(left.get_size() - pivot_idx); - replacement_right.append_copy_from_foreign_head( + copy_from_foreign( replacement_right.iter_end(), right.iter_begin(), right.iter_end()); replacement_right.set_size(right.get_size() + left.get_size() - pivot_idx); } else { - replacement_left.copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), left.iter_begin(), left.iter_end()); replacement_left.set_size(left.get_size()); - replacement_left.append_copy_from_foreign_head( + copy_from_foreign( replacement_left.iter_end(), right.iter_begin(), right.iter_idx(pivot_idx - left.get_size())); replacement_left.set_size(pivot_idx); - replacement_right.copy_from_foreign_back( + copy_from_foreign( replacement_right.iter_end(), right.iter_idx(pivot_idx - left.get_size()), right.iter_end()); @@ -1552,8 +1562,8 @@ public: private: void leaf_insert( iterator iter, - const std::string &key, - const std::string &val) { + std::string_view key, + std::string_view val) { if (VALIDATE_INVARIANTS) { if (iter != iter_begin()) { assert((iter - 1)->get_node_val() < key); @@ -1576,7 +1586,7 @@ private: node_key.val_len = val.size() + 1; } if (get_size() != 0 && iter != iter_end()) - local_move_back(node_key, iter + 1, iter, iter_end()); + copy_from_local(node_key.key_len + node_key.val_len, iter + 1, iter, iter_end()); iter->set_node_key(node_key); set_size(get_size() + 1); @@ -1586,8 +1596,8 @@ private: void leaf_update( iterator iter, - const std::string &key, - const std::string &val) { + std::string_view key, + std::string_view val) { assert(iter != iter_end()); if (VALIDATE_INVARIANTS) { assert(is_overflow(0, val.size() + 1) == false); @@ -1598,8 +1608,10 @@ private: void leaf_remove(iterator iter) { assert(iter != iter_end()); - if ((iter + 1) != iter_end()) - local_move_ahead(iter, iter + 1, iter_end()); + if ((iter + 1) != iter_end()) { + omap_leaf_key_t key = iter->get_node_key(); + copy_from_local(key.key_len + key.val_len, iter, iter + 1, iter_end()); + } set_size(get_size() - 1); } @@ -1615,163 +1627,11 @@ private: return L::Partial(1, 1, get_size()).template Pointer<2>(buf); } - /** - * copy_from_foreign_head - * - * Copy from another node begin entries to this node. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - static void copy_from_foreign_head( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = (to_src -1)->get_node_key().key_off; - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - - /** - * copy_from_foreign_back - * - * Copy from another node back entries to this node. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - void copy_from_foreign_back( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - auto offset = from_src.get_index() == 0? 0: (from_src-1)->get_node_key().key_off; - - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off - offset); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = from_src.get_index() == 0? (to_src -1)->get_node_key().key_off: - (from_src-1)->get_node_val_ptr() - (to_src -1)->get_node_val_ptr(); - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - if ( from_src.get_index() == 0) - return; - - omap_leaf_key_t key = (from_src - 1)->get_node_key(); - for (auto ite = tgt; ite.get_index() < (tgt.get_index() + to_src.get_index() - from_src.get_index()); ite++) { - omap_leaf_key_t node_key = ite->get_node_key(); - node_key.key_off -= key.key_off; - node_key.val_off -= key.key_off; - ite->set_node_key(node_key); - } - } - - /** - * append copy_from_foreign_ahead - * - * append another node head entries to this node back. - * [from_src, to_src) is another node entry range. - * tgt is this node entry to copy to. - * tgt and from_src must be from different nodes. - * from_src and to_src must be in the same node. - */ - void append_copy_from_foreign_head( - iterator tgt, - const_iterator from_src, - const_iterator to_src) { - assert(tgt->node != from_src->node); - assert(to_src->node == from_src->node); - if (from_src == to_src) - return; - - void* des = tgt.node->from_end((to_src -1)->get_node_key().key_off + (tgt - 1)->get_node_key().key_off); - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = (to_src -1)->get_node_key().key_off; - memcpy(des, src, len); - memcpy( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - omap_leaf_key_t key = (tgt - 1)->get_node_key(); - auto end_idx = tgt.get_index() + to_src.get_index() - from_src.get_index(); - for (auto ite = tgt; ite.get_index() != end_idx; ite++) { - omap_leaf_key_t node_key = ite->get_node_key(); - node_key.key_off += key.key_off; - node_key.val_off += key.key_off; - ite->set_node_key(node_key); - } - } - - /** - * local_move_back - * - * move this node entries range [from_src, to_src) back to tgt position. - * - * tgt, from_src, and to_src must be from the same node. - */ - static void local_move_back( - omap_leaf_key_t key, - iterator tgt, - iterator from_src, - iterator to_src) { - assert(tgt->node == from_src->node); - assert(to_src->node == from_src->node); - void* des = (to_src-1)->get_node_val_ptr() - (key.key_len + key.val_len); - void* src = (to_src-1)->get_node_val_ptr(); - size_t len = from_src.get_index() == 0? - from_src->node->buf + BlockSize - (to_src-1)->get_node_val_ptr(): - (from_src-1)->get_node_val_ptr() - (to_src-1)->get_node_val_ptr(); - memmove(des, src, len); - for ( auto ite = from_src; ite < to_src; ite++) { - omap_leaf_key_t node_key = ite->get_node_key(); - node_key.key_off += (key.key_len + key.val_len); - node_key.val_off += (key.key_len + key.val_len); - ite->set_node_key(node_key); - } - memmove( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - - /** - * local_move_ahead - * - * move this node entries range [from_src, to_src) ahead to tgt position. - * - * tgt, from_src, and to_src must be from the same node. - */ - static void local_move_ahead( - iterator tgt, - iterator from_src, - iterator to_src) { - assert(tgt->node == from_src->node); - assert(to_src->node == from_src->node); - assert(from_src.get_index() != 0); - omap_leaf_key_t key = tgt->get_node_key(); - void* des = (to_src - 1)->get_node_val_ptr() + key.key_len + key.val_len; - void* src = (to_src - 1)->get_node_val_ptr(); - size_t len = (from_src - 1)->get_node_val_ptr() - (to_src - 1)->get_node_val_ptr(); - memmove(des, src, len); - for ( auto ite = from_src; ite < to_src; ite++) { - omap_leaf_key_t node_key = ite->get_node_key(); - node_key.key_off -= (key.key_len + key.val_len); - node_key.val_off -= (key.key_len + key.val_len); - ite->set_node_key(node_key); - } - memmove( - tgt->get_node_key_ptr(), from_src->get_node_key_ptr(), - to_src->get_node_key_ptr() - from_src->get_node_key_ptr()); - } - }; } +using namespace crimson::os::seastore::omap_manager; +using InnerNodeLayout = StringKVInnerNodeLayout; +WRITE_CLASS_DENC_BOUNDED(InnerNodeLayout::delta_inner_t) +using LeafNodeLayout = StringKVLeafNodeLayout; +WRITE_CLASS_DENC_BOUNDED(LeafNodeLayout::delta_leaf_t)