Allow adding children to DataInnerNode and write some test cases
This commit is contained in:
parent
17440ec52d
commit
a427b0e677
@ -21,7 +21,7 @@ DataInnerNode::~DataInnerNode() {
|
|||||||
void DataInnerNode::InitializeNewNode(const DataNode &first_child) {
|
void DataInnerNode::InitializeNewNode(const DataNode &first_child) {
|
||||||
*node().Depth() = first_child.depth() + 1;
|
*node().Depth() = first_child.depth() + 1;
|
||||||
*node().Size() = 1;
|
*node().Size() = 1;
|
||||||
first_child.key().ToBinary(ChildrenBegin()->key);
|
ChildrenBegin()->setKey(first_child.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DataInnerNode::numChildren() const {
|
uint32_t DataInnerNode::numChildren() const {
|
||||||
@ -44,10 +44,30 @@ const DataInnerNode::ChildEntry *DataInnerNode::ChildrenEnd() const {
|
|||||||
return ChildrenBegin() + *node().Size();
|
return ChildrenBegin() + *node().Size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataInnerNode::ChildEntry *DataInnerNode::RightmostExistingChild() const{
|
DataInnerNode::ChildEntry *DataInnerNode::LastChild() {
|
||||||
|
return const_cast<ChildEntry*>(const_cast<const DataInnerNode*>(this)->LastChild());
|
||||||
|
}
|
||||||
|
|
||||||
|
const DataInnerNode::ChildEntry *DataInnerNode::LastChild() const {
|
||||||
return ChildrenEnd()-1;
|
return ChildrenEnd()-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataInnerNode::ChildEntry *DataInnerNode::getChild(unsigned int index) {
|
||||||
|
return const_cast<ChildEntry*>(const_cast<const DataInnerNode*>(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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,21 +14,37 @@ public:
|
|||||||
virtual ~DataInnerNode();
|
virtual ~DataInnerNode();
|
||||||
|
|
||||||
struct ChildEntry {
|
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);
|
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 *ChildrenBegin();
|
||||||
ChildEntry *ChildrenEnd();
|
ChildEntry *ChildrenEnd();
|
||||||
const ChildEntry *ChildrenBegin() const;
|
const ChildEntry *ChildrenBegin() const;
|
||||||
const ChildEntry *ChildrenEnd() 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;
|
uint32_t numChildren() const;
|
||||||
|
|
||||||
|
void addChild(const DataNode &child_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1,64 @@
|
|||||||
//TODO
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <blobstore/implementations/onblocks/datanodestore/DataInnerNode.h>
|
||||||
|
#include <blobstore/implementations/onblocks/datanodestore/DataLeafNode.h>
|
||||||
|
#include <blobstore/implementations/onblocks/datanodestore/DataNodeStore.h>
|
||||||
|
|
||||||
|
#include "blockstore/implementations/testfake/FakeBlockStore.h"
|
||||||
|
#include "blockstore/implementations/testfake/FakeBlock.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
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<FakeBlockStore>()),
|
||||||
|
blockStore(_blockStore.get()),
|
||||||
|
nodeStore(make_unique<DataNodeStore>(std::move(_blockStore))),
|
||||||
|
leaf(nodeStore->createNewLeafNode()),
|
||||||
|
node(nodeStore->createNewInnerNode(*leaf)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr<BlockStore> _blockStore;
|
||||||
|
BlockStore *blockStore;
|
||||||
|
unique_ptr<DataNodeStore> nodeStore;
|
||||||
|
unique_ptr<DataLeafNode> leaf;
|
||||||
|
unique_ptr<DataInnerNode> 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());
|
||||||
|
}
|
||||||
|
@ -80,3 +80,15 @@ TEST_F(DataNodeStoreTest, DataNodeCrashesOnLoadIfDepthIsTooHigh) {
|
|||||||
nodeStore->load(key)
|
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());
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user