Write factory methods in DataNode and write more test cases

This commit is contained in:
Sebastian Messmer 2014-12-10 22:55:02 +01:00
parent 1201823b68
commit eebe8a4b75
8 changed files with 60 additions and 30 deletions

View File

@ -14,7 +14,7 @@ DataInnerNode::DataInnerNode(DataNodeView view)
DataInnerNode::~DataInnerNode() { DataInnerNode::~DataInnerNode() {
} }
void DataInnerNode::InitializeNewInnerNode() { void DataInnerNode::InitializeNewNode() {
*_node.MagicNumber() = _node.magicNumberNodeWithChildren; *_node.MagicNumber() = _node.magicNumberNodeWithChildren;
*_node.Size() = 0; *_node.Size() = 0;
} }

View File

@ -9,23 +9,23 @@ namespace onblocks {
class DataInnerNode: public DataNode { class DataInnerNode: public DataNode {
public: public:
//TODO Creation of node objects should be in DataNode class (factory)
DataInnerNode(DataNodeView block); DataInnerNode(DataNodeView block);
virtual ~DataInnerNode(); virtual ~DataInnerNode();
void InitializeNewNode();
struct ChildEntry { struct ChildEntry {
uint32_t numBlocksInThisAndLeftwardNodes; uint32_t numBlocksInThisAndLeftwardNodes;
uint8_t key[Key::KEYLENGTH_BINARY]; uint8_t key[Key::KEYLENGTH_BINARY];
}; };
void InitializeNewInnerNode();
void read(off_t offset, size_t count, blockstore::Data *result) override; void read(off_t offset, size_t count, blockstore::Data *result) override;
void write(off_t offset, size_t count, const blockstore::Data &data) override; void write(off_t offset, size_t count, const blockstore::Data &data) override;
uint64_t numBytesInThisNode() override; uint64_t numBytesInThisNode() override;
private: private:
ChildEntry *ChildrenBegin(); ChildEntry *ChildrenBegin();
ChildEntry *ChildrenEnd(); ChildEntry *ChildrenEnd();
ChildEntry *ChildrenLast(); ChildEntry *ChildrenLast();

View File

@ -26,7 +26,7 @@ void DataLeafNode::write(off_t offset, size_t count, const Data &data) {
std::memcpy(_node.DataBegin<unsigned char>()+offset, data.data(), count); std::memcpy(_node.DataBegin<unsigned char>()+offset, data.data(), count);
} }
void DataLeafNode::InitializeNewLeafNode() { void DataLeafNode::InitializeNewNode() {
*_node.MagicNumber() = _node.magicNumberLeaf; *_node.MagicNumber() = _node.magicNumberLeaf;
*_node.Size() = 0; *_node.Size() = 0;
} }

View File

@ -9,16 +9,14 @@ namespace onblocks {
class DataLeafNode: public DataNode { class DataLeafNode: public DataNode {
public: public:
//TODO Creation of node objects should be in DataNode class (factory)
DataLeafNode(DataNodeView block); DataLeafNode(DataNodeView block);
virtual ~DataLeafNode(); virtual ~DataLeafNode();
void InitializeNewNode();
void read(off_t offset, size_t count, blockstore::Data *result) override; void read(off_t offset, size_t count, blockstore::Data *result) override;
void write(off_t offset, size_t count, const blockstore::Data &data) override; void write(off_t offset, size_t count, const blockstore::Data &data) override;
//TODO This should then also only be accessible for the DataNode class in its factory methods (we can override a general Initialize() method here)
void InitializeNewLeafNode();
uint64_t numBytesInThisNode() override; uint64_t numBytesInThisNode() override;
}; };

View File

@ -23,27 +23,26 @@ unique_ptr<DataNode> DataNode::load(unique_ptr<Block> block) {
DataNodeView node(std::move(block)); DataNodeView node(std::move(block));
if (*node.MagicNumber() == node.magicNumberNodeWithChildren) { if (*node.MagicNumber() == node.magicNumberNodeWithChildren) {
return make_unique<DataInnerNode>(std::move(node)); return unique_ptr<DataInnerNode>(new DataInnerNode(std::move(node)));
} else if (*node.MagicNumber() == node.magicNumberLeaf) { } else if (*node.MagicNumber() == node.magicNumberLeaf) {
return make_unique<DataLeafNode>(std::move(node)); return unique_ptr<DataLeafNode>(new DataLeafNode(std::move(node)));
} else { } else {
//TODO Better exception //TODO Better exception
throw runtime_error("Invalid node magic number"); throw runtime_error("Invalid node magic number");
} }
} }
/* unique_ptr<DataNode> DataNode::createNewInnerNode(unique_ptr<Block> block) {
unique_ptr<DataInnerNode> DataNodeView::initializeNewInnerNode(unique_ptr<Block> block) { auto newNode = unique_ptr<DataInnerNode>(new DataInnerNode(std::move(block)));
auto newNode = make_unique<DataInnerNode>(std::move(block)); newNode->InitializeNewNode();
newNode->InitializeEmptyInnerNode(); return std::move(newNode);
return newNode;
} }
unique_ptr<DataLeafNode> DataNodeView::initializeNewLeafNode(unique_ptr<Block> block) { unique_ptr<DataNode> DataNode::createNewLeafNode(unique_ptr<Block> block) {
auto newNode = make_unique<DataLeafNode>(std::move(block)); auto newNode = unique_ptr<DataLeafNode>(new DataLeafNode(std::move(block)));
newNode->InitializeEmptyLeaf(); newNode->InitializeNewNode();
return newNode; return std::move(newNode);
}*/ }
} }
} }

View File

@ -20,6 +20,8 @@ public:
virtual uint64_t numBytesInThisNode() = 0; virtual uint64_t numBytesInThisNode() = 0;
static std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block); static std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block);
static std::unique_ptr<DataNode> createNewLeafNode(std::unique_ptr<blockstore::Block> block);
static std::unique_ptr<DataNode> createNewInnerNode(std::unique_ptr<blockstore::Block> block);
protected: protected:
DataNode(DataNodeView block); DataNode(DataNodeView block);

View File

@ -19,6 +19,8 @@ using blockstore::inmemory::InMemoryBlockStore;
using namespace blobstore; using namespace blobstore;
using namespace blobstore::onblocks; using namespace blobstore::onblocks;
#define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type"
class DataLeafNodeTest: public Test { class DataLeafNodeTest: public Test {
public: public:
unique_ptr<BlockStore> blockStore = make_unique<InMemoryBlockStore>(); unique_ptr<BlockStore> blockStore = make_unique<InMemoryBlockStore>();
@ -31,14 +33,15 @@ public:
Key WriteDataToNewLeafBlockAndReturnKey() { Key WriteDataToNewLeafBlockAndReturnKey() {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
DataLeafNode leaf(DataNodeView(std::move(block.block))); auto leaf = DataNode::createNewLeafNode(std::move(block.block));
leaf.write(0, randomData.size(), randomData); leaf->write(0, randomData.size(), randomData);
return block.key; return block.key;
} }
void ReadDataFromLeafBlock(Key key, Data *data) { void ReadDataFromLeafBlock(Key key, Data *data) {
DataLeafNode leaf(DataNodeView(blockStore->load(key))); auto leaf = DataNode::load(blockStore->load(key));
leaf.read(0, data->size(), data); EXPECT_IS_PTR_TYPE(DataLeafNode, leaf.get());
leaf->read(0, data->size(), data);
} }
Data randomData; Data randomData;
@ -46,11 +49,11 @@ public:
TEST_F(DataLeafNodeTest, ReadWrittenDataImmediately) { TEST_F(DataLeafNodeTest, ReadWrittenDataImmediately) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
DataLeafNode leaf(DataNodeView(std::move(block.block))); auto leaf = DataNode::createNewLeafNode(std::move(block.block));
leaf.write(0, randomData.size(), randomData); leaf->write(0, randomData.size(), randomData);
Data read(DataNodeView::DATASIZE_BYTES); Data read(DataNodeView::DATASIZE_BYTES);
leaf.read(0, read.size(), &read); leaf->read(0, read.size(), &read);
EXPECT_EQ(0, std::memcmp(randomData.data(), read.data(), randomData.size())); EXPECT_EQ(0, std::memcmp(randomData.data(), read.data(), randomData.size()));
} }
@ -63,5 +66,21 @@ TEST_F(DataLeafNodeTest, ReadWrittenDataAfterReloadingBLock) {
EXPECT_EQ(0, std::memcmp(randomData.data(), data.data(), randomData.size())); EXPECT_EQ(0, std::memcmp(randomData.data(), data.data(), randomData.size()));
} }
TEST_F(DataLeafNodeTest, NewLeafNodeHasSizeZero) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
auto leaf = DataNode::createNewLeafNode(std::move(block.block));
EXPECT_EQ(0u, leaf->numBytesInThisNode());
}
TEST_F(DataLeafNodeTest, NewLeafNodeHasSizeZero_AfterLoading) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
{
DataNode::createNewLeafNode(std::move(block.block));
}
auto leaf = DataNode::load(blockStore->load(block.key));
EXPECT_EQ(0u, leaf->numBytesInThisNode());
}
//TODO Write tests that only read part of the data //TODO Write tests that only read part of the data
//TODO Test numBytesInThisNode() //TODO Test numBytesInThisNode()

View File

@ -24,11 +24,23 @@ public:
#define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type" #define EXPECT_IS_PTR_TYPE(Type, ptr) EXPECT_NE(nullptr, dynamic_cast<Type*>(ptr)) << "Given pointer cannot be cast to the given type"
TEST_F(DataNodeTest, CreateLeafNodeCreatesLeafNode) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
auto node = DataNode::createNewLeafNode(std::move(block.block));
EXPECT_IS_PTR_TYPE(DataLeafNode, node.get());
}
TEST_F(DataNodeTest, CreateInnerNodeCreatesInnerNode) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
auto node = DataNode::createNewInnerNode(std::move(block.block));
EXPECT_IS_PTR_TYPE(DataInnerNode, node.get());
}
TEST_F(DataNodeTest, LeafNodeIsRecognizedAfterStoreAndLoad) { TEST_F(DataNodeTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
Key key = block.key; Key key = block.key;
{ {
DataLeafNode(std::move(block.block)).InitializeNewLeafNode(); DataNode::createNewLeafNode(std::move(block.block));
} }
auto loaded_node = DataNode::load(blockStore->load(key)); auto loaded_node = DataNode::load(blockStore->load(key));
@ -40,7 +52,7 @@ TEST_F(DataNodeTest, InnerNodeIsRecognizedAfterStoreAndLoad) {
auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE);
Key key = block.key; Key key = block.key;
{ {
DataInnerNode(std::move(block.block)).InitializeNewInnerNode(); DataNode::createNewInnerNode(std::move(block.block));
} }
auto loaded_node = DataNode::load(blockStore->load(key)); auto loaded_node = DataNode::load(blockStore->load(key));