#include <string>
#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 <
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 <typename iterator, typename const_iterator>
+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 <typename iterator>
+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
*
template <bool is_const>
struct iter_t {
friend class StringKVInnerNodeLayout;
+
+ template <typename iterator, typename const_iterator>
+ friend void copy_from_foreign(iterator, const_iterator, const_iterator);
+ template <typename iterator>
+ friend void copy_from_local(unsigned, iterator, iterator, iterator);
+
using parent_t = typename crimson::common::maybe_const_t<StringKVInnerNodeLayout, is_const>::type;
parent_t node;
return iter_t<!is_const>(node, index);
}
- // Work nicely with for loops without requiring a nested type.
iter_t &operator*() { return *this; }
iter_t *operator->() { return this; }
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;
}
char *get_node_val_ptr() {
- auto tail = node->buf + BlockSize;
+ auto tail = node->buf + BLOCK_SIZE;
if (*this == node->iter_end())
return tail;
else {
}
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 {
}
}
- 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(){
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;
}
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;
typename crimson::common::maybe_const_t<char, is_const>::type get_node_key_ptr() const {
return reinterpret_cast<
typename crimson::common::maybe_const_t<char, is_const>::type>(
- node->get_node_key_ptr() + index);
+ node->get_node_key_ptr() + index);
}
};
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");
}
}
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) {
}
//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);
}
}
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(
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(
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();
}
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);
}
}
uint16_t capacity() const {
- return BlockSize - (reinterpret_cast<char*>(layout.template Pointer<2>(buf))-
+ return BLOCK_SIZE - (reinterpret_cast<char*>(layout.template Pointer<2>(buf))-
reinterpret_cast<char*>(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);
}
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();
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());
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());
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);
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);
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()) {
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);
}
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 <
friend class StringKVLeafNodeLayout;
using parent_t = typename crimson::common::maybe_const_t<StringKVLeafNodeLayout, is_const>::type;
+ template <typename iterator, typename const_iterator>
+ friend void copy_from_foreign(iterator, const_iterator, const_iterator);
+ template <typename iterator>
+ friend void copy_from_local(unsigned, iterator, iterator, iterator);
+
parent_t node;
uint16_t index;
return iter_t<!is_const>(node, index);
}
- // Work nicely with for loops without requiring a nested type.
iter_t &operator*() { return *this; }
iter_t *operator->() { return this; }
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;
}
char *get_node_val_ptr() {
- auto tail = node->buf + BlockSize;
+ auto tail = node->buf + BLOCK_SIZE;
if ( *this == node->iter_end())
return tail;
else
}
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
}
char *get_string_val_ptr() {
- auto tail = node->buf + BlockSize;
+ auto tail = node->buf + BLOCK_SIZE;
return tail - static_cast<int>(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<int>(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 {
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)
}
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;
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");
}
}
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(),
""
});
}
}
//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);
}
}
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) {
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) {
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);
}
}
uint32_t capacity() const {
- return BlockSize - (reinterpret_cast<char*>(layout.template Pointer<2>(buf))-
+ return BLOCK_SIZE - (reinterpret_cast<char*>(layout.template Pointer<2>(buf))-
reinterpret_cast<char*>(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);
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++;
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();
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());
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());
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);
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);
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);
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);
}
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<omap_node_meta_t, omap_node_meta_le_t>;
+WRITE_CLASS_DENC_BOUNDED(InnerNodeLayout::delta_inner_t)
+using LeafNodeLayout = StringKVLeafNodeLayout<omap_node_meta_t, omap_node_meta_le_t>;
+WRITE_CLASS_DENC_BOUNDED(LeafNodeLayout::delta_leaf_t)