Implement DataLeafNode::resize and test cases for it

This commit is contained in:
Sebastian Messmer 2014-12-10 23:34:36 +01:00
parent eebe8a4b75
commit 24c81dd0b0
6 changed files with 53 additions and 15 deletions

View File

@ -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
}
}
}

View File

@ -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:

View File

@ -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<unsigned char>()+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<unsigned char>()+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;
}
}
}

View File

@ -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;
};

View File

@ -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<DataNode> load(std::unique_ptr<blockstore::Block> block);

View File

@ -25,15 +25,16 @@ class DataLeafNodeTest: public Test {
public:
unique_ptr<BlockStore> blockStore = make_unique<InMemoryBlockStore>();
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<unsigned int> {};
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()