Refactor initialization of DataLeafNode/DataInnerNode

This commit is contained in:
Sebastian Messmer 2015-02-20 19:46:52 +01:00
parent 8b792e691c
commit 0607dcb282
8 changed files with 45 additions and 25 deletions

View File

@ -2,6 +2,7 @@
#include "DataNodeStore.h" #include "DataNodeStore.h"
using std::unique_ptr; using std::unique_ptr;
using std::make_unique;
using blockstore::Block; using blockstore::Block;
using blockstore::Data; using blockstore::Data;
using blockstore::Key; using blockstore::Key;
@ -14,15 +15,23 @@ constexpr uint32_t DataInnerNode::MAX_STORED_CHILDREN;
DataInnerNode::DataInnerNode(DataNodeView view) DataInnerNode::DataInnerNode(DataNodeView view)
: DataNode(std::move(view)) { : DataNode(std::move(view)) {
assert(depth() > 0);
} }
DataInnerNode::~DataInnerNode() { DataInnerNode::~DataInnerNode() {
} }
void DataInnerNode::InitializeNewNode(const DataNode &first_child) { unique_ptr<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ptr<Block> block, const DataNode &first_child) {
*node().Depth() = first_child.depth() + 1; DataNodeView node(std::move(block));
*node().Size() = 1; *node.Depth() = first_child.depth() + 1;
ChildrenBegin()->setKey(first_child.key()); *node.Size() = 1;
auto result = make_unique<DataInnerNode>(std::move(node));
result->ChildrenBegin()->setKey(first_child.key());
return result;
}
uint8_t DataInnerNode::depth() const {
return *node().Depth();
} }
uint32_t DataInnerNode::numChildren() const { uint32_t DataInnerNode::numChildren() const {

View File

@ -10,6 +10,8 @@ namespace datanodestore {
class DataInnerNode: public DataNode { class DataInnerNode: public DataNode {
public: public:
static std::unique_ptr<DataInnerNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block, const DataNode &first_child_key);
DataInnerNode(DataNodeView block); DataInnerNode(DataNodeView block);
virtual ~DataInnerNode(); virtual ~DataInnerNode();
@ -29,7 +31,7 @@ public:
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_key); uint8_t depth() const;
ChildEntry *getChild(unsigned int index); ChildEntry *getChild(unsigned int index);
const ChildEntry *getChild(unsigned int index) const; const ChildEntry *getChild(unsigned int index) const;

View File

@ -13,16 +13,19 @@ namespace datanodestore {
DataLeafNode::DataLeafNode(DataNodeView view) DataLeafNode::DataLeafNode(DataNodeView view)
: DataNode(std::move(view)) { : DataNode(std::move(view)) {
assert(*node().Depth() == 0);
assert(numBytes() <= MAX_STORED_BYTES); assert(numBytes() <= MAX_STORED_BYTES);
} }
DataLeafNode::~DataLeafNode() { DataLeafNode::~DataLeafNode() {
} }
void DataLeafNode::InitializeNewNode() { unique_ptr<DataLeafNode> DataLeafNode::InitializeNewNode(unique_ptr<Block> block) {
*node().Depth() = 0; DataNodeView node(std::move(block));
*node().Size() = 0; *node.Depth() = 0;
*node.Size() = 0;
//fillDataWithZeroes(); not needed, because a newly created block will be zeroed out. DataLeafNodeTest.SpaceIsZeroFilledWhenGrowing ensures this. //fillDataWithZeroes(); not needed, because a newly created block will be zeroed out. DataLeafNodeTest.SpaceIsZeroFilledWhenGrowing ensures this.
return make_unique<DataLeafNode>(std::move(node));
} }
void *DataLeafNode::data() { void *DataLeafNode::data() {

View File

@ -11,13 +11,13 @@ class DataInnerNode;
class DataLeafNode: public DataNode { class DataLeafNode: public DataNode {
public: public:
static std::unique_ptr<DataLeafNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block);
DataLeafNode(DataNodeView block); DataLeafNode(DataNodeView block);
virtual ~DataLeafNode(); virtual ~DataLeafNode();
static constexpr uint32_t MAX_STORED_BYTES = DataNodeView::DATASIZE_BYTES; static constexpr uint32_t MAX_STORED_BYTES = DataNodeView::DATASIZE_BYTES;
void InitializeNewNode();
void *data(); void *data();
const void *data() const; const void *data() const;

View File

@ -42,9 +42,7 @@ unique_ptr<DataInnerNode> DataNode::convertToNewInnerNode(unique_ptr<DataNode> n
auto block = node->_node.releaseBlock(); auto block = node->_node.releaseBlock();
std::memset(block->data(), 0, block->size()); std::memset(block->data(), 0, block->size());
auto innerNode = make_unique<DataInnerNode>(DataNodeView(std::move(block))); return DataInnerNode::InitializeNewNode(std::move(block), first_child);
innerNode->InitializeNewNode(first_child);
return innerNode;
} }
void DataNode::flush() const { void DataNode::flush() const {

View File

@ -38,16 +38,12 @@ unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) { unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES); auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
auto newNode = make_unique<DataInnerNode>(std::move(block)); return DataInnerNode::InitializeNewNode(std::move(block), first_child);
newNode->InitializeNewNode(first_child);
return std::move(newNode);
} }
unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() { unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES); auto block = _blockstore->create(DataNodeView::BLOCKSIZE_BYTES);
auto newNode = make_unique<DataLeafNode>(std::move(block)); return DataLeafNode::InitializeNewNode(std::move(block));
newNode->InitializeNewNode();
return std::move(newNode);
} }
unique_ptr<DataNode> DataNodeStore::load(const Key &key) { unique_ptr<DataNode> DataNodeStore::load(const Key &key) {

View File

@ -92,6 +92,12 @@ public:
return dynamic_pointer_move<DataInnerNode>(copied); return dynamic_pointer_move<DataInnerNode>(copied);
} }
Key InitializeInnerNodeAddLeafReturnKey() {
auto node = DataInnerNode::InitializeNewNode(blockStore->create(DataNodeView::BLOCKSIZE_BYTES), *leaf);
AddALeafTo(node.get());
return node->key();
}
Data ZEROES; Data ZEROES;
unique_ptr<BlockStore> _blockStore; unique_ptr<BlockStore> _blockStore;
BlockStore *blockStore; BlockStore *blockStore;
@ -101,15 +107,15 @@ public:
}; };
TEST_F(DataInnerNodeTest, InitializesCorrectly) { TEST_F(DataInnerNodeTest, InitializesCorrectly) {
node->InitializeNewNode(*leaf); auto node = DataInnerNode::InitializeNewNode(blockStore->create(DataNodeView::BLOCKSIZE_BYTES), *leaf);
EXPECT_EQ(1u, node->numChildren()); EXPECT_EQ(1u, node->numChildren());
EXPECT_EQ(leaf->key(), node->getChild(0)->key()); EXPECT_EQ(leaf->key(), node->getChild(0)->key());
} }
TEST_F(DataInnerNodeTest, ReinitializesCorrectly) { TEST_F(DataInnerNodeTest, ReinitializesCorrectly) {
AddALeafTo(node.get()); auto key = InitializeInnerNodeAddLeafReturnKey();
node->InitializeNewNode(*leaf); auto node = DataInnerNode::InitializeNewNode(blockStore->load(key), *leaf);
EXPECT_EQ(1u, node->numChildren()); EXPECT_EQ(1u, node->numChildren());
EXPECT_EQ(leaf->key(), node->getChild(0)->key()); EXPECT_EQ(leaf->key(), node->getChild(0)->key());

View File

@ -88,6 +88,12 @@ public:
return dynamic_pointer_move<DataLeafNode>(copied); return dynamic_pointer_move<DataLeafNode>(copied);
} }
Key InitializeLeafGrowAndReturnKey() {
auto leaf = DataLeafNode::InitializeNewNode(blockStore->create(DataNodeView::BLOCKSIZE_BYTES));
leaf->resize(5);
return leaf->key();
}
Data ZEROES; Data ZEROES;
Data randomData; Data randomData;
unique_ptr<BlockStore> _blockStore; unique_ptr<BlockStore> _blockStore;
@ -97,13 +103,13 @@ public:
}; };
TEST_F(DataLeafNodeTest, InitializesCorrectly) { TEST_F(DataLeafNodeTest, InitializesCorrectly) {
leaf->InitializeNewNode(); auto leaf = DataLeafNode::InitializeNewNode(blockStore->create(DataNodeView::BLOCKSIZE_BYTES));
EXPECT_EQ(0u, leaf->numBytes()); EXPECT_EQ(0u, leaf->numBytes());
} }
TEST_F(DataLeafNodeTest, ReinitializesCorrectly) { TEST_F(DataLeafNodeTest, ReinitializesCorrectly) {
leaf->resize(5); auto key = InitializeLeafGrowAndReturnKey();
leaf->InitializeNewNode(); auto leaf = DataLeafNode::InitializeNewNode(blockStore->load(key));
EXPECT_EQ(0u, leaf->numBytes()); EXPECT_EQ(0u, leaf->numBytes());
} }