]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/onode-staged-tree: fix errors about misaligned address access
authorYingxin Cheng <yingxin.cheng@intel.com>
Tue, 22 Sep 2020 07:39:57 +0000 (15:39 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Tue, 1 Dec 2020 04:50:53 +0000 (12:50 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
16 files changed:
src/crimson/os/seastore/onode_manager/staged-fltree/node.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_visitor.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_impl.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_layout_replayable.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_types.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/item_iterator_stage.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/key_layout.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.cc
src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage_types.h
src/crimson/os/seastore/onode_manager/staged-fltree/stages/sub_items_stage.cc
src/crimson/os/seastore/onode_manager/staged-fltree/stages/sub_items_stage.h
src/test/crimson/seastore/onode_tree/test_staged_fltree.cc

index 15a14ab79553e15a9846beb1c09c6c4747980539..1fe1997315b914185c9648ca6efd47c1c32df07e 100644 (file)
@@ -262,6 +262,7 @@ node_future<> InternalNode::apply_child_split(
 
   // update pos => left_child to pos => right_child
   auto left_child_addr = left_child->impl->laddr();
+  auto left_child_addr_packed = laddr_packed_t{left_child_addr};
   auto right_child_addr = right_child->impl->laddr();
   impl->replace_child_addr(pos, right_child_addr, left_child_addr);
   replace_track(pos, right_child, left_child);
@@ -273,11 +274,11 @@ node_future<> InternalNode::apply_child_split(
   auto free_size = impl->free_size();
   if (free_size >= insert_size) {
     // insert
-    auto p_value = impl->insert(left_key, left_child_addr,
+    auto p_value = impl->insert(left_key, left_child_addr_packed,
                                 insert_pos, insert_stage, insert_size);
     assert(impl->free_size() == free_size - insert_size);
     assert(insert_pos <= pos);
-    assert(*p_value == left_child_addr);
+    assert(p_value->value == left_child_addr);
     track_insert(insert_pos, insert_stage, left_child, right_child);
     validate_tracked_children();
     return node_ertr::now();
@@ -297,10 +298,11 @@ node_future<> InternalNode::apply_child_split(
                 insert_pos, insert_stage, insert_size](auto fresh_right) mutable {
     auto right_node = fresh_right.node;
     auto left_child_addr = left_child->impl->laddr();
+    auto left_child_addr_packed = laddr_packed_t{left_child_addr};
     auto [split_pos, is_insert_left, p_value] = impl->split_insert(
-        fresh_right.mut, *right_node->impl, left_key, left_child_addr,
+        fresh_right.mut, *right_node->impl, left_key, left_child_addr_packed,
         insert_pos, insert_stage, insert_size);
-    assert(*p_value == left_child_addr);
+    assert(p_value->value == left_child_addr);
     track_split(split_pos, right_node);
     if (is_insert_left) {
       track_insert(insert_pos, insert_stage, left_child);
@@ -324,9 +326,9 @@ node_future<Ref<InternalNode>> InternalNode::allocate_root(
   ).safe_then([c, old_root_addr,
                super = std::move(super)](auto fresh_node) mutable {
     auto root = fresh_node.node;
-    const laddr_t* p_value = root->impl->get_p_value(search_position_t::end());
+    auto p_value = root->impl->get_p_value(search_position_t::end());
     fresh_node.mut.copy_in_absolute(
-        const_cast<laddr_t*>(p_value), old_root_addr);
+        const_cast<laddr_packed_t*>(p_value), old_root_addr);
     root->make_root_from(c, std::move(super), old_root_addr);
     return root;
   });
@@ -335,7 +337,7 @@ node_future<Ref<InternalNode>> InternalNode::allocate_root(
 node_future<Ref<tree_cursor_t>>
 InternalNode::lookup_smallest(context_t c) {
   auto position = search_position_t::begin();
-  laddr_t child_addr = *impl->get_p_value(position);
+  laddr_t child_addr = impl->get_p_value(position)->value;
   return get_or_track_child(c, position, child_addr
   ).safe_then([c](auto child) {
     return child->lookup_smallest(c);
@@ -347,7 +349,7 @@ InternalNode::lookup_largest(context_t c) {
   // NOTE: unlike LeafNode::lookup_largest(), this only works for the tail
   // internal node to return the tail child address.
   auto position = search_position_t::end();
-  laddr_t child_addr = *impl->get_p_value(position);
+  laddr_t child_addr = impl->get_p_value(position)->value;
   return get_or_track_child(c, position, child_addr).safe_then([c](auto child) {
     return child->lookup_largest(c);
   });
@@ -357,7 +359,7 @@ node_future<Node::search_result_t>
 InternalNode::lower_bound_tracked(
     context_t c, const key_hobj_t& key, MatchHistory& history) {
   auto result = impl->lower_bound(key, history);
-  return get_or_track_child(c, result.position, *result.p_value
+  return get_or_track_child(c, result.position, result.p_value->value
   ).safe_then([c, &key, &history](auto child) {
     // XXX(multi-type): pass result.mstat to child
     return child->lower_bound_tracked(c, key, history);
@@ -473,7 +475,7 @@ void InternalNode::validate_child(const Node& child) const {
   assert(impl->level() - 1 == child.impl->level());
   assert(this == child.parent_info().ptr);
   auto& child_pos = child.parent_info().position;
-  assert(*impl->get_p_value(child_pos) == child.impl->laddr());
+  assert(impl->get_p_value(child_pos)->value == child.impl->laddr());
   if (child_pos.is_end()) {
     assert(impl->is_level_tail());
     assert(child.impl->is_level_tail());
index 30e65a46f397b8b8e507ec9c895a4bbb462bb78d..2668b916655e4f81af41eba303cfbb5f70cd2086 100644 (file)
@@ -101,7 +101,7 @@ class NodeExtentT {
   }
 
   void update_child_addr_replayable(
-      const laddr_t new_addr, laddr_t* p_addr) {
+      const laddr_t new_addr, laddr_packed_t* p_addr) {
     assert(state != state_t::PENDING_MUTATE);
     // TODO: encode params to recorder as delta
     return layout_t::update_child_addr(*mut, new_addr, p_addr);
index acd00c964e5a35845895e4749b50a23708a519e7..a01e73eff010b1ccf1a8ec6b85d28bf5292e0424 100644 (file)
@@ -50,7 +50,7 @@ class InternalNodeImpl : public NodeImpl {
   virtual ~InternalNodeImpl() = default;
 
   #pragma GCC diagnostic ignored "-Woverloaded-virtual"
-  virtual const laddr_t* get_p_value(
+  virtual const laddr_packed_t* get_p_value(
       const search_position_t&,
       key_view_t* = nullptr, internal_marker_t = {}) const {
     assert(false && "impossible path");
@@ -62,13 +62,13 @@ class InternalNodeImpl : public NodeImpl {
     assert(false && "impossible path");
   }
   #pragma GCC diagnostic ignored "-Woverloaded-virtual"
-  virtual const laddr_t* insert(
-      const key_view_t&, const laddr_t&, search_position_t&, match_stage_t&, node_offset_t&) {
+  virtual const laddr_packed_t* insert(
+      const key_view_t&, const laddr_packed_t&, search_position_t&, match_stage_t&, node_offset_t&) {
     assert(false && "impossible path");
   }
   #pragma GCC diagnostic ignored "-Woverloaded-virtual"
-  virtual std::tuple<search_position_t, bool, const laddr_t*> split_insert(
-      NodeExtentMutable&, NodeImpl&, const key_view_t&, const laddr_t&,
+  virtual std::tuple<search_position_t, bool, const laddr_packed_t*> split_insert(
+      NodeExtentMutable&, NodeImpl&, const key_view_t&, const laddr_packed_t&,
       search_position_t&, match_stage_t&, node_offset_t&) {
     assert(false && "impossible path");
   }
index c3244aa3154e5ec51c9c76405874a9391f604a85..0c6e478807dc01e74531a5a02e0b480087db2181 100644 (file)
@@ -124,7 +124,7 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
         auto value_ptr = node_stage.get_end_p_laddr();
         int offset = reinterpret_cast<const char*>(value_ptr) - p_start;
         os << "\n  tail value: 0x"
-           << std::hex << *value_ptr << std::dec
+           << std::hex << value_ptr->value << std::dec
            << " " << size << "B"
            << "  @" << offset << "B";
       }
@@ -322,9 +322,9 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
   void replace_child_addr(
       const search_position_t& pos, laddr_t dst, laddr_t src) override {
     if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
-      const laddr_t* p_value = get_p_value(pos);
-      assert(*p_value == src);
-      extent.update_child_addr_replayable(dst, const_cast<laddr_t*>(p_value));
+      const laddr_packed_t* p_value = get_p_value(pos);
+      assert(p_value->value == src);
+      extent.update_child_addr_replayable(dst, const_cast<laddr_packed_t*>(p_value));
     } else {
       assert(false && "impossible path");
     }
@@ -334,16 +334,17 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
       const key_view_t& key, const laddr_t& value,
       search_position_t& insert_pos) const override {
     if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
+      auto packed_value = laddr_packed_t{value};
       auto& node_stage = extent.read();
       match_stage_t insert_stage;
       node_offset_t insert_size;
       if (unlikely(!node_stage.keys())) {
         assert(insert_pos.is_end());
         insert_stage = STAGE;
-        insert_size = STAGE_T::template insert_size<KeyT::VIEW>(key, value);
+        insert_size = STAGE_T::template insert_size<KeyT::VIEW>(key, packed_value);
       } else {
         std::tie(insert_stage, insert_size) = STAGE_T::evaluate_insert(
-            node_stage, key, value, cast_down<STAGE>(insert_pos), true);
+            node_stage, key, packed_value, cast_down<STAGE>(insert_pos), true);
       }
       return {insert_stage, insert_size};
     } else {
index ef01d2cc7b419647d9e8fe15cba9479241bf8218..398e2f66f1cf07a8992e8fa652793708e92c7ee5 100644 (file)
@@ -64,7 +64,7 @@ struct NodeLayoutReplayableT {
   }
 
   static void update_child_addr(
-      NodeExtentMutable& mut, const laddr_t new_addr, laddr_t* p_addr) {
+      NodeExtentMutable& mut, const laddr_t new_addr, laddr_packed_t* p_addr) {
     assert(NODE_TYPE == node_type_t::INTERNAL);
     mut.copy_in_absolute(p_addr, new_addr);
   }
index 2466588e3f0ad4e6b326eb576885072163016b16..c1b4d190da58da279183946865e20fbc2aabee34 100644 (file)
@@ -43,4 +43,8 @@ inline std::ostream& operator<<(std::ostream &os, const node_type_t& type) {
   return os;
 }
 
+struct laddr_packed_t {
+  laddr_t value;
+} __attribute__((packed));
+
 }
index 6c7e928b807a0012ebf2ce96a0152f4fc742c8bb..3c1725d5f0419dd091f6183d551703e995b15b90 100644 (file)
@@ -100,7 +100,7 @@ class item_iterator_t {
   void next_item_range(const char* p_end) const {
     auto p_item_end = p_end - sizeof(node_offset_t);
     assert(p_items_start < p_item_end);
-    back_offset = *reinterpret_cast<const node_offset_t*>(p_item_end);
+    back_offset = reinterpret_cast<const node_offset_packed_t*>(p_item_end)->value;
     assert(back_offset);
     const char* p_item_start = p_item_end - back_offset;
     assert(p_items_start <= p_item_start);
index 01caa32341c72e8725b7ade405264d8d0282b4a6..f0e2673a8ff1971a6e6fd67463688596a8f2043e 100644 (file)
@@ -34,6 +34,10 @@ template<> struct _full_key_type<KeyT::HOBJ> { using type = key_hobj_t; };
 template <KeyT type>
 using full_key_t = typename _full_key_type<type>::type;
 
+struct node_offset_packed_t {
+  node_offset_t value;
+} __attribute__((packed));
+
 // TODO: consider alignments
 struct shard_pool_t {
   bool operator==(const shard_pool_t& x) const {
index d1c1394a051fddfc6f7e4f27c08cc9c0f0718f39..f7f326daeac24d8ed9e997c7e077730df5099e62 100644 (file)
@@ -302,7 +302,7 @@ char* APPEND_T::wrap() {
   assert(p_src);
   if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
     if (p_src->is_level_tail()) {
-      laddr_t tail_value = *p_src->get_end_p_laddr();
+      laddr_t tail_value = p_src->get_end_p_laddr()->value;
       p_append_right -= sizeof(laddr_t);
       assert(p_append_left <= p_append_right);
       p_mut->copy_in_absolute(p_append_right, tail_value);
index 73703fd7d65713b126dced386b90939b47d397a5..4edeab5912ff3eb94bf4e9a981d155549e2f0792 100644 (file)
@@ -51,18 +51,17 @@ class node_extent_t {
   size_t total_size() const { return p_fields->total_size(); }
   const char* p_left_bound() const;
   template <node_type_t T = NODE_TYPE>
-  std::enable_if_t<T == node_type_t::INTERNAL, const laddr_t*>
+  std::enable_if_t<T == node_type_t::INTERNAL, const laddr_packed_t*>
   get_end_p_laddr() const {
     assert(is_level_tail());
     if constexpr (FIELD_TYPE == field_type_t::N3) {
-      #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
       return &p_fields->child_addrs[keys()];
     } else {
       auto offset_start = p_fields->get_item_end_offset(keys());
       assert(offset_start <= FieldType::SIZE);
-      offset_start -= sizeof(laddr_t);
+      offset_start -= sizeof(laddr_packed_t);
       auto p_addr = p_start() + offset_start;
-      return reinterpret_cast<const laddr_t*>(p_addr);
+      return reinterpret_cast<const laddr_packed_t*>(p_addr);
     }
   }
 
@@ -84,7 +83,6 @@ class node_extent_t {
   get_p_value(size_t index) const {
     assert(index < keys());
     if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
-      #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
       return &p_fields->child_addrs[index];
     } else {
       auto range = get_nxt_container(index);
index 67405a376a0f9cc9ad05a2cf61470e0b6d30d22b..a79a364b3d69379564ffbdc1c579e653984bb8f5 100644 (file)
@@ -373,7 +373,7 @@ struct _internal_fields_3_t {
   node_header_t header;
   num_keys_t num_keys = 0u;
   snap_gen_t keys[MAX_NUM_KEYS];
-  laddr_t child_addrs[MAX_NUM_KEYS];
+  laddr_packed_t child_addrs[MAX_NUM_KEYS];
 } __attribute__((packed));
 static_assert(_internal_fields_3_t<MAX_NUM_KEYS_I3>::SIZE <= NODE_BLOCK_SIZE &&
               _internal_fields_3_t<MAX_NUM_KEYS_I3 + 1>::SIZE > NODE_BLOCK_SIZE);
index ac82e03a1a098bd1ae4221f96da1f3909bf6f376..cc57d432ccc3b359c4fae70a81a5a3f21a899ad3 100644 (file)
@@ -1246,7 +1246,7 @@ struct staged {
         if constexpr (NODE_TYPE == node_type_t::LEAF) {
           os << *value_ptr;
         } else {
-          os << "0x" << std::hex << *value_ptr << std::dec;
+          os << "0x" << std::hex << value_ptr->value << std::dec;
         }
         os << " " << size << "B"
            << "  @" << offset << "B";
index 6f30a15485730ec395d59e70366bc68316ffe9c6..b900d666a79b3ad24da9f4d759fa9e9f96036c24 100644 (file)
@@ -284,7 +284,7 @@ struct memory_range_t {
 enum class ContainerType { ITERATIVE, INDEXABLE };
 
 template <node_type_t> struct value_type;
-template<> struct value_type<node_type_t::INTERNAL> { using type = laddr_t; };
+template<> struct value_type<node_type_t::INTERNAL> { using type = laddr_packed_t; };
 template<> struct value_type<node_type_t::LEAF> { using type = onode_t; };
 template <node_type_t NODE_TYPE>
 using value_type_t = typename value_type<NODE_TYPE>::type;
index 06263c53ebdf804ebf3c02a1aa0a86c10c52f97f..7788d283b8009a34e72aa5dc8a2abe0dd1f716df 100644 (file)
@@ -8,9 +8,9 @@
 namespace crimson::os::seastore::onode {
 
 template <KeyT KT>
-const laddr_t* internal_sub_items_t::insert_at(
+const laddr_packed_t* internal_sub_items_t::insert_at(
     NodeExtentMutable& mut, const internal_sub_items_t& sub_items,
-    const full_key_t<KT>& key, const laddr_t& value,
+    const full_key_t<KT>& key, const laddr_packed_t& value,
     size_t index, node_offset_t size, const char* p_left_bound) {
   assert(index <= sub_items.keys());
   assert(size == estimate_insert<KT>(key, value));
@@ -24,9 +24,9 @@ const laddr_t* internal_sub_items_t::insert_at(
   mut.copy_in_absolute(p_insert, item);
   return &reinterpret_cast<internal_sub_item_t*>(p_insert)->value;
 }
-template const laddr_t* internal_sub_items_t::insert_at<KeyT::VIEW>(
+template const laddr_packed_t* internal_sub_items_t::insert_at<KeyT::VIEW>(
     NodeExtentMutable&, const internal_sub_items_t&, const full_key_t<KeyT::VIEW>&,
-    const laddr_t&, size_t, node_offset_t, const char*);
+    const laddr_packed_t&, size_t, node_offset_t, const char*);
 
 size_t internal_sub_items_t::trim_until(
     NodeExtentMutable&, internal_sub_items_t& items, size_t index) {
@@ -55,8 +55,8 @@ void internal_sub_items_t::Appender<KT>::append(
 
 template <KeyT KT>
 void internal_sub_items_t::Appender<KT>::append(
-    const full_key_t<KT>& key, const laddr_t& value, const laddr_t*& p_value) {
-  assert(pp_value == nullptr);
+    const full_key_t<KT>& key, const laddr_packed_t& value,
+    const laddr_packed_t*& p_value) {
   p_append -= sizeof(internal_sub_item_t);
   auto item = internal_sub_item_t{snap_gen_t::from_key<KT>(key), value};
   p_mut->copy_in_absolute(p_append, item);
@@ -86,8 +86,8 @@ const onode_t* leaf_sub_items_t::insert_at(
   // c. compensate affected offsets
   auto item_size = value.size + sizeof(snap_gen_t);
   for (auto i = index; i < sub_items.keys(); ++i) {
-    const node_offset_t& offset_i = sub_items.get_offset(i);
-    mut.copy_in_absolute((void*)&offset_i, node_offset_t(offset_i + item_size));
+    const node_offset_packed_t& offset_i = sub_items.get_offset(i);
+    mut.copy_in_absolute((void*)&offset_i, node_offset_t(offset_i.value + item_size));
   }
 
   // d. [item(index-1) ... item(0) ... offset(index)] <<< sizeof(node_offset_t)
@@ -162,7 +162,7 @@ char* leaf_sub_items_t::Appender<KT>::wrap() {
         int compensate = (last_offset - op_src->get_offset_to_end(arg.from));
         node_offset_t offset;
         for (auto i = arg.from; i < arg.from + arg.items; ++i) {
-          offset = op_src->get_offset(i) + compensate;
+          offset = op_src->get_offset(i).value + compensate;
           p_cur -= sizeof(node_offset_t);
           p_mut->copy_in_absolute(p_cur, offset);
         }
index 124a47b035d8ce895fa07fa0859d588a0d79a8d7..12594d183c0d382125129829b036cdc71cd59081 100644 (file)
@@ -15,11 +15,10 @@ class NodeExtentMutable;
 
 struct internal_sub_item_t {
   const snap_gen_t& get_key() const { return key; }
-  #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
-  const laddr_t* get_p_value() const { return &value; }
+  const laddr_packed_t* get_p_value() const { return &value; }
 
   snap_gen_t key;
-  laddr_t value;
+  laddr_packed_t value;
 } __attribute__((packed));
 
 /*
@@ -56,7 +55,7 @@ class internal_sub_items_t {
   size_t size_before(size_t index) const {
     return index * sizeof(internal_sub_item_t);
   }
-  const laddr_t* get_p_value(size_t index) const {
+  const laddr_packed_t* get_p_value(size_t index) const {
     assert(index < num_items);
     return (p_first_item - index)->get_p_value();
   }
@@ -64,14 +63,15 @@ class internal_sub_items_t {
   static node_offset_t header_size() { return 0u; }
 
   template <KeyT KT>
-  static node_offset_t estimate_insert(const full_key_t<KT>&, const laddr_t&) {
+  static node_offset_t estimate_insert(
+      const full_key_t<KT>&, const laddr_packed_t&) {
     return sizeof(internal_sub_item_t);
   }
 
   template <KeyT KT>
-  static const laddr_t* insert_at(
+  static const laddr_packed_t* insert_at(
       NodeExtentMutable&, const internal_sub_items_t&,
-      const full_key_t<KT>&, const laddr_t&,
+      const full_key_t<KT>&, const laddr_packed_t&,
       size_t index, node_offset_t size, const char* p_left_bound);
 
   static size_t trim_until(NodeExtentMutable&, internal_sub_items_t&, size_t);
@@ -90,10 +90,9 @@ class internal_sub_items_t::Appender {
   Appender(NodeExtentMutable* p_mut, char* p_append)
     : p_mut{p_mut}, p_append{p_append} {}
   void append(const internal_sub_items_t& src, size_t from, size_t items);
-  void append(const full_key_t<KT>&, const laddr_t&, const laddr_t*&);
+  void append(const full_key_t<KT>&, const laddr_packed_t&, const laddr_packed_t*&);
   char* wrap() { return p_append; }
  private:
-  const laddr_t** pp_value = nullptr;
   NodeExtentMutable* p_mut;
   char* p_append;
 };
@@ -127,7 +126,7 @@ class leaf_sub_items_t {
     assert(keys());
     auto _p_offsets = _p_num_keys - sizeof(node_offset_t);
     assert(range.p_start < _p_offsets);
-    p_offsets = reinterpret_cast<const node_offset_t*>(_p_offsets);
+    p_offsets = reinterpret_cast<const node_offset_packed_t*>(_p_offsets);
     p_items_end = reinterpret_cast<const char*>(&get_offset(keys() - 1));
     assert(range.p_start < p_items_end);
     assert(range.p_start == p_start());
@@ -141,18 +140,18 @@ class leaf_sub_items_t {
 
   const char* p_start() const { return get_item_end(keys()); }
 
-  const node_offset_t& get_offset(size_t index) const {
+  const node_offset_packed_t& get_offset(size_t index) const {
     assert(index < keys());
     return *(p_offsets - index);
   }
 
   const node_offset_t get_offset_to_end(size_t index) const {
     assert(index <= keys());
-    return index == 0 ? 0 : get_offset(index - 1);
+    return index == 0 ? 0 : get_offset(index - 1).value;
   }
 
   const char* get_item_start(size_t index) const {
-    return p_items_end - get_offset(index);
+    return p_items_end - get_offset(index).value;
   }
 
   const char* get_item_end(size_t index) const {
@@ -179,7 +178,7 @@ class leaf_sub_items_t {
     --index;
     auto ret = sizeof(num_keys_t) +
                (index + 1) * sizeof(node_offset_t) +
-               get_offset(index);
+               get_offset(index).value;
     return ret;
   }
   const onode_t* get_p_value(size_t index) const {
@@ -211,7 +210,7 @@ class leaf_sub_items_t {
  private:
   // TODO: support unaligned access
   const num_keys_t* p_num_keys;
-  const node_offset_t* p_offsets;
+  const node_offset_packed_t* p_offsets;
   const char* p_items_end;
 };
 
index 689149e075a76a8680899f32d092314acc63df1b..448105565c12449d17c3f474b87cff4eac6afde8 100644 (file)
@@ -167,6 +167,7 @@ TEST_F(a_basic_test_t, 1_basic_sizes)
   onode_t value = {2};
 #define _STAGE_T(NodeType) node_to_stage_t<typename NodeType::node_stage_t>
 #define NXT_T(StageType)  staged<typename StageType::next_param_t>
+  laddr_packed_t i_value{0};
   logger().info("\n"
     "Bytes of a key-value insertion (full-string):\n"
     "  s-p-c, 'n'-'o', s-g => onode_t(2): typically internal 41B, leaf 35B\n"
@@ -178,15 +179,15 @@ TEST_F(a_basic_test_t, 1_basic_sizes)
     "  LeafNode1: {} {} {}\n"
     "  LeafNode2: {} {}\n"
     "  LeafNode3: {}",
-    _STAGE_T(InternalNode0)::template insert_size<KeyT::VIEW>(key_view, 0),
-    NXT_T(_STAGE_T(InternalNode0))::template insert_size<KeyT::VIEW>(key_view, 0),
-    NXT_T(NXT_T(_STAGE_T(InternalNode0)))::template insert_size<KeyT::VIEW>(key_view, 0),
-    _STAGE_T(InternalNode1)::template insert_size<KeyT::VIEW>(key_view, 0),
-    NXT_T(_STAGE_T(InternalNode1))::template insert_size<KeyT::VIEW>(key_view, 0),
-    NXT_T(NXT_T(_STAGE_T(InternalNode1)))::template insert_size<KeyT::VIEW>(key_view, 0),
-    _STAGE_T(InternalNode2)::template insert_size<KeyT::VIEW>(key_view, 0),
-    NXT_T(_STAGE_T(InternalNode2))::template insert_size<KeyT::VIEW>(key_view, 0),
-    _STAGE_T(InternalNode3)::template insert_size<KeyT::VIEW>(key_view, 0),
+    _STAGE_T(InternalNode0)::template insert_size<KeyT::VIEW>(key_view, i_value),
+    NXT_T(_STAGE_T(InternalNode0))::template insert_size<KeyT::VIEW>(key_view, i_value),
+    NXT_T(NXT_T(_STAGE_T(InternalNode0)))::template insert_size<KeyT::VIEW>(key_view, i_value),
+    _STAGE_T(InternalNode1)::template insert_size<KeyT::VIEW>(key_view, i_value),
+    NXT_T(_STAGE_T(InternalNode1))::template insert_size<KeyT::VIEW>(key_view, i_value),
+    NXT_T(NXT_T(_STAGE_T(InternalNode1)))::template insert_size<KeyT::VIEW>(key_view, i_value),
+    _STAGE_T(InternalNode2)::template insert_size<KeyT::VIEW>(key_view, i_value),
+    NXT_T(_STAGE_T(InternalNode2))::template insert_size<KeyT::VIEW>(key_view, i_value),
+    _STAGE_T(InternalNode3)::template insert_size<KeyT::VIEW>(key_view, i_value),
     _STAGE_T(LeafNode0)::template insert_size<KeyT::HOBJ>(key, value),
     NXT_T(_STAGE_T(LeafNode0))::template insert_size<KeyT::HOBJ>(key, value),
     NXT_T(NXT_T(_STAGE_T(LeafNode0)))::template insert_size<KeyT::HOBJ>(key, value),