From 24c81dd0b03a42c6c52cb94a616332ceddc76018 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Wed, 10 Dec 2014 23:34:36 +0100 Subject: [PATCH] Implement DataLeafNode::resize and test cases for it --- .../onblocks/impl/DataInnerNode.cpp | 8 ++-- .../onblocks/impl/DataInnerNode.h | 7 +++- .../onblocks/impl/DataLeafNode.cpp | 11 +++++- .../onblocks/impl/DataLeafNode.h | 3 ++ .../implementations/onblocks/impl/DataNode.h | 1 + .../onblocks/impl/DataLeafNodeTest.cpp | 38 +++++++++++++++---- 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/blobstore/implementations/onblocks/impl/DataInnerNode.cpp b/src/blobstore/implementations/onblocks/impl/DataInnerNode.cpp index 92556f07..68f8d5b4 100644 --- a/src/blobstore/implementations/onblocks/impl/DataInnerNode.cpp +++ b/src/blobstore/implementations/onblocks/impl/DataInnerNode.cpp @@ -85,11 +85,13 @@ DataInnerNode::ChildEntry *DataInnerNode::ChildrenLast() { } void DataInnerNode::write(off_t offset, size_t count, const Data &data) { - //assert(count <= data.size()); - //assert(offset+count <= _node->DATASIZE_BYTES); - //std::memcpy(_node->DataBegin()+offset, result.data(), count); + //TODO Implement } +void DataInnerNode::resize(uint64_t newsize_bytes) { + //TODO Implement +} + } } diff --git a/src/blobstore/implementations/onblocks/impl/DataInnerNode.h b/src/blobstore/implementations/onblocks/impl/DataInnerNode.h index d71b6c93..6bb97977 100644 --- a/src/blobstore/implementations/onblocks/impl/DataInnerNode.h +++ b/src/blobstore/implementations/onblocks/impl/DataInnerNode.h @@ -12,17 +12,20 @@ public: DataInnerNode(DataNodeView block); virtual ~DataInnerNode(); - void InitializeNewNode(); - struct ChildEntry { uint32_t numBlocksInThisAndLeftwardNodes; uint8_t key[Key::KEYLENGTH_BINARY]; }; + static constexpr uint32_t MAX_STORED_CHILDREN = DataNodeView::DATASIZE_BYTES / sizeof(ChildEntry); + + void InitializeNewNode(); + 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; uint64_t numBytesInThisNode() override; + void resize(uint64_t newsize_bytes) override; private: diff --git a/src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp b/src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp index a4f4884c..2ec4897d 100644 --- a/src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp +++ b/src/blobstore/implementations/onblocks/impl/DataLeafNode.cpp @@ -9,6 +9,7 @@ namespace onblocks { DataLeafNode::DataLeafNode(DataNodeView view) : DataNode(std::move(view)) { + assert(numBytesInThisNode() <= MAX_STORED_BYTES); } DataLeafNode::~DataLeafNode() { @@ -16,13 +17,13 @@ DataLeafNode::~DataLeafNode() { void DataLeafNode::read(off_t offset, size_t count, Data *result) { assert(count <= result->size()); - assert(offset+count <= _node.DATASIZE_BYTES); + assert(offset+count <= numBytesInThisNode()); std::memcpy(result->data(), _node.DataBegin()+offset, count); } void DataLeafNode::write(off_t offset, size_t count, const Data &data) { assert(count <= data.size()); - assert(offset+count <= _node.DATASIZE_BYTES); + assert(offset+count <= numBytesInThisNode()); std::memcpy(_node.DataBegin()+offset, data.data(), count); } @@ -35,5 +36,11 @@ uint64_t DataLeafNode::numBytesInThisNode() { return *_node.Size(); } +void DataLeafNode::resize(uint64_t newsize_bytes) { + assert(newsize_bytes <= MAX_STORED_BYTES); + + *_node.Size() = newsize_bytes; +} + } } diff --git a/src/blobstore/implementations/onblocks/impl/DataLeafNode.h b/src/blobstore/implementations/onblocks/impl/DataLeafNode.h index 69c07035..62034b71 100644 --- a/src/blobstore/implementations/onblocks/impl/DataLeafNode.h +++ b/src/blobstore/implementations/onblocks/impl/DataLeafNode.h @@ -12,12 +12,15 @@ public: DataLeafNode(DataNodeView block); virtual ~DataLeafNode(); + static constexpr uint32_t MAX_STORED_BYTES = DataNodeView::DATASIZE_BYTES; + void InitializeNewNode(); 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; uint64_t numBytesInThisNode() override; + void resize(uint64_t newsize_bytes) override; }; diff --git a/src/blobstore/implementations/onblocks/impl/DataNode.h b/src/blobstore/implementations/onblocks/impl/DataNode.h index 01d0594b..918dfeb3 100644 --- a/src/blobstore/implementations/onblocks/impl/DataNode.h +++ b/src/blobstore/implementations/onblocks/impl/DataNode.h @@ -17,6 +17,7 @@ public: virtual void read(off_t offset, size_t count, blockstore::Data *result) = 0; virtual void write(off_t offset, size_t count, const blockstore::Data &data) = 0; + virtual void resize(uint64_t newsize_bytes) = 0; virtual uint64_t numBytesInThisNode() = 0; static std::unique_ptr load(std::unique_ptr block); diff --git a/src/test/blobstore/implementations/onblocks/impl/DataLeafNodeTest.cpp b/src/test/blobstore/implementations/onblocks/impl/DataLeafNodeTest.cpp index b9e3791e..5d912ce2 100644 --- a/src/test/blobstore/implementations/onblocks/impl/DataLeafNodeTest.cpp +++ b/src/test/blobstore/implementations/onblocks/impl/DataLeafNodeTest.cpp @@ -25,15 +25,16 @@ class DataLeafNodeTest: public Test { public: unique_ptr blockStore = make_unique(); - DataLeafNodeTest(): randomData(DataNodeView::DATASIZE_BYTES) { - DataBlockFixture dataFixture(DataNodeView::DATASIZE_BYTES); + DataLeafNodeTest(): randomData(DataLeafNode::MAX_STORED_BYTES) { + DataBlockFixture dataFixture(DataLeafNode::MAX_STORED_BYTES); std::memcpy(randomData.data(), dataFixture.data(), randomData.size()); } Key WriteDataToNewLeafBlockAndReturnKey() { - auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); auto leaf = DataNode::createNewLeafNode(std::move(block.block)); + leaf->resize(randomData.size()); leaf->write(0, randomData.size(), randomData); return block.key; } @@ -48,11 +49,12 @@ public: }; TEST_F(DataLeafNodeTest, ReadWrittenDataImmediately) { - auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); auto leaf = DataNode::createNewLeafNode(std::move(block.block)); + leaf->resize(randomData.size()); leaf->write(0, randomData.size(), randomData); - Data read(DataNodeView::DATASIZE_BYTES); + Data read(DataLeafNode::MAX_STORED_BYTES); leaf->read(0, read.size(), &read); EXPECT_EQ(0, std::memcmp(randomData.data(), read.data(), randomData.size())); } @@ -60,20 +62,20 @@ TEST_F(DataLeafNodeTest, ReadWrittenDataImmediately) { TEST_F(DataLeafNodeTest, ReadWrittenDataAfterReloadingBLock) { Key key = WriteDataToNewLeafBlockAndReturnKey(); - Data data(DataNodeView::DATASIZE_BYTES); + Data data(DataLeafNode::MAX_STORED_BYTES); ReadDataFromLeafBlock(key, &data); EXPECT_EQ(0, std::memcmp(randomData.data(), data.data(), randomData.size())); } TEST_F(DataLeafNodeTest, NewLeafNodeHasSizeZero) { - auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); auto leaf = DataNode::createNewLeafNode(std::move(block.block)); EXPECT_EQ(0u, leaf->numBytesInThisNode()); } TEST_F(DataLeafNodeTest, NewLeafNodeHasSizeZero_AfterLoading) { - auto block = blockStore->create(BlobStoreOnBlocks::BLOCKSIZE); + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); { DataNode::createNewLeafNode(std::move(block.block)); } @@ -82,5 +84,25 @@ TEST_F(DataLeafNodeTest, NewLeafNodeHasSizeZero_AfterLoading) { EXPECT_EQ(0u, leaf->numBytesInThisNode()); } +class DataLeafNodeSizeTest: public DataLeafNodeTest, public WithParamInterface {}; +INSTANTIATE_TEST_CASE_P(DataLeafNodeSizeTest, DataLeafNodeSizeTest, Values(0, 1, 5, 16, 32, 512, DataLeafNode::MAX_STORED_BYTES)); + +TEST_P(DataLeafNodeSizeTest, ResizeNode_ReadSizeImmediately) { + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); + auto leaf = DataNode::createNewLeafNode(std::move(block.block)); + leaf->resize(GetParam()); + EXPECT_EQ(GetParam(), leaf->numBytesInThisNode()); +} + +TEST_P(DataLeafNodeSizeTest, ResizeNode_ReadSizeAfterLoading) { + auto block = blockStore->create(DataNodeView::BLOCKSIZE_BYTES); + { + auto leaf = DataNode::createNewLeafNode(std::move(block.block)); + leaf->resize(GetParam()); + } + auto leaf = DataNode::load(blockStore->load(block.key)); + EXPECT_EQ(GetParam(), leaf->numBytesInThisNode()); +} + //TODO Write tests that only read part of the data //TODO Test numBytesInThisNode()