Implemented DataTree::resizeNumBytes(). No test cases yet.

This commit is contained in:
Sebastian Messmer 2015-02-26 17:33:47 +01:00
parent a66bccb122
commit 4e8e4ea3d3
5 changed files with 55 additions and 3 deletions

View File

@ -17,10 +17,14 @@ BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTree> datatree)
BlobOnBlocks::~BlobOnBlocks() {
}
size_t BlobOnBlocks::size() const {
uint64_t BlobOnBlocks::size() const {
return _datatree->numStoredBytes();
}
void BlobOnBlocks::resize(uint64_t numBytes) {
_datatree->resizeNumBytes(numBytes);
}
void BlobOnBlocks::flush() const {
_datatree->flush();
}

View File

@ -17,7 +17,8 @@ public:
BlobOnBlocks(std::unique_ptr<datatreestore::DataTree> datatree);
virtual ~BlobOnBlocks();
size_t size() const override;
uint64_t size() const override;
void resize(uint64_t numBytes) override;
void flush() const override;

View File

@ -7,6 +7,7 @@
#include "impl/algorithms.h"
#include "messmer/cpp-utils/pointer.h"
#include "messmer/cpp-utils/optional_ownership_ptr.h"
#include <cmath>
using blockstore::Key;
@ -21,6 +22,8 @@ using std::function;
using cpputils::dynamic_pointer_move;
using cpputils::optional_ownership_ptr;
using cpputils::WithOwnership;
using cpputils::WithoutOwnership;
namespace blobstore {
namespace onblocks {
@ -177,6 +180,43 @@ uint64_t DataTree::numStoredBytes(const DataNode &root) const {
return numBytesInLeftChildren + numBytesInRightChild;
}
void DataTree::resizeNumBytes(uint64_t newNumBytes) {
//TODO Faster implementation possible
LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf());
uint64_t currentNumBytes = numStoredBytes();
assert(currentNumBytes % _nodeStore->layout().maxBytesPerLeaf() == 0);
uint32_t currentNumLeaves = currentNumBytes / _nodeStore->layout().maxBytesPerLeaf();
uint32_t newNumLeaves = ceilDivision(newNumBytes, _nodeStore->layout().maxBytesPerLeaf());
for(uint32_t i = currentNumLeaves; i < newNumLeaves; ++i) {
addDataLeaf();
}
for(uint32_t i = currentNumLeaves; i > newNumLeaves; --i) {
removeLastDataLeaf();
}
uint32_t newLastLeafSize = newNumBytes - (newNumLeaves-1)*_nodeStore->layout().maxBytesPerLeaf();
LastLeaf(_rootNode.get())->resize(newLastLeafSize);
}
optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *root) {
DataLeafNode *leaf = dynamic_cast<DataLeafNode*>(root);
if (leaf != nullptr) {
return WithoutOwnership(leaf);
}
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root);
return WithOwnership(LastLeaf(_nodeStore->load(inner->LastChild()->key())));
}
unique_ptr<DataLeafNode> DataTree::LastLeaf(unique_ptr<DataNode> root) {
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
if (leaf.get() != nullptr) {
return leaf;
}
auto inner = dynamic_pointer_move<DataInnerNode>(root);
return LastLeaf(_nodeStore->load(inner->LastChild()->key()));
}
}
}
}

View File

@ -33,6 +33,9 @@ public:
void traverseLeaves(uint32_t beginIndex, uint32_t endIndex, std::function<void (datanodestore::DataLeafNode*, uint32_t)> func);
uint64_t numStoredBytes() const;
void resizeNumBytes(uint64_t newNumBytes);
//TODO Test resizeNumBytes()
private:
datanodestore::DataNodeStore *_nodeStore;
@ -51,6 +54,8 @@ private:
void traverseLeaves(datanodestore::DataNode *root, uint32_t leafOffset, uint32_t beginIndex, uint32_t endIndex, std::function<void (datanodestore::DataLeafNode*, uint32_t)> func);
uint32_t leavesPerFullChild(const datanodestore::DataInnerNode &root) const;
uint64_t numStoredBytes(const datanodestore::DataNode &root) const;
cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> LastLeaf(datanodestore::DataNode *root);
std::unique_ptr<datanodestore::DataLeafNode> LastLeaf(std::unique_ptr<datanodestore::DataNode> root);
DISALLOW_COPY_AND_ASSIGN(DataTree);
};

View File

@ -3,6 +3,7 @@
#define BLOBSTORE_INTERFACE_BLOB_H_
#include <cstring>
#include <cstdint>
namespace blobstore {
@ -10,7 +11,8 @@ class Blob {
public:
virtual ~Blob() {}
virtual size_t size() const = 0;
virtual uint64_t size() const = 0;
virtual void resize(uint64_t numBytes) = 0;
virtual void flush() const = 0;
};