/* @file GenericNode.hpp */ #pragma once #include "BplusTreeUtil.hpp" #include "bplustree_tags.hpp" #include // for std::unique_ptr #include namespace xo { namespace tree { /* shim so we can partially specialize */ template struct GenericNodeBase { }; /*GenericNodeBase*/ template struct GenericNodeBase { /* #of items (key-value pairs) in this subtree */ virtual std::size_t size() const = 0; }; /*GenericNodeShim*/ // ----- GenericNode ----- // // base class for LeafNode, InternalNode template class GenericNode : public GenericNodeBase { public: using PropertiesType = Properties; using InternalNodeType = InternalNode; using LeafNodeType = LeafNode; public: explicit GenericNode(NodeType ntype, std::size_t branching_factor) : node_type_{ntype}, branching_factor_{branching_factor} {} virtual ~GenericNode() = default; NodeType node_type() const { return node_type_; } InternalNodeType * parent() const { return parent_; } std::size_t n_elt() const { return n_elt_; } std::size_t branching_factor() const { return branching_factor_; } void set_parent(InternalNodeType * x) { this->parent_ = x; } #ifdef OBSOLETE /* #of items (key-value pairs) in this subtree */ virtual std::size_t size() const = 0; #endif virtual Key const & glb_key() const = 0; /* support methods for BplusTree::verify() * with_lub. true to use lub_key; false to ignore * lub_key. if with_lub=true, strict least upper bound key (in B+ tree) for this subtree; * all keys in this subtree must be strictly less than lub_key. * ignored when with_lub=false * lh_leaf. if null, this subtree contains the smallest key in ancestor B+ tree; * if non-null, lh_leaf's rightmost key is immediate predecessor * of leftmost key in this subtree * rh_leaf. if null, this subtree contains the largest key in ancestor B+ tree; * if non-null, rh_leaf's leftmost key is immediate successor * of rightmost key in this subtree */ virtual std::size_t verify_helper(InternalNodeType const * parent, bool with_lub, Key const & lub_key, LeafNodeType const * lh_leaf, LeafNodeType const * rh_leaf) const = 0; virtual void verify_glb_key(Key const & key) const = 0; FindNodeResult c_find_min_leaf_node() const; FindNodeResult c_find_max_leaf_node() const; virtual FindNodeResult find_min_leaf_node() = 0; virtual FindNodeResult find_max_leaf_node() = 0; /* notification just before permanently removing this node from B+ tree */ virtual void notify_remove() {} private: /* NodeType::internal | NodeType::leaf */ NodeType node_type_; /* pointer to parent node * invariant: parent has direct pointer to this node, * except briefly during construction */ InternalNodeType * parent_ = nullptr; protected: /* #of non-empty elements (children) of this node * * invariant: * - .elt_v[i].child.ptr is non-null for 0 <= i < .n_elt * - for (0 < i < .n_elt): * .elt_v[i-1].key < .elt_v[i].key * - elt_v[i].key not defined for (i >= .n_elt) */ std::size_t n_elt_ = 0; /* need to store actual branching factor, for LeafNode/InternalNode dtors */ std::size_t branching_factor_ = 0; }; /*GenericNode*/ /* const version (non-const version below) */ template FindNodeResult const> GenericNode::c_find_min_leaf_node() const { InternalNode * self = const_cast *>(this); return self->find_min_leaf_node(); } /*c_find_min_leaf_node*/ /* const version (non-const version below) */ template FindNodeResult const> GenericNode::c_find_max_leaf_node() const { InternalNode * self = const_cast *>(this); return self->find_max_leaf_node(); } /*c_find_max_leaf_node*/ } /*namespace tree*/ } /*namespace xo*/ /* end GenericNode.hpp */