- Refactor GetLowestRightBorderNodeWithLessThanKChildrenOrNull into algorithm.h
- Started shrinking leaves
This commit is contained in:
parent
e784e054d5
commit
f5c48db10b
@ -4,7 +4,7 @@
|
|||||||
#include "../datanodestore/DataInnerNode.h"
|
#include "../datanodestore/DataInnerNode.h"
|
||||||
#include "../datanodestore/DataLeafNode.h"
|
#include "../datanodestore/DataLeafNode.h"
|
||||||
|
|
||||||
#include "impl/GetLowestRightBorderNodeWithLessThanKChildrenOrNull.h"
|
#include "impl/algorithms.h"
|
||||||
|
|
||||||
#include "messmer/cpp-utils/pointer.h"
|
#include "messmer/cpp-utils/pointer.h"
|
||||||
|
|
||||||
@ -32,8 +32,16 @@ DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr<DataNode> rootNode)
|
|||||||
DataTree::~DataTree() {
|
DataTree::~DataTree() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DataTree::removeLastDataLeaf() {
|
||||||
|
DataInnerNode *rootNode = dynamic_cast<DataInnerNode*>(_rootNode.get());
|
||||||
|
assert(rootNode != nullptr);
|
||||||
|
|
||||||
|
auto deletePosOrNull = algorithms::GetLowestRightBorderNodeWithMoreThanOneChildOrNull(_nodeStore, _rootNode.get());
|
||||||
|
//TODO ...
|
||||||
|
}
|
||||||
|
|
||||||
unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
|
unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
|
||||||
auto insertPosOrNull = impl::GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(_nodeStore, _rootNode.get());
|
auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get());
|
||||||
if (insertPosOrNull) {
|
if (insertPosOrNull) {
|
||||||
return addDataLeafAt(insertPosOrNull.get());
|
return addDataLeafAt(insertPosOrNull.get());
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREE_H_
|
#define BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREE_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "messmer/cpp-utils/macros.h"
|
#include <messmer/cpp-utils/macros.h>
|
||||||
#include "impl/GetLowestRightBorderNodeWithLessThanKChildrenOrNull.h"
|
#include <messmer/cpp-utils/optional_ownership_ptr.h>
|
||||||
|
|
||||||
namespace blockstore {
|
namespace blockstore {
|
||||||
class Key;
|
class Key;
|
||||||
@ -25,6 +25,7 @@ public:
|
|||||||
virtual ~DataTree();
|
virtual ~DataTree();
|
||||||
|
|
||||||
std::unique_ptr<datanodestore::DataLeafNode> addDataLeaf();
|
std::unique_ptr<datanodestore::DataLeafNode> addDataLeaf();
|
||||||
|
void removeLastDataLeaf();
|
||||||
|
|
||||||
const blockstore::Key &key() const;
|
const blockstore::Key &key() const;
|
||||||
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#ifndef TEST_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_GETLOWESTRIGHTBORDERNODEWITHLESSTHANKCHILDRENORNULL_H_
|
|
||||||
#define TEST_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_GETLOWESTRIGHTBORDERNODEWITHLESSTHANKCHILDRENORNULL_H_
|
|
||||||
|
|
||||||
#include "messmer/cpp-utils/optional_ownership_ptr.h"
|
|
||||||
|
|
||||||
namespace blobstore {
|
|
||||||
namespace onblocks {
|
|
||||||
namespace datanodestore {
|
|
||||||
class DataNode;
|
|
||||||
class DataInnerNode;
|
|
||||||
class DataNodeStore;
|
|
||||||
}
|
|
||||||
namespace datatreestore {
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
class GetLowestRightBorderNodeWithLessThanKChildrenOrNull {
|
|
||||||
public:
|
|
||||||
//Returns the lowest right border node with less than k children (not considering leaves).
|
|
||||||
//Returns nullptr, if all right border nodes have k children (the tree is full)
|
|
||||||
static cpputils::optional_ownership_ptr<datanodestore::DataInnerNode> run(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,24 +1,23 @@
|
|||||||
#include "GetLowestRightBorderNodeWithLessThanKChildrenOrNull.h"
|
#include "algorithms.h"
|
||||||
|
#include <messmer/cpp-utils/pointer.h>
|
||||||
|
#include <messmer/blockstore/utils/Key.h>
|
||||||
|
|
||||||
#include "../../datanodestore/DataInnerNode.h"
|
#include "../../datanodestore/DataInnerNode.h"
|
||||||
#include "../../datanodestore/DataLeafNode.h"
|
|
||||||
#include "../../datanodestore/DataNodeStore.h"
|
#include "../../datanodestore/DataNodeStore.h"
|
||||||
|
|
||||||
#include "messmer/cpp-utils/pointer.h"
|
using std::function;
|
||||||
|
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
using cpputils::dynamic_pointer_move;
|
|
||||||
using cpputils::optional_ownership_ptr;
|
using cpputils::optional_ownership_ptr;
|
||||||
using blobstore::onblocks::datanodestore::DataNode;
|
using cpputils::dynamic_pointer_move;
|
||||||
using blobstore::onblocks::datanodestore::DataInnerNode;
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||||
using blobstore::onblocks::datanodestore::DataLeafNode;
|
using blobstore::onblocks::datanodestore::DataNode;
|
||||||
using blobstore::onblocks::datanodestore::DataNodeStore;
|
using blobstore::onblocks::datanodestore::DataNodeStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
|
|
||||||
namespace blobstore {
|
namespace blobstore {
|
||||||
namespace onblocks {
|
namespace onblocks {
|
||||||
namespace datatreestore {
|
namespace datatreestore {
|
||||||
namespace impl {
|
namespace algorithms {
|
||||||
|
|
||||||
unique_ptr<DataInnerNode> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
|
unique_ptr<DataInnerNode> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
|
||||||
Key key = node.LastChild()->key();
|
Key key = node.LastChild()->key();
|
||||||
@ -26,12 +25,14 @@ unique_ptr<DataInnerNode> getLastChildAsInnerNode(DataNodeStore *nodeStore, cons
|
|||||||
return dynamic_pointer_move<DataInnerNode>(lastChild);
|
return dynamic_pointer_move<DataInnerNode>(lastChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
optional_ownership_ptr<DataInnerNode> GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(DataNodeStore *nodeStore, DataNode *rootNode) {
|
//Returns the lowest right border node meeting the condition specified (exclusive the leaf).
|
||||||
|
//Returns nullptr, if no inner right border node meets the condition.
|
||||||
|
optional_ownership_ptr<DataInnerNode> GetLowestInnerRightBorderNodeWithConditionOrNull(DataNodeStore *nodeStore, datanodestore::DataNode *rootNode, function<bool(const DataInnerNode &)> condition) {
|
||||||
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
|
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
|
||||||
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
|
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
|
||||||
for (unsigned int i=0; i < rootNode->depth(); ++i) {
|
for (unsigned int i=0; i < rootNode->depth(); ++i) {
|
||||||
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
|
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
|
||||||
if (currentNode->numChildren() < DataInnerNode::MAX_STORED_CHILDREN) {
|
if (condition(*currentNode)) {
|
||||||
result = std::move(currentNode);
|
result = std::move(currentNode);
|
||||||
}
|
}
|
||||||
currentNode = std::move(lastChild);
|
currentNode = std::move(lastChild);
|
||||||
@ -40,6 +41,19 @@ optional_ownership_ptr<DataInnerNode> GetLowestRightBorderNodeWithLessThanKChild
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optional_ownership_ptr<DataInnerNode> GetLowestRightBorderNodeWithMoreThanOneChildOrNull(DataNodeStore *nodeStore, DataNode *rootNode) {
|
||||||
|
return GetLowestInnerRightBorderNodeWithConditionOrNull(nodeStore, rootNode, [] (const datanodestore::DataInnerNode &node) {
|
||||||
|
return node.numChildren() > 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//TODO Test this
|
||||||
|
|
||||||
|
optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode) {
|
||||||
|
return GetLowestInnerRightBorderNodeWithConditionOrNull(nodeStore, rootNode, [] (const datanodestore::DataInnerNode &node) {
|
||||||
|
return node.numChildren() < DataInnerNode::MAX_STORED_CHILDREN;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
30
implementations/onblocks/datatreestore/impl/algorithms.h
Normal file
30
implementations/onblocks/datatreestore/impl/algorithms.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_ALGORITHMS_H_
|
||||||
|
#define MESSMER_BLOBSTORE_IMPLEMENTATIONS_ONBLOCKS_DATATREESTORE_IMPL_ALGORITHMS_H_
|
||||||
|
|
||||||
|
#include <messmer/cpp-utils/optional_ownership_ptr.h>
|
||||||
|
|
||||||
|
namespace blobstore {
|
||||||
|
namespace onblocks {
|
||||||
|
namespace datanodestore{
|
||||||
|
class DataNode;
|
||||||
|
class DataInnerNode;
|
||||||
|
class DataNodeStore;
|
||||||
|
}
|
||||||
|
namespace datatreestore {
|
||||||
|
namespace algorithms {
|
||||||
|
|
||||||
|
//Returns the lowest right border node with at least two children.
|
||||||
|
//Returns nullptr, if all right border nodes have only one child (since the root is a right border node, this means that the whole tree has exactly one leaf)
|
||||||
|
cpputils::optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestRightBorderNodeWithMoreThanOneChildOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode);
|
||||||
|
|
||||||
|
//Returns the lowest right border node with less than k children (not considering leaves).
|
||||||
|
//Returns nullptr, if all right border nodes have k children (the tree is full)
|
||||||
|
cpputils::optional_ownership_ptr<datanodestore::DataInnerNode> GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(datanodestore::DataNodeStore *nodeStore, datanodestore::DataNode *rootNode);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -5,6 +5,7 @@
|
|||||||
#include "../../../../../implementations/onblocks/datanodestore/DataLeafNode.h"
|
#include "../../../../../implementations/onblocks/datanodestore/DataLeafNode.h"
|
||||||
#include "../../../../../implementations/onblocks/datanodestore/DataInnerNode.h"
|
#include "../../../../../implementations/onblocks/datanodestore/DataInnerNode.h"
|
||||||
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
|
||||||
|
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
|
||||||
|
|
||||||
using ::testing::Test;
|
using ::testing::Test;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
@ -17,9 +18,9 @@ using blobstore::onblocks::datanodestore::DataNode;
|
|||||||
using blobstore::onblocks::datanodestore::DataInnerNode;
|
using blobstore::onblocks::datanodestore::DataInnerNode;
|
||||||
using blockstore::testfake::FakeBlockStore;
|
using blockstore::testfake::FakeBlockStore;
|
||||||
using blockstore::Key;
|
using blockstore::Key;
|
||||||
using blobstore::onblocks::datatreestore::impl::GetLowestRightBorderNodeWithLessThanKChildrenOrNull;
|
using namespace blobstore::onblocks::datatreestore::algorithms;
|
||||||
|
|
||||||
class GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest: public DataTreeTest {
|
class GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest: public DataTreeTest {
|
||||||
public:
|
public:
|
||||||
struct TestData {
|
struct TestData {
|
||||||
TestData(Key rootNode_, Key expectedResult_): rootNode(rootNode_), expectedResult(expectedResult_) {}
|
TestData(Key rootNode_, Key expectedResult_): rootNode(rootNode_), expectedResult(expectedResult_) {}
|
||||||
@ -29,7 +30,7 @@ public:
|
|||||||
|
|
||||||
void check(const TestData &testData) {
|
void check(const TestData &testData) {
|
||||||
auto root = nodeStore.load(testData.rootNode);
|
auto root = nodeStore.load(testData.rootNode);
|
||||||
auto result = GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(&nodeStore, root.get());
|
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get());
|
||||||
EXPECT_EQ(testData.expectedResult, result->key());
|
EXPECT_EQ(testData.expectedResult, result->key());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,40 +69,40 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, Leaf) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, Leaf) {
|
||||||
auto leaf = nodeStore.createNewLeafNode();
|
auto leaf = nodeStore.createNewLeafNode();
|
||||||
auto result = GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(&nodeStore, leaf.get());
|
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, leaf.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, TwoRightBorderNodes) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, TwoRightBorderNodes) {
|
||||||
auto testData = CreateTwoRightBorderNodes();
|
auto testData = CreateTwoRightBorderNodes();
|
||||||
check(testData);
|
check(testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, ThreeRightBorderNodes) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, ThreeRightBorderNodes) {
|
||||||
auto testData = CreateThreeRightBorderNodes();
|
auto testData = CreateThreeRightBorderNodes();
|
||||||
check(testData);
|
check(testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, ThreeRightBorderNodes_LastFull) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, ThreeRightBorderNodes_LastFull) {
|
||||||
auto testData = CreateThreeRightBorderNodes_LastFull();
|
auto testData = CreateThreeRightBorderNodes_LastFull();
|
||||||
check(testData);
|
check(testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, LargerTree) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, LargerTree) {
|
||||||
auto testData = CreateLargerTree();
|
auto testData = CreateLargerTree();
|
||||||
check(testData);
|
check(testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, FullTwoLevelTree) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, FullTwoLevelTree) {
|
||||||
auto root = nodeStore.load(CreateFullTwoLevelTree());
|
auto root = nodeStore.load(CreateFullTwoLevelTree());
|
||||||
auto result = GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(&nodeStore, root.get());
|
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GetLowestRightBorderNodeWithLessThanKChildrenOrNullTest, FullThreeLevelTree) {
|
TEST_F(GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest, FullThreeLevelTree) {
|
||||||
auto root = nodeStore.load(CreateFullThreeLevelTree());
|
auto root = nodeStore.load(CreateFullThreeLevelTree());
|
||||||
auto result = GetLowestRightBorderNodeWithLessThanKChildrenOrNull::run(&nodeStore, root.get());
|
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(&nodeStore, root.get());
|
||||||
EXPECT_EQ(nullptr, result.get());
|
EXPECT_EQ(nullptr, result.get());
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user