Implement copying DataNode blocks and finish DataTree::addDataLeaf implementation

This commit is contained in:
Sebastian Messmer 2015-01-24 01:59:42 +01:00
parent d442016d16
commit 03e10cabf5
8 changed files with 63 additions and 8 deletions

View File

@ -26,6 +26,7 @@ protected:
DataNodeView &node();
const DataNodeView &node() const;
friend class DataNodeStore;
private:
blockstore::Key _key; //TODO Remove this and make blockstore::Block store the key

View File

@ -3,6 +3,7 @@
#include "DataNodeStore.h"
#include "blockstore/interface/BlockStore.h"
#include "blockstore/interface/Block.h"
#include "blockstore/utils/BlockStoreUtils.h"
using blockstore::BlockStore;
@ -53,6 +54,11 @@ unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
return load(_blockstore->load(key), key);
}
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block());
return load(std::move(newBlock.block), newBlock.key);
}
}
}
}

View File

@ -30,6 +30,8 @@ public:
std::unique_ptr<DataLeafNode> createNewLeafNode();
std::unique_ptr<DataInnerNode> createNewInnerNode(const DataNode &first_child);
std::unique_ptr<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
private:
std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block, const blockstore::Key &key);

View File

@ -76,6 +76,10 @@ public:
return std::move(_block);
}
const blockstore::Block &block() const {
return *_block;
}
private:
template<int offset, class Type>
const Type *GetOffset() const {

View File

@ -76,19 +76,13 @@ optional_ownership_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int
}
unique_ptr<DataLeafNode> DataTree::addDataLeafToFullTree() {
auto copyOfOldRoot = copyNode(*_rootNode);
auto copyOfOldRoot = _nodeStore->createNewNodeAsCopyFrom(*_rootNode);
auto newRootNode = DataNode::convertToNewInnerNode(std::move(_rootNode), *copyOfOldRoot);
auto newLeaf = addDataLeafAt(newRootNode.get());
_rootNode = std::move(newRootNode);
return newLeaf;
}
unique_ptr<DataNode> DataTree::copyNode(const DataNode &source) {
//TODO
assert(false);
return nullptr;
}
}

View File

@ -31,7 +31,6 @@ private:
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafAt(datanodestore::DataInnerNode *insertPos);
fspp::ptr::optional_ownership_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, datanodestore::DataLeafNode *leaf);
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafToFullTree();
std::unique_ptr<datanodestore::DataNode> copyNode(const datanodestore::DataNode &source);
DISALLOW_COPY_AND_ASSIGN(DataTree);
};

View File

@ -87,6 +87,11 @@ public:
return converted->key();
}
unique_ptr<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
return dynamic_pointer_move<DataInnerNode>(copied);
}
Data ZEROES;
unique_ptr<BlockStore> _blockStore;
BlockStore *blockStore;
@ -169,5 +174,26 @@ TEST_F(DataInnerNodeTest, ConvertToInternalNodeZeroesOutChildrenRegion) {
EXPECT_EQ(0, std::memcmp(ZEROES.data(), (uint8_t*)block->data()+DataNodeView::HEADERSIZE_BYTES+sizeof(DataInnerNode::ChildEntry), DataLeafNode::MAX_STORED_BYTES-sizeof(DataInnerNode::ChildEntry)));
}
TEST_F(DataInnerNodeTest, CopyingCreatesNewNode) {
auto copied = CopyInnerNode(*node);
EXPECT_NE(node->key(), copied->key());
}
TEST_F(DataInnerNodeTest, CopyInnerNodeWithOneChild) {
auto copied = CopyInnerNode(*node);
EXPECT_EQ(node->numChildren(), copied->numChildren());
EXPECT_EQ(node->getChild(0)->key(), copied->getChild(0)->key());
}
TEST_F(DataInnerNodeTest, CopyInnerNodeWithTwoChildren) {
AddALeafTo(node.get());
auto copied = CopyInnerNode(*node);
EXPECT_EQ(node->numChildren(), copied->numChildren());
EXPECT_EQ(node->getChild(0)->key(), copied->getChild(0)->key());
EXPECT_EQ(node->getChild(1)->key(), copied->getChild(1)->key());
}
//TODO TestCase for LastChild

View File

@ -84,6 +84,11 @@ public:
return converted->key();
}
unique_ptr<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
return dynamic_pointer_move<DataLeafNode>(copied);
}
Data ZEROES;
Data randomData;
unique_ptr<BlockStore> _blockStore;
@ -204,6 +209,24 @@ TEST_F(DataLeafNodeTest, ConvertToInternalNodeZeroesOutChildrenRegion) {
EXPECT_EQ(0, std::memcmp(ZEROES.data(), (uint8_t*)block->data()+DataNodeView::HEADERSIZE_BYTES+sizeof(DataInnerNode::ChildEntry), DataLeafNode::MAX_STORED_BYTES-sizeof(DataInnerNode::ChildEntry)));
}
TEST_F(DataLeafNodeTest, CopyingCreatesANewLeaf) {
auto copied = CopyLeafNode(*leaf);
EXPECT_NE(leaf->key(), copied->key());
}
TEST_F(DataLeafNodeTest, CopyEmptyLeaf) {
auto copied = CopyLeafNode(*leaf);
EXPECT_EQ(leaf->numBytes(), copied->numBytes());
}
TEST_F(DataLeafNodeTest, CopyDataLeaf) {
FillLeafBlockWithData();
auto copied = CopyLeafNode(*leaf);
EXPECT_EQ(leaf->numBytes(), copied->numBytes());
EXPECT_EQ(0, std::memcmp(leaf->data(), copied->data(), leaf->numBytes()));
EXPECT_NE(leaf->data(), copied->data());
}
/* TODO
* The following test cases test reading/writing part of a leaf. This doesn't make much sense,