]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: update key-view upon extent duplication in cursor cache
authorYingxin Cheng <yingxin.cheng@intel.com>
Tue, 9 Mar 2021 05:50:40 +0000 (13:50 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Thu, 11 Mar 2021 01:53:53 +0000 (09:53 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/fwd.h
src/crimson/os/seastore/onode_manager/staged-fltree/node.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h

index ac31bcfd8cd000602dbd5da53ae0d66b7159f970..57f7d63aed8cc7f5485bf797103b20706b8da1ce 100644 (file)
@@ -160,4 +160,12 @@ inline std::ostream& operator<<(std::ostream& os, const tree_stats_t& stats) {
   return os;
 }
 
+template <typename PtrType>
+void reset_ptr(PtrType& ptr, const char* origin_base, const char* new_base) {
+  assert((const char*)ptr > origin_base);
+  assert((const char*)ptr - origin_base < NODE_BLOCK_SIZE);
+  ptr = reinterpret_cast<PtrType>(
+      (const char*)ptr - origin_base + new_base);
+}
+
 }
index 1aecbb3a2bbeb50197451fb9fc79af4b1ed9c99e..67c5a339bca81723d8a3e429cd84008d7d0ddc4c 100644 (file)
@@ -164,13 +164,11 @@ void tree_cursor_t::Cache::update_all(const node_version_t& current_version,
   needs_update_all = false;
   version = current_version;
 
+  p_node_base = ref_leaf_node->read();
   key_view = _key_view;
   p_value_header = _p_value_header;
-
-  auto p_node_base = ref_leaf_node->read();
-  assert((const char*)_p_value_header > p_node_base);
-  offset_value_header = (const char*)_p_value_header - p_node_base;
-  assert(offset_value_header < NODE_BLOCK_SIZE);
+  assert((const char*)p_value_header > p_node_base);
+  assert((const char*)p_value_header - p_node_base < NODE_BLOCK_SIZE);
 
   value_payload_mut.reset();
   p_value_recorder = nullptr;
@@ -180,17 +178,20 @@ void tree_cursor_t::Cache::maybe_duplicate(const node_version_t& current_version
 {
   assert(version.layout == current_version.layout);
   if (!version.is_duplicate && current_version.is_duplicate) {
-    assert(p_value_header);
-    auto _p_value_header = reinterpret_cast<const value_header_t*>(
-        ref_leaf_node->read() + offset_value_header);
-    assert(_p_value_header != p_value_header);
-    assert(*_p_value_header == *p_value_header);
-
+    assert(p_node_base != nullptr);
+    assert(key_view.has_value());
+    assert(p_value_header != nullptr);
     assert(!value_payload_mut);
-    assert(!p_value_recorder);
+    assert(p_value_recorder == nullptr);
+
+    auto current_p_node_base = ref_leaf_node->read();
+    assert(current_p_node_base != p_node_base);
 
     version.is_duplicate = true;
-    p_value_header = _p_value_header;
+    reset_ptr(p_value_header, p_node_base, current_p_node_base);
+    key_view->reset_to(p_node_base, current_p_node_base);
+
+    p_node_base = current_p_node_base;
   } else {
     // cache must be latest.
     // node cannot change is_duplicate from true to false.
@@ -219,10 +220,9 @@ void tree_cursor_t::Cache::validate_is_latest(const search_position_t& pos) cons
   assert(version == ref_leaf_node->get_version());
 
   auto [_key_view, _p_value_header] = ref_leaf_node->get_kv(pos);
+  assert(p_node_base == ref_leaf_node->read());
   assert(key_view->compare_to(_key_view) == MatchKindCMP::EQ);
   assert(p_value_header == _p_value_header);
-  auto p_node_base = ref_leaf_node->read();
-  assert((const char*)_p_value_header - p_node_base == offset_value_header);
 #endif
 }
 
index ea4c741e7d561809c60c55a384af821f5ca0657e..14cb7a8581f7f4a3ef3eb626d4c4dd901e4dc390 100644 (file)
@@ -205,9 +205,9 @@ class tree_cursor_t final
     node_version_t version;
 
     // cached key value info
-    std::optional<key_view_t> key_view; // maybe still point to the read_only extent
+    const char* p_node_base = nullptr;
+    std::optional<key_view_t> key_view;
     const value_header_t* p_value_header = nullptr;
-    node_offset_t offset_value_header;
 
     // cached data-structures to update value payload
     std::optional<NodeExtentMutable> value_payload_mut;
index 670e781c7a8fee076acf925e810b5a561f438f4b..2475b744c8609988bbcccd2ed7d09ff5c6d37599 100644 (file)
@@ -212,6 +212,16 @@ struct string_key_view_t {
   }
   bool operator!=(const string_key_view_t& x) const { return !(*this == x); }
 
+  void reset_to(const char* origin_base, const char* new_base) {
+    reset_ptr(p_key, origin_base, new_base);
+    reset_ptr(p_length, origin_base, new_base);
+#ifndef NDEBUG
+    string_size_t current_length;
+    std::memcpy(&current_length, p_length, sizeof(string_size_t));
+    assert(length == current_length);
+#endif
+  }
+
   static void append_str(
       NodeExtentMutable&, std::string_view, char*& p_append);
 
@@ -404,6 +414,11 @@ struct ns_oid_view_t {
   }
   bool operator!=(const ns_oid_view_t& x) const { return !(*this == x); }
 
+  void reset_to(const char* origin_base, const char* new_base) {
+    nspace.reset_to(origin_base, new_base);
+    oid.reset_to(origin_base, new_base);
+  }
+
   template <KeyT KT>
   static node_offset_t estimate_size(const full_key_t<KT>& key);
 
@@ -647,6 +662,21 @@ class key_view_t {
     replace(key);
   }
 
+  void reset_to(const char* origin_base, const char* new_base) {
+    if (p_shard_pool != nullptr) {
+      reset_ptr(p_shard_pool, origin_base, new_base);
+    }
+    if (p_crush != nullptr) {
+      reset_ptr(p_crush, origin_base, new_base);
+    }
+    if (p_ns_oid.has_value()) {
+      p_ns_oid->reset_to(origin_base, new_base);
+    }
+    if (p_snap_gen != nullptr) {
+      reset_ptr(p_snap_gen, origin_base, new_base);
+    }
+  }
+
   std::ostream& dump(std::ostream& os) const {
     os << "key_view(";
     if (has_shard_pool()) {