diff --git a/src/blobstore/implementations/onblocks/datatreestore/DataTree.cpp b/src/blobstore/implementations/onblocks/datatreestore/DataTree.cpp index fe0dc1c0..0af0fa94 100644 --- a/src/blobstore/implementations/onblocks/datatreestore/DataTree.cpp +++ b/src/blobstore/implementations/onblocks/datatreestore/DataTree.cpp @@ -13,8 +13,11 @@ using blobstore::onblocks::datanodestore::DataInnerNode; using blobstore::onblocks::datanodestore::DataLeafNode; using std::unique_ptr; +using std::dynamic_pointer_cast; +using std::function; using fspp::dynamic_pointer_move; +using fspp::ptr::optional_ownership_ptr; namespace blobstore { namespace onblocks { @@ -27,51 +30,47 @@ DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr rootNode) DataTree::~DataTree() { } -void DataTree::addDataLeaf() { - auto insertPosOrNull = LowestRightBorderNodeWithLessThanKChildrenOrNull(); +unique_ptr DataTree::addDataLeaf() { + auto insertPosOrNull = lowestRightBorderNodeWithLessThanKChildrenOrNull(); if (insertPosOrNull) { - addDataLeafAt(insertPosOrNull.get()); + return addDataLeafAt(insertPosOrNull.get()); } else { - addDataLeafToFullTree(); + return addDataLeafToFullTree(); } } -unique_ptr DataTree::LowestRightBorderNodeWithLessThanKChildrenOrNull() { - const DataInnerNode *root_inner_node = dynamic_cast(_rootNode.get()); - if (nullptr == root_inner_node) { - //Root is not an inner node but a leaf - return nullptr; - } - - unique_ptr currentNode = _nodeStore->load(root_inner_node->LastChild()->key()); - unique_ptr result(nullptr); - while(auto currentInnerNode = dynamic_pointer_move(currentNode)) { - Key rightmostChildKey = currentInnerNode->LastChild()->key(); - if (currentInnerNode->numChildren() < DataInnerNode::MAX_STORED_CHILDREN) { - result = std::move(currentInnerNode); +optional_ownership_ptr DataTree::lowestRightBorderNodeWithLessThanKChildrenOrNull() { + optional_ownership_ptr currentNode = fspp::ptr::WithoutOwnership(dynamic_cast(_rootNode.get())); + optional_ownership_ptr result = fspp::ptr::null(); + for (unsigned int i=0; i < _rootNode->depth(); ++i) { + auto lastChild = getLastChildAsInnerNode(*currentNode); + if (currentNode->numChildren() < DataInnerNode::MAX_STORED_CHILDREN) { + result = std::move(currentNode); } - currentNode = _nodeStore->load(rightmostChildKey); + currentNode = std::move(lastChild); } return result; } +unique_ptr DataTree::getLastChildAsInnerNode(const DataInnerNode &node) { + Key key = node.LastChild()->key(); + auto lastChild = _nodeStore->load(key); + return dynamic_pointer_move(lastChild); +} + unique_ptr DataTree::addDataLeafAt(DataInnerNode *insertPos) { auto new_leaf = _nodeStore->createNewLeafNode(); - if (insertPos->depth() == 1) { - insertPos->addChild(*new_leaf); - } else { - auto chain = createChainOfInnerNodes(insertPos->depth()-1, *new_leaf); - insertPos->addChild(*chain); - } + auto chain = createChainOfInnerNodes(insertPos->depth()-1, new_leaf.get()); + insertPos->addChild(*chain); return new_leaf; } -unique_ptr DataTree::createChainOfInnerNodes(unsigned int num, const DataLeafNode &leaf) { - assert(num > 0); - unique_ptr chain = _nodeStore->createNewInnerNode(leaf); - for(unsigned int i=1; icreateNewInnerNode(*chain); +optional_ownership_ptr DataTree::createChainOfInnerNodes(unsigned int num, DataLeafNode *leaf) { + optional_ownership_ptr chain = fspp::ptr::WithoutOwnership(leaf); + for(unsigned int i=0; icreateNewInnerNode(*chain); + chain = fspp::ptr::WithOwnership(std::move(newnode)); } return chain; } diff --git a/src/blobstore/implementations/onblocks/datatreestore/DataTree.h b/src/blobstore/implementations/onblocks/datatreestore/DataTree.h index 25ebd439..3b9eb9bc 100644 --- a/src/blobstore/implementations/onblocks/datatreestore/DataTree.h +++ b/src/blobstore/implementations/onblocks/datatreestore/DataTree.h @@ -4,6 +4,7 @@ #include #include "fspp/utils/macros.h" +#include "fspp/utils/OptionalOwnershipPointer.h" namespace blobstore { namespace onblocks { @@ -20,14 +21,15 @@ public: DataTree(datanodestore::DataNodeStore *nodeStore, std::unique_ptr rootNode); virtual ~DataTree(); - void addDataLeaf(); + std::unique_ptr addDataLeaf(); private: datanodestore::DataNodeStore *_nodeStore; - std::unique_ptr _rootNode; + std::shared_ptr _rootNode; - std::unique_ptr LowestRightBorderNodeWithLessThanKChildrenOrNull(); + fspp::ptr::optional_ownership_ptr lowestRightBorderNodeWithLessThanKChildrenOrNull(); + std::unique_ptr getLastChildAsInnerNode(const datanodestore::DataInnerNode &node); std::unique_ptr addDataLeafAt(datanodestore::DataInnerNode *insertPos); - std::unique_ptr createChainOfInnerNodes(unsigned int num, const datanodestore::DataLeafNode &leaf); + fspp::ptr::optional_ownership_ptr createChainOfInnerNodes(unsigned int num, datanodestore::DataLeafNode *leaf); std::unique_ptr addDataLeafToFullTree(); std::unique_ptr copyNode(const datanodestore::DataNode &source);