diff --git a/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.cpp b/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.cpp index 5f42105f..d562bdc8 100644 --- a/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.cpp +++ b/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.cpp @@ -21,7 +21,7 @@ DataInnerNode::~DataInnerNode() { void DataInnerNode::InitializeNewNode(const DataNode &first_child) { *node().Depth() = first_child.depth() + 1; *node().Size() = 1; - first_child.key().ToBinary(ChildrenBegin()->key); + ChildrenBegin()->setKey(first_child.key()); } uint32_t DataInnerNode::numChildren() const { @@ -44,10 +44,30 @@ const DataInnerNode::ChildEntry *DataInnerNode::ChildrenEnd() const { return ChildrenBegin() + *node().Size(); } -const DataInnerNode::ChildEntry *DataInnerNode::RightmostExistingChild() const{ +DataInnerNode::ChildEntry *DataInnerNode::LastChild() { + return const_cast(const_cast(this)->LastChild()); +} + +const DataInnerNode::ChildEntry *DataInnerNode::LastChild() const { return ChildrenEnd()-1; } +DataInnerNode::ChildEntry *DataInnerNode::getChild(unsigned int index) { + return const_cast(const_cast(this)->getChild(index)); +} + +const DataInnerNode::ChildEntry *DataInnerNode::getChild(unsigned int index) const { + assert(index < numChildren()); + return ChildrenBegin()+index; +} + +void DataInnerNode::addChild(const DataNode &child) { + assert(numChildren() < DataInnerNode::MAX_STORED_CHILDREN); + assert(child.depth() == depth()-1); + *node().Size() += 1; + LastChild()->setKey(child.key()); +} + } } } diff --git a/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.h b/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.h index 9ba07c88..fecc9229 100644 --- a/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.h +++ b/src/blobstore/implementations/onblocks/datanodestore/DataInnerNode.h @@ -14,21 +14,37 @@ public: virtual ~DataInnerNode(); struct ChildEntry { - uint8_t key[blockstore::Key::KEYLENGTH_BINARY]; + public: + blockstore::Key key() const { + return blockstore::Key::FromBinary(_keydata); + } + private: + void setKey(const blockstore::Key &key) { + key.ToBinary(_keydata); + } + friend class DataInnerNode; + uint8_t _keydata[blockstore::Key::KEYLENGTH_BINARY]; + DISALLOW_COPY_AND_ASSIGN(ChildEntry); }; static constexpr uint32_t MAX_STORED_CHILDREN = DataNodeView::DATASIZE_BYTES / sizeof(ChildEntry); - void InitializeNewNode(const DataNode &first_child); + void InitializeNewNode(const DataNode &first_child_key); ChildEntry *ChildrenBegin(); ChildEntry *ChildrenEnd(); const ChildEntry *ChildrenBegin() const; const ChildEntry *ChildrenEnd() const; - const ChildEntry *RightmostExistingChild() const; + ChildEntry *getChild(unsigned int index); + const ChildEntry *getChild(unsigned int index) const; + + ChildEntry *LastChild(); + const ChildEntry *LastChild() const; uint32_t numChildren() const; + + void addChild(const DataNode &child_key); }; } diff --git a/src/test/blobstore/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp b/src/test/blobstore/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp index 8ad1dfb5..69b087f0 100644 --- a/src/test/blobstore/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp +++ b/src/test/blobstore/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp @@ -1 +1,64 @@ -//TODO +#include + +#include +#include +#include + +#include "blockstore/implementations/testfake/FakeBlockStore.h" +#include "blockstore/implementations/testfake/FakeBlock.h" + +#include + +using ::testing::Test; + +using blockstore::Key; +using blockstore::testfake::FakeBlockStore; +using blockstore::BlockStore; +using namespace blobstore; +using namespace blobstore::onblocks; +using namespace blobstore::onblocks::datanodestore; + +using std::unique_ptr; +using std::make_unique; + +class DataInnerNodeTest: public Test { +public: + DataInnerNodeTest() : + _blockStore(make_unique()), + blockStore(_blockStore.get()), + nodeStore(make_unique(std::move(_blockStore))), + leaf(nodeStore->createNewLeafNode()), + node(nodeStore->createNewInnerNode(*leaf)) { + } + + unique_ptr _blockStore; + BlockStore *blockStore; + unique_ptr nodeStore; + unique_ptr leaf; + unique_ptr node; +}; + +TEST_F(DataInnerNodeTest, InitializesCorrectly) { + node->InitializeNewNode(*leaf); + EXPECT_EQ(1u, node->numChildren()); + EXPECT_EQ(leaf->key(), node->getChild(0)->key()); +} + +TEST_F(DataInnerNodeTest, ReinitializesCorrectly) { + node->InitializeNewNode(*leaf); + auto leaf2 = nodeStore->createNewLeafNode(); + node->addChild(*leaf2); + node->InitializeNewNode(*leaf); + + EXPECT_EQ(1u, node->numChildren()); + EXPECT_EQ(leaf->key(), node->getChild(0)->key()); +} + +TEST_F(DataInnerNodeTest, AddingASecondLeaf) { + auto leaf2 = nodeStore->createNewLeafNode(); + node->addChild(*leaf2); + + EXPECT_EQ(2u, node->numChildren()); + EXPECT_EQ(leaf->key(), node->getChild(0)->key()); + EXPECT_EQ(leaf2->key(), node->getChild(1)->key()); +} diff --git a/src/test/blobstore/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp b/src/test/blobstore/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp index 68a9938d..de3dd4b1 100644 --- a/src/test/blobstore/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp +++ b/src/test/blobstore/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp @@ -80,3 +80,15 @@ TEST_F(DataNodeStoreTest, DataNodeCrashesOnLoadIfDepthIsTooHigh) { nodeStore->load(key) ); } + +TEST_F(DataNodeStoreTest, CreatedInnerNodeIsInitialized) { + auto leaf = nodeStore->createNewLeafNode(); + auto node = nodeStore->createNewInnerNode(*leaf); + EXPECT_EQ(1u, node->numChildren()); + EXPECT_EQ(leaf->key(), node->getChild(0)->key()); +} + +TEST_F(DataNodeStoreTest, CreatedLeafNodeIsInitialized) { + auto leaf = nodeStore->createNewLeafNode(); + EXPECT_EQ(0u, leaf->numBytes()); +}