Use unique_ref instead of unique_ptr

This commit is contained in:
Sebastian Messmer 2015-06-26 15:59:18 +02:00
parent 7fae2d1e59
commit 3d1341114b
36 changed files with 346 additions and 316 deletions

View File

@ -5,8 +5,8 @@
#include "utils/Math.h"
#include <cmath>
using std::unique_ptr;
using std::function;
using cpputils::unique_ref;
using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataNodeLayout;
using blockstore::Key;
@ -16,7 +16,7 @@ namespace onblocks {
using parallelaccessdatatreestore::DataTreeRef;
BlobOnBlocks::BlobOnBlocks(unique_ptr<DataTreeRef> datatree)
BlobOnBlocks::BlobOnBlocks(unique_ref<DataTreeRef> datatree)
: _datatree(std::move(datatree)) {
}
@ -86,7 +86,7 @@ Key BlobOnBlocks::key() const {
return _datatree->key();
}
unique_ptr<DataTreeRef> BlobOnBlocks::releaseTree() {
unique_ref<DataTreeRef> BlobOnBlocks::releaseTree() {
return std::move(_datatree);
}

View File

@ -17,7 +17,7 @@ class DataTreeRef;
class BlobOnBlocks: public Blob {
public:
BlobOnBlocks(std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> datatree);
BlobOnBlocks(cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> datatree);
virtual ~BlobOnBlocks();
blockstore::Key key() const override;
@ -31,14 +31,14 @@ public:
void flush() override;
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> releaseTree();
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> releaseTree();
private:
void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function<void (uint64_t, datanodestore::DataLeafNode *, uint32_t, uint32_t)>) const;
void resizeIfSmallerThan(uint64_t neededSize);
std::unique_ptr<parallelaccessdatatreestore::DataTreeRef> _datatree;
cpputils::unique_ref<parallelaccessdatatreestore::DataTreeRef> _datatree;
};
}

View File

@ -9,9 +9,6 @@
#include "BlobOnBlocks.h"
#include <messmer/cpp-utils/pointer/cast.h>
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
@ -29,8 +26,8 @@ using datanodestore::DataNodeStore;
using datatreestore::DataTreeStore;
using parallelaccessdatatreestore::ParallelAccessDataTreeStore;
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ptr<BlockStore> blockStore, uint32_t blocksizeBytes)
: _dataTreeStore(make_unique<ParallelAccessDataTreeStore>(make_unique<DataTreeStore>(make_unique<DataNodeStore>(make_unique<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ref<BlockStore> blockStore, uint32_t blocksizeBytes)
: _dataTreeStore(make_unique_ref<ParallelAccessDataTreeStore>(make_unique_ref<DataTreeStore>(make_unique_ref<DataNodeStore>(make_unique_ref<ParallelAccessBlockStore>(std::move(blockStore)), blocksizeBytes)))) {
}
BlobStoreOnBlocks::~BlobStoreOnBlocks() {
@ -42,10 +39,10 @@ unique_ref<Blob> BlobStoreOnBlocks::create() {
optional<unique_ref<Blob>> BlobStoreOnBlocks::load(const Key &key) {
auto tree = _dataTreeStore->load(key);
if (tree == nullptr) {
if (tree == none) {
return none;
}
return optional<unique_ref<Blob>>(make_unique_ref<BlobOnBlocks>(std::move(tree)));
return optional<unique_ref<Blob>>(make_unique_ref<BlobOnBlocks>(std::move(*tree)));
}
void BlobStoreOnBlocks::remove(unique_ref<Blob> blob) {

View File

@ -15,7 +15,7 @@ class ParallelAccessDataTreeStore;
class BlobStoreOnBlocks: public BlobStore {
public:
BlobStoreOnBlocks(std::unique_ptr<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
BlobStoreOnBlocks(cpputils::unique_ref<blockstore::BlockStore> blockStore, uint32_t blocksizeBytes);
virtual ~BlobStoreOnBlocks();
cpputils::unique_ref<Blob> create() override;
@ -24,7 +24,7 @@ public:
void remove(cpputils::unique_ref<Blob> blob) override;
private:
std::unique_ptr<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
cpputils::unique_ref<parallelaccessdatatreestore::ParallelAccessDataTreeStore> _dataTreeStore;
};
}

View File

@ -2,9 +2,10 @@
#include "DataNodeStore.h"
using std::unique_ptr;
using std::make_unique;
using blockstore::Block;
using cpputils::Data;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using blockstore::Key;
namespace blobstore {
@ -19,11 +20,11 @@ DataInnerNode::DataInnerNode(DataNodeView view)
DataInnerNode::~DataInnerNode() {
}
unique_ptr<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ptr<Block> block, const DataNode &first_child) {
unique_ref<DataInnerNode> DataInnerNode::InitializeNewNode(unique_ptr<Block> block, const DataNode &first_child) {
DataNodeView node(std::move(block));
node.setDepth(first_child.depth() + 1);
node.setSize(1);
auto result = make_unique<DataInnerNode>(std::move(node));
auto result = make_unique_ref<DataInnerNode>(std::move(node));
result->ChildrenBegin()->setKey(first_child.key());
return result;
}

View File

@ -11,7 +11,7 @@ namespace datanodestore {
class DataInnerNode: public DataNode {
public:
static std::unique_ptr<DataInnerNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block, const DataNode &first_child_key);
static cpputils::unique_ref<DataInnerNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block, const DataNode &first_child_key);
DataInnerNode(DataNodeView block);
virtual ~DataInnerNode();

View File

@ -2,10 +2,11 @@
#include "DataInnerNode.h"
using std::unique_ptr;
using std::make_unique;
using blockstore::Block;
using cpputils::Data;
using blockstore::Key;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
namespace blobstore {
namespace onblocks {
@ -20,12 +21,12 @@ DataLeafNode::DataLeafNode(DataNodeView view)
DataLeafNode::~DataLeafNode() {
}
unique_ptr<DataLeafNode> DataLeafNode::InitializeNewNode(unique_ptr<Block> block) {
unique_ref<DataLeafNode> DataLeafNode::InitializeNewNode(unique_ptr<Block> block) {
DataNodeView node(std::move(block));
node.setDepth(0);
node.setSize(0);
//fillDataWithZeroes(); not needed, because a newly created block will be zeroed out. DataLeafNodeTest.SpaceIsZeroFilledWhenGrowing ensures this.
return make_unique<DataLeafNode>(std::move(node));
return make_unique_ref<DataLeafNode>(std::move(node));
}
void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const {

View File

@ -11,7 +11,7 @@ class DataInnerNode;
class DataLeafNode: public DataNode {
public:
static std::unique_ptr<DataLeafNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block);
static cpputils::unique_ref<DataLeafNode> InitializeNewNode(std::unique_ptr<blockstore::Block> block);
DataLeafNode(DataNodeView block);
virtual ~DataLeafNode();

View File

@ -7,9 +7,8 @@
using blockstore::Block;
using blockstore::Key;
using std::unique_ptr;
using std::make_unique;
using std::runtime_error;
using cpputils::unique_ref;
namespace blobstore {
namespace onblocks {
@ -38,7 +37,7 @@ uint8_t DataNode::depth() const {
return _node.Depth();
}
unique_ptr<DataInnerNode> DataNode::convertToNewInnerNode(unique_ptr<DataNode> node, const DataNode &first_child) {
unique_ref<DataInnerNode> DataNode::convertToNewInnerNode(unique_ref<DataNode> node, const DataNode &first_child) {
Key key = node->key();
auto block = node->_node.releaseBlock();
blockstore::utils::fillWithZeroes(block.get());

View File

@ -19,7 +19,7 @@ public:
uint8_t depth() const;
static std::unique_ptr<DataInnerNode> convertToNewInnerNode(std::unique_ptr<DataNode> node, const DataNode &first_child);
static cpputils::unique_ref<DataInnerNode> convertToNewInnerNode(cpputils::unique_ref<DataNode> node, const DataNode &first_child);
void flush() const;

View File

@ -10,76 +10,81 @@ using blockstore::BlockStore;
using blockstore::Block;
using blockstore::Key;
using cpputils::Data;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using std::unique_ptr;
using std::make_unique;
using std::runtime_error;
using boost::optional;
using boost::none;
namespace blobstore {
namespace onblocks {
namespace datanodestore {
DataNodeStore::DataNodeStore(unique_ptr<BlockStore> blockstore, uint32_t blocksizeBytes)
DataNodeStore::DataNodeStore(unique_ref<BlockStore> blockstore, uint32_t blocksizeBytes)
: _blockstore(std::move(blockstore)), _layout(blocksizeBytes) {
}
DataNodeStore::~DataNodeStore() {
}
unique_ptr<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
unique_ref<DataNode> DataNodeStore::load(unique_ptr<Block> block) {
assert(block->size() == _layout.blocksizeBytes());
DataNodeView node(std::move(block));
if (node.Depth() == 0) {
return unique_ptr<DataLeafNode>(new DataLeafNode(std::move(node)));
return make_unique_ref<DataLeafNode>(std::move(node));
} else if (node.Depth() <= MAX_DEPTH) {
return unique_ptr<DataInnerNode>(new DataInnerNode(std::move(node)));
return make_unique_ref<DataInnerNode>(std::move(node));
} else {
throw runtime_error("Tree is to deep. Data corruption?");
}
}
unique_ptr<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
unique_ref<DataInnerNode> DataNodeStore::createNewInnerNode(const DataNode &first_child) {
assert(first_child.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
return DataInnerNode::InitializeNewNode(std::move(block), first_child);
}
unique_ptr<DataLeafNode> DataNodeStore::createNewLeafNode() {
unique_ref<DataLeafNode> DataNodeStore::createNewLeafNode() {
//TODO Initialize block and then create it in the blockstore - this is more efficient than creating it and then writing to it
auto block = _blockstore->create(Data(_layout.blocksizeBytes()).FillWithZeroes());
return DataLeafNode::InitializeNewNode(std::move(block));
}
unique_ptr<DataNode> DataNodeStore::load(const Key &key) {
optional<unique_ref<DataNode>> DataNodeStore::load(const Key &key) {
auto block = _blockstore->load(key);
if (block == nullptr) {
return nullptr;
return none;
}
return load(std::move(block));
}
unique_ptr<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
unique_ref<DataNode> DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) {
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes()); // This might be violated if source is from a different DataNodeStore
auto newBlock = blockstore::utils::copyToNewBlock(_blockstore.get(), source.node().block());
return load(std::move(newBlock));
}
unique_ptr<DataNode> DataNodeStore::overwriteNodeWith(unique_ptr<DataNode> target, const DataNode &source) {
unique_ref<DataNode> DataNodeStore::overwriteNodeWith(unique_ref<DataNode> target, const DataNode &source) {
assert(target->node().layout().blocksizeBytes() == _layout.blocksizeBytes());
assert(source.node().layout().blocksizeBytes() == _layout.blocksizeBytes());
Key key = target->key();
{
auto targetBlock = target->node().releaseBlock();
target.reset();
cpputils::to_unique_ptr(std::move(target)).reset(); // Call destructor
blockstore::utils::copyTo(targetBlock.get(), source.node().block());
}
return load(key);
auto loaded = load(key);
assert(loaded != none);
return std::move(*loaded);
}
void DataNodeStore::remove(unique_ptr<DataNode> node) {
void DataNodeStore::remove(unique_ref<DataNode> node) {
auto block = node->node().releaseBlock();
node.reset();
cpputils::to_unique_ptr(std::move(node)).reset(); // Call destructor
_blockstore->remove(std::move(block));
}
@ -87,12 +92,13 @@ uint64_t DataNodeStore::numNodes() const {
return _blockstore->numBlocks();
}
void DataNodeStore::removeSubtree(unique_ptr<DataNode> node) {
void DataNodeStore::removeSubtree(unique_ref<DataNode> node) {
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(node.get());
if (inner != nullptr) {
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
auto child = load(inner->getChild(i)->key());
removeSubtree(std::move(child));
assert(child != none);
removeSubtree(std::move(*child));
}
}
remove(std::move(node));

View File

@ -21,33 +21,33 @@ class DataInnerNode;
class DataNodeStore {
public:
DataNodeStore(std::unique_ptr<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
DataNodeStore(cpputils::unique_ref<blockstore::BlockStore> blockstore, uint32_t blocksizeBytes);
virtual ~DataNodeStore();
static constexpr uint8_t MAX_DEPTH = 10;
DataNodeLayout layout() const;
std::unique_ptr<DataNode> load(const blockstore::Key &key);
boost::optional<cpputils::unique_ref<DataNode>> load(const blockstore::Key &key);
std::unique_ptr<DataLeafNode> createNewLeafNode();
std::unique_ptr<DataInnerNode> createNewInnerNode(const DataNode &first_child);
cpputils::unique_ref<DataLeafNode> createNewLeafNode();
cpputils::unique_ref<DataInnerNode> createNewInnerNode(const DataNode &first_child);
std::unique_ptr<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
cpputils::unique_ref<DataNode> createNewNodeAsCopyFrom(const DataNode &source);
std::unique_ptr<DataNode> overwriteNodeWith(std::unique_ptr<DataNode> target, const DataNode &source);
cpputils::unique_ref<DataNode> overwriteNodeWith(cpputils::unique_ref<DataNode> target, const DataNode &source);
void remove(std::unique_ptr<DataNode> node);
void remove(cpputils::unique_ref<DataNode> node);
void removeSubtree(std::unique_ptr<DataNode> node);
void removeSubtree(cpputils::unique_ref<DataNode> node);
uint64_t numNodes() const;
//TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree()
private:
std::unique_ptr<DataNode> load(std::unique_ptr<blockstore::Block> block);
cpputils::unique_ref<DataNode> load(std::unique_ptr<blockstore::Block> block);
std::unique_ptr<blockstore::BlockStore> _blockstore;
cpputils::unique_ref<blockstore::BlockStore> _blockstore;
const DataNodeLayout _layout;
DISALLOW_COPY_AND_ASSIGN(DataNodeStore);

View File

@ -18,24 +18,25 @@ using blobstore::onblocks::datanodestore::DataInnerNode;
using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datanodestore::DataNodeLayout;
using std::unique_ptr;
using std::dynamic_pointer_cast;
using std::function;
using boost::shared_mutex;
using boost::shared_lock;
using boost::unique_lock;
using boost::none;
using std::vector;
using cpputils::dynamic_pointer_move;
using cpputils::optional_ownership_ptr;
using cpputils::WithOwnership;
using cpputils::WithoutOwnership;
using cpputils::unique_ref;
namespace blobstore {
namespace onblocks {
namespace datatreestore {
DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr<DataNode> rootNode)
DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode)
: _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)) {
}
@ -56,18 +57,20 @@ void DataTree::ifRootHasOnlyOneChildReplaceRootWithItsChild() {
assert(rootNode != nullptr);
if (rootNode->numChildren() == 1) {
auto child = _nodeStore->load(rootNode->getChild(0)->key());
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), *child);
_nodeStore->remove(std::move(child));
assert(child != none);
_rootNode = _nodeStore->overwriteNodeWith(std::move(_rootNode), **child);
_nodeStore->remove(std::move(*child));
}
}
void DataTree::deleteLastChildSubtree(DataInnerNode *node) {
auto lastChild = _nodeStore->load(node->LastChild()->key());
_nodeStore->removeSubtree(std::move(lastChild));
assert(lastChild != none);
_nodeStore->removeSubtree(std::move(*lastChild));
node->removeLastChild();
}
unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
unique_ref<DataLeafNode> DataTree::addDataLeaf() {
auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get());
if (insertPosOrNull) {
return addDataLeafAt(insertPosOrNull.get());
@ -76,7 +79,7 @@ unique_ptr<DataLeafNode> DataTree::addDataLeaf() {
}
}
unique_ptr<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
unique_ref<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
auto new_leaf = _nodeStore->createNewLeafNode();
auto chain = createChainOfInnerNodes(insertPos->depth()-1, new_leaf.get());
insertPos->addChild(*chain);
@ -84,17 +87,18 @@ unique_ptr<DataLeafNode> DataTree::addDataLeafAt(DataInnerNode *insertPos) {
}
optional_ownership_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, DataNode *child) {
//TODO This function is implemented twice, once with optional_ownership_ptr, once with unique_ptr. Redundancy!
//TODO This function is implemented twice, once with optional_ownership_ptr, once with unique_ref. Redundancy!
optional_ownership_ptr<DataNode> chain = cpputils::WithoutOwnership<DataNode>(child);
for(unsigned int i=0; i<num; ++i) {
auto newnode = _nodeStore->createNewInnerNode(*chain);
chain = cpputils::WithOwnership<DataNode>(std::move(newnode));
//TODO Don't use to_unique_ptr, but make optional_ownership_ptr work with unique_ref
chain = cpputils::WithOwnership<DataNode>(cpputils::to_unique_ptr(std::move(newnode)));
}
return chain;
}
unique_ptr<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ptr<DataNode> child) {
unique_ptr<DataNode> chain = std::move(child);
unique_ref<DataNode> DataTree::createChainOfInnerNodes(unsigned int num, unique_ref<DataNode> child) {
unique_ref<DataNode> chain = std::move(child);
for(unsigned int i=0; i<num; ++i) {
chain = _nodeStore->createNewInnerNode(*chain);
}
@ -111,7 +115,7 @@ DataInnerNode* DataTree::increaseTreeDepth(unsigned int levels) {
return result;
}
unique_ptr<DataLeafNode> DataTree::addDataLeafToFullTree() {
unique_ref<DataLeafNode> DataTree::addDataLeafToFullTree() {
DataInnerNode *rootNode = increaseTreeDepth(1);
auto newLeaf = addDataLeafAt(rootNode);
return newLeaf;
@ -125,7 +129,7 @@ void DataTree::flush() const {
_rootNode->flush();
}
unique_ptr<DataNode> DataTree::releaseRootNode() {
unique_ref<DataNode> DataTree::releaseRootNode() {
return std::move(_rootNode);
}
@ -143,7 +147,8 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const {
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(node);
uint64_t numLeavesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner);
auto lastChild = _nodeStore->load(inner.LastChild()->key());
uint64_t numLeavesInRightChild = _numLeaves(*lastChild);
assert(lastChild != none);
uint64_t numLeavesInRightChild = _numLeaves(**lastChild);
return numLeavesInLeftChildren + numLeavesInRightChild;
}
@ -199,7 +204,7 @@ void DataTree::_traverseLeaves(DataNode *root, uint32_t leafOffset, uint32_t beg
uint32_t leavesPerChild = leavesPerFullChild(*inner);
uint32_t beginChild = beginIndex/leavesPerChild;
uint32_t endChild = utils::ceilDivision(endIndex, leavesPerChild);
vector<unique_ptr<DataNode>> children = getOrCreateChildren(inner, beginChild, endChild);
vector<unique_ref<DataNode>> children = getOrCreateChildren(inner, beginChild, endChild);
for (uint32_t childIndex = beginChild; childIndex < endChild; ++childIndex) {
uint32_t childOffset = childIndex * leavesPerChild;
@ -210,11 +215,13 @@ void DataTree::_traverseLeaves(DataNode *root, uint32_t leafOffset, uint32_t beg
}
}
vector<unique_ptr<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) {
vector<unique_ptr<DataNode>> children;
vector<unique_ref<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) {
vector<unique_ref<DataNode>> children;
children.reserve(end-begin);
for (uint32_t childIndex = begin; childIndex < std::min(node->numChildren(), end); ++childIndex) {
children.emplace_back(_nodeStore->load(node->getChild(childIndex)->key()));
auto child = _nodeStore->load(node->getChild(childIndex)->key());
assert(child != none);
children.emplace_back(std::move(*child));
}
for (uint32_t childIndex = node->numChildren(); childIndex < end; ++childIndex) {
children.emplace_back(addChildTo(node));
@ -223,7 +230,7 @@ vector<unique_ptr<DataNode>> DataTree::getOrCreateChildren(DataInnerNode *node,
return children;
}
unique_ptr<DataNode> DataTree::addChildTo(DataInnerNode *node) {
unique_ref<DataNode> DataTree::addChildTo(DataInnerNode *node) {
auto new_leaf = _nodeStore->createNewLeafNode();
new_leaf->resize(_nodeStore->layout().maxBytesPerLeaf());
auto chain = createChainOfInnerNodes(node->depth()-1, std::move(new_leaf));
@ -253,7 +260,8 @@ uint64_t DataTree::_numStoredBytes(const DataNode &root) const {
const DataInnerNode &inner = dynamic_cast<const DataInnerNode&>(root);
uint64_t numBytesInLeftChildren = (inner.numChildren()-1) * leavesPerFullChild(inner) * _nodeStore->layout().maxBytesPerLeaf();
auto lastChild = _nodeStore->load(inner.LastChild()->key());
uint64_t numBytesInRightChild = _numStoredBytes(*lastChild);
assert(lastChild != none);
uint64_t numBytesInRightChild = _numStoredBytes(**lastChild);
return numBytesInLeftChildren + numBytesInRightChild;
}
@ -288,16 +296,22 @@ optional_ownership_ptr<DataLeafNode> DataTree::LastLeaf(DataNode *root) {
}
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root);
return WithOwnership(LastLeaf(_nodeStore->load(inner->LastChild()->key())));
auto lastChild = _nodeStore->load(inner->LastChild()->key());
assert(lastChild != none);
//TODO Don't use to_unique_ptr but make optional_ownership_ptr work with unique_ref
return WithOwnership(cpputils::to_unique_ptr(LastLeaf(std::move(*lastChild))));
}
unique_ptr<DataLeafNode> DataTree::LastLeaf(unique_ptr<DataNode> root) {
unique_ref<DataLeafNode> DataTree::LastLeaf(unique_ref<DataNode> root) {
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
if (leaf.get() != nullptr) {
return leaf;
if (leaf != none) {
return std::move(*leaf);
}
auto inner = dynamic_pointer_move<DataInnerNode>(root);
return LastLeaf(_nodeStore->load(inner->LastChild()->key()));
assert(inner != none);
auto child = _nodeStore->load((*inner)->LastChild()->key());
assert(child != none);
return LastLeaf(std::move(*child));
}
uint32_t DataTree::maxBytesPerLeaf() const {

View File

@ -23,7 +23,7 @@ namespace datatreestore {
//TODO It is strange that DataLeafNode is still part in the public interface of DataTree. This should be separated somehow.
class DataTree {
public:
DataTree(datanodestore::DataNodeStore *nodeStore, std::unique_ptr<datanodestore::DataNode> rootNode);
DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref<datanodestore::DataNode> rootNode);
virtual ~DataTree();
const blockstore::Key &key() const;
@ -40,18 +40,18 @@ public:
private:
mutable boost::shared_mutex _mutex;
datanodestore::DataNodeStore *_nodeStore;
std::unique_ptr<datanodestore::DataNode> _rootNode;
cpputils::unique_ref<datanodestore::DataNode> _rootNode;
std::unique_ptr<datanodestore::DataLeafNode> addDataLeaf();
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeaf();
void removeLastDataLeaf();
std::unique_ptr<datanodestore::DataNode> releaseRootNode();
cpputils::unique_ref<datanodestore::DataNode> releaseRootNode();
friend class DataTreeStore;
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafAt(datanodestore::DataInnerNode *insertPos);
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeafAt(datanodestore::DataInnerNode *insertPos);
cpputils::optional_ownership_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, datanodestore::DataNode *child);
std::unique_ptr<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, std::unique_ptr<datanodestore::DataNode> child);
std::unique_ptr<datanodestore::DataLeafNode> addDataLeafToFullTree();
cpputils::unique_ref<datanodestore::DataNode> createChainOfInnerNodes(unsigned int num, cpputils::unique_ref<datanodestore::DataNode> child);
cpputils::unique_ref<datanodestore::DataLeafNode> addDataLeafToFullTree();
void deleteLastChildSubtree(datanodestore::DataInnerNode *node);
void ifRootHasOnlyOneChildReplaceRootWithItsChild();
@ -63,10 +63,10 @@ private:
uint64_t _numStoredBytes(const datanodestore::DataNode &root) const;
uint32_t _numLeaves(const datanodestore::DataNode &node) const;
cpputils::optional_ownership_ptr<datanodestore::DataLeafNode> LastLeaf(datanodestore::DataNode *root);
std::unique_ptr<datanodestore::DataLeafNode> LastLeaf(std::unique_ptr<datanodestore::DataNode> root);
cpputils::unique_ref<datanodestore::DataLeafNode> LastLeaf(cpputils::unique_ref<datanodestore::DataNode> root);
datanodestore::DataInnerNode* increaseTreeDepth(unsigned int levels);
std::vector<std::unique_ptr<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
std::unique_ptr<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
std::vector<cpputils::unique_ref<datanodestore::DataNode>> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end);
cpputils::unique_ref<datanodestore::DataNode> addChildTo(datanodestore::DataInnerNode *node);
DISALLOW_COPY_AND_ASSIGN(DataTree);
};

View File

@ -4,7 +4,10 @@
#include "DataTree.h"
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using boost::optional;
using boost::none;
using blobstore::onblocks::datanodestore::DataNodeStore;
using blobstore::onblocks::datanodestore::DataNode;
@ -13,30 +16,29 @@ namespace blobstore {
namespace onblocks {
namespace datatreestore {
DataTreeStore::DataTreeStore(unique_ptr<DataNodeStore> nodeStore)
DataTreeStore::DataTreeStore(unique_ref<DataNodeStore> nodeStore)
: _nodeStore(std::move(nodeStore)) {
}
DataTreeStore::~DataTreeStore() {
}
unique_ptr<DataTree> DataTreeStore::load(const blockstore::Key &key) {
optional<unique_ref<DataTree>> DataTreeStore::load(const blockstore::Key &key) {
auto node = _nodeStore->load(key);
if (node.get() == nullptr) {
return nullptr;
} else {
return make_unique<DataTree>(_nodeStore.get(), std::move(node));
if (node == none) {
return none;
}
return make_unique_ref<DataTree>(_nodeStore.get(), std::move(*node));
}
unique_ptr<DataTree> DataTreeStore::createNewTree() {
unique_ptr<DataNode> newleaf = _nodeStore->createNewLeafNode();
return make_unique<DataTree>(_nodeStore.get(), std::move(newleaf));
unique_ref<DataTree> DataTreeStore::createNewTree() {
auto newleaf = _nodeStore->createNewLeafNode();
return make_unique_ref<DataTree>(_nodeStore.get(), std::move(newleaf));
}
void DataTreeStore::remove(unique_ptr<DataTree> tree) {
void DataTreeStore::remove(unique_ref<DataTree> tree) {
auto root = tree->releaseRootNode();
tree.reset();
to_unique_ptr(std::move(tree)).reset(); // Destruct tree
_nodeStore->removeSubtree(std::move(root));
}

View File

@ -4,7 +4,9 @@
#include <memory>
#include <messmer/cpp-utils/macros.h>
#include <messmer/cpp-utils/pointer/unique_ref.h>
#include <messmer/blockstore/utils/Key.h>
#include <boost/optional.hpp>
namespace blobstore {
namespace onblocks {
@ -16,17 +18,17 @@ class DataTree;
class DataTreeStore {
public:
DataTreeStore(std::unique_ptr<datanodestore::DataNodeStore> nodeStore);
DataTreeStore(cpputils::unique_ref<datanodestore::DataNodeStore> nodeStore);
virtual ~DataTreeStore();
std::unique_ptr<DataTree> load(const blockstore::Key &key);
boost::optional<cpputils::unique_ref<DataTree>> load(const blockstore::Key &key);
std::unique_ptr<DataTree> createNewTree();
cpputils::unique_ref<DataTree> createNewTree();
void remove(std::unique_ptr<DataTree> tree);
void remove(cpputils::unique_ref<DataTree> tree);
private:
std::unique_ptr<datanodestore::DataNodeStore> _nodeStore;
cpputils::unique_ref<datanodestore::DataNodeStore> _nodeStore;
DISALLOW_COPY_AND_ASSIGN(DataTreeStore);
};

View File

@ -6,23 +6,26 @@
#include "../../datanodestore/DataNodeStore.h"
using std::function;
using std::unique_ptr;
using cpputils::optional_ownership_ptr;
using cpputils::dynamic_pointer_move;
using cpputils::unique_ref;
using blobstore::onblocks::datanodestore::DataInnerNode;
using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datanodestore::DataNodeStore;
using blockstore::Key;
using boost::optional;
using boost::none;
namespace blobstore {
namespace onblocks {
namespace datatreestore {
namespace algorithms {
unique_ptr<DataInnerNode> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
optional<unique_ref<DataInnerNode>> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) {
Key key = node.LastChild()->key();
auto lastChild = nodeStore->load(key);
return dynamic_pointer_move<DataInnerNode>(lastChild);
assert(lastChild != none);
return dynamic_pointer_move<DataInnerNode>(*lastChild);
}
//Returns the lowest right border node meeting the condition specified (exclusive the leaf).
@ -31,11 +34,16 @@ optional_ownership_ptr<DataInnerNode> GetLowestInnerRightBorderNodeWithCondition
optional_ownership_ptr<DataInnerNode> currentNode = cpputils::WithoutOwnership(dynamic_cast<DataInnerNode*>(rootNode));
optional_ownership_ptr<DataInnerNode> result = cpputils::null<DataInnerNode>();
for (unsigned int i=0; i < rootNode->depth(); ++i) {
//TODO Don't use to_unique_ptr, but make optional_ownership_ptr work with unique_ref
//TODO This unnecessarily loads the leaf node in the last loop run
auto lastChild = getLastChildAsInnerNode(nodeStore, *currentNode);
if (condition(*currentNode)) {
result = std::move(currentNode);
}
currentNode = std::move(lastChild);
assert(lastChild != none || static_cast<int>(i) == rootNode->depth()-1);
if (lastChild != none) {
currentNode = cpputils::to_unique_ptr(std::move(*lastChild));
}
}
return result;

View File

@ -4,8 +4,9 @@
#include "../datanodestore/DataNodeStore.h"
#include "../datanodestore/DataLeafNode.h"
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using boost::optional;
using blobstore::onblocks::datatreestore::DataTreeStore;
using blockstore::Key;
@ -16,24 +17,24 @@ using datatreestore::DataTreeStore;
using datatreestore::DataTree;
namespace parallelaccessdatatreestore {
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ptr<DataTreeStore> dataTreeStore)
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ref<DataTreeStore> dataTreeStore)
: _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique_ref<ParallelAccessDataTreeStoreAdapter>(_dataTreeStore.get())) {
}
ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() {
}
unique_ptr<DataTreeRef> ParallelAccessDataTreeStore::load(const blockstore::Key &key) {
optional<unique_ref<DataTreeRef>> ParallelAccessDataTreeStore::load(const blockstore::Key &key) {
return _parallelAccessStore.load(key);
}
unique_ptr<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
unique_ref<DataTreeRef> ParallelAccessDataTreeStore::createNewTree() {
auto dataTree = _dataTreeStore->createNewTree();
Key key = dataTree->key();
return _parallelAccessStore.add(key, std::move(dataTree));
}
void ParallelAccessDataTreeStore::remove(unique_ptr<DataTreeRef> tree) {
void ParallelAccessDataTreeStore::remove(unique_ref<DataTreeRef> tree) {
Key key = tree->key();
return _parallelAccessStore.remove(key, std::move(tree));
}

View File

@ -20,17 +20,17 @@ class DataTreeRef;
class ParallelAccessDataTreeStore {
public:
ParallelAccessDataTreeStore(std::unique_ptr<datatreestore::DataTreeStore> dataTreeStore);
ParallelAccessDataTreeStore(cpputils::unique_ref<datatreestore::DataTreeStore> dataTreeStore);
virtual ~ParallelAccessDataTreeStore();
std::unique_ptr<DataTreeRef> load(const blockstore::Key &key);
boost::optional<cpputils::unique_ref<DataTreeRef>> load(const blockstore::Key &key);
std::unique_ptr<DataTreeRef> createNewTree();
cpputils::unique_ref<DataTreeRef> createNewTree();
void remove(std::unique_ptr<DataTreeRef> tree);
void remove(cpputils::unique_ref<DataTreeRef> tree);
private:
std::unique_ptr<datatreestore::DataTreeStore> _dataTreeStore;
cpputils::unique_ref<datatreestore::DataTreeStore> _dataTreeStore;
parallelaccessstore::ParallelAccessStore<datatreestore::DataTree, DataTreeRef, blockstore::Key> _parallelAccessStore;
DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore);

View File

@ -16,11 +16,11 @@ public:
:_baseDataTreeStore(std::move(baseDataTreeStore)) {
}
std::unique_ptr<datatreestore::DataTree> loadFromBaseStore(const blockstore::Key &key) override {
boost::optional<cpputils::unique_ref<datatreestore::DataTree>> loadFromBaseStore(const blockstore::Key &key) override {
return _baseDataTreeStore->load(key);
}
void removeFromBaseStore(std::unique_ptr<datatreestore::DataTree> dataTree) override {
void removeFromBaseStore(cpputils::unique_ref<datatreestore::DataTree> dataTree) override {
return _baseDataTreeStore->remove(std::move(dataTree));
}

View File

@ -22,17 +22,17 @@ using namespace blobstore;
using namespace blobstore::onblocks;
using namespace blobstore::onblocks::datanodestore;
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
class DataInnerNodeTest: public Test {
public:
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
DataInnerNodeTest() :
_blockStore(make_unique<FakeBlockStore>()),
_blockStore(make_unique_ref<FakeBlockStore>()),
blockStore(_blockStore.get()),
nodeStore(make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
nodeStore(make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
leaf(nodeStore->createNewLeafNode()),
node(nodeStore->createNewInnerNode(*leaf)) {
@ -40,26 +40,26 @@ public:
ZEROES.FillWithZeroes();
}
unique_ptr<DataInnerNode> LoadInnerNode(const Key &key) {
auto node = nodeStore->load(key);
return dynamic_pointer_move<DataInnerNode>(node);
unique_ref<DataInnerNode> LoadInnerNode(const Key &key) {
auto node = std::move(nodeStore->load(key).get());
return std::move(dynamic_pointer_move<DataInnerNode>(node).get());
}
Key CreateNewInnerNodeReturnKey(const DataNode &firstChild) {
return nodeStore->createNewInnerNode(firstChild)->key();
}
unique_ptr<DataInnerNode> CreateNewInnerNode() {
unique_ref<DataInnerNode> CreateNewInnerNode() {
auto new_leaf = nodeStore->createNewLeafNode();
return nodeStore->createNewInnerNode(*new_leaf);
}
unique_ptr<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
unique_ref<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild) {
auto key = CreateNewInnerNodeReturnKey(firstChild);
return LoadInnerNode(key);
}
unique_ptr<DataInnerNode> CreateNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
unique_ref<DataInnerNode> CreateNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
auto node = nodeStore->createNewInnerNode(firstChild);
node->addChild(secondChild);
return node;
@ -69,7 +69,7 @@ public:
return CreateNewInnerNode(firstChild, secondChild)->key();
}
unique_ptr<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
unique_ref<DataInnerNode> CreateAndLoadNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) {
auto key = CreateNewInnerNodeReturnKey(firstChild, secondChild);
return LoadInnerNode(key);
}
@ -85,13 +85,13 @@ public:
AddALeafTo(node.get());
AddALeafTo(node.get());
auto child = nodeStore->createNewLeafNode();
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
return converted->key();
}
unique_ptr<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
unique_ref<DataInnerNode> CopyInnerNode(const DataInnerNode &node) {
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
return dynamic_pointer_move<DataInnerNode>(copied);
return std::move(dynamic_pointer_move<DataInnerNode>(copied).get());
}
Key InitializeInnerNodeAddLeafReturnKey() {
@ -100,12 +100,12 @@ public:
return node->key();
}
unique_ptr<BlockStore> _blockStore;
unique_ref<BlockStore> _blockStore;
BlockStore *blockStore;
unique_ptr<DataNodeStore> nodeStore;
unique_ref<DataNodeStore> nodeStore;
Data ZEROES;
unique_ptr<DataLeafNode> leaf;
unique_ptr<DataInnerNode> node;
unique_ref<DataLeafNode> leaf;
unique_ref<DataInnerNode> node;
};
constexpr uint32_t DataInnerNodeTest::BLOCKSIZE_BYTES;
@ -122,7 +122,7 @@ TEST_F(DataInnerNodeTest, CorrectKeyReturnedAfterLoading) {
Key key = block->key();
DataInnerNode::InitializeNewNode(std::move(block), *leaf);
auto loaded = nodeStore->load(key);
auto loaded = std::move(nodeStore->load(key).get());
EXPECT_EQ(key, loaded->key());
}
@ -186,7 +186,7 @@ TEST_F(DataInnerNodeTest, BuildingAThreeLevelTreeAndReload) {
TEST_F(DataInnerNodeTest, ConvertToInternalNode) {
auto child = nodeStore->createNewLeafNode();
Key node_key = node->key();
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(node), *child);
EXPECT_EQ(1u, converted->numChildren());
EXPECT_EQ(child->key(), converted->getChild(0)->key());

View File

@ -14,8 +14,8 @@ using ::testing::Test;
using ::testing::WithParamInterface;
using ::testing::Values;
using ::testing::Combine;
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using std::string;
using cpputils::DataFixture;
@ -40,9 +40,9 @@ public:
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
DataLeafNodeTest():
_blockStore(make_unique<FakeBlockStore>()),
_blockStore(make_unique_ref<FakeBlockStore>()),
blockStore(_blockStore.get()),
nodeStore(make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
nodeStore(make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES)),
ZEROES(nodeStore->layout().maxBytesPerLeaf()),
randomData(nodeStore->layout().maxBytesPerLeaf()),
leaf(nodeStore->createNewLeafNode()) {
@ -76,9 +76,9 @@ public:
leaf_to_fill->write(randomData.data(), 0, randomData.size());
}
unique_ptr<DataLeafNode> LoadLeafNode(const Key &key) {
auto leaf = nodeStore->load(key);
return dynamic_pointer_move<DataLeafNode>(leaf);
unique_ref<DataLeafNode> LoadLeafNode(const Key &key) {
auto leaf = std::move(nodeStore->load(key).get());
return std::move(dynamic_pointer_move<DataLeafNode>(leaf).get());
}
void ResizeLeaf(const Key &key, size_t size) {
@ -91,13 +91,13 @@ public:
auto leaf = nodeStore->createNewLeafNode();
FillLeafBlockWithData(leaf.get());
auto child = nodeStore->createNewLeafNode();
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
return converted->key();
}
unique_ptr<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
unique_ref<DataLeafNode> CopyLeafNode(const DataLeafNode &node) {
auto copied = nodeStore->createNewNodeAsCopyFrom(node);
return dynamic_pointer_move<DataLeafNode>(copied);
return std::move(dynamic_pointer_move<DataLeafNode>(copied).get());
}
Key InitializeLeafGrowAndReturnKey() {
@ -106,12 +106,12 @@ public:
return leaf->key();
}
unique_ptr<BlockStore> _blockStore;
unique_ref<BlockStore> _blockStore;
BlockStore *blockStore;
unique_ptr<DataNodeStore> nodeStore;
unique_ref<DataNodeStore> nodeStore;
Data ZEROES;
Data randomData;
unique_ptr<DataLeafNode> leaf;
unique_ref<DataLeafNode> leaf;
};
constexpr uint32_t DataLeafNodeTest::BLOCKSIZE_BYTES;
@ -129,7 +129,7 @@ TEST_F(DataLeafNodeTest, CorrectKeyReturnedAfterLoading) {
Key key = block->key();
DataLeafNode::InitializeNewNode(std::move(block));
auto loaded = nodeStore->load(key);
auto loaded = std::move(nodeStore->load(key).get());
EXPECT_EQ(key, loaded->key());
}
@ -231,7 +231,7 @@ TEST_F(DataLeafNodeTest, ShrinkingDoesntDestroyValidDataRegion) {
TEST_F(DataLeafNodeTest, ConvertToInternalNode) {
auto child = nodeStore->createNewLeafNode();
Key leaf_key = leaf->key();
unique_ptr<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
unique_ref<DataInnerNode> converted = DataNode::convertToNewInnerNode(std::move(leaf), *child);
EXPECT_EQ(1u, converted->numChildren());
EXPECT_EQ(child->key(), converted->getChild(0)->key());

View File

@ -7,11 +7,13 @@
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
#include "messmer/blockstore/implementations/testfake/FakeBlock.h"
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
using ::testing::Test;
using std::unique_ptr;
using std::make_unique;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using std::string;
using boost::none;
using blockstore::BlockStore;
using blockstore::testfake::FakeBlockStore;
@ -25,9 +27,9 @@ class DataNodeStoreTest: public Test {
public:
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
unique_ptr<BlockStore> _blockStore = make_unique<FakeBlockStore>();
unique_ref<BlockStore> _blockStore = make_unique_ref<FakeBlockStore>();
BlockStore *blockStore = _blockStore.get();
unique_ptr<DataNodeStore> nodeStore = make_unique<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES);
unique_ref<DataNodeStore> nodeStore = make_unique_ref<DataNodeStore>(std::move(_blockStore), BLOCKSIZE_BYTES);
};
constexpr uint32_t DataNodeStoreTest::BLOCKSIZE_BYTES;
@ -49,7 +51,7 @@ TEST_F(DataNodeStoreTest, CreateInnerNodeCreatesInnerNode) {
TEST_F(DataNodeStoreTest, LeafNodeIsRecognizedAfterStoreAndLoad) {
Key key = nodeStore->createNewLeafNode()->key();
auto loaded_node = nodeStore->load(key);
auto loaded_node = std::move(nodeStore->load(key).get());
EXPECT_IS_PTR_TYPE(DataLeafNode, loaded_node.get());
}
@ -58,7 +60,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth1IsRecognizedAfterStoreAndLoad) {
auto leaf = nodeStore->createNewLeafNode();
Key key = nodeStore->createNewInnerNode(*leaf)->key();
auto loaded_node = nodeStore->load(key);
auto loaded_node = std::move(nodeStore->load(key).get());
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
}
@ -68,7 +70,7 @@ TEST_F(DataNodeStoreTest, InnerNodeWithDepth2IsRecognizedAfterStoreAndLoad) {
auto inner = nodeStore->createNewInnerNode(*leaf);
Key key = nodeStore->createNewInnerNode(*inner)->key();
auto loaded_node = nodeStore->load(key);
auto loaded_node = std::move(nodeStore->load(key).get());
EXPECT_IS_PTR_TYPE(DataInnerNode, loaded_node.get());
}
@ -101,9 +103,9 @@ TEST_F(DataNodeStoreTest, CreatedLeafNodeIsInitialized) {
TEST_F(DataNodeStoreTest, NodeIsNotLoadableAfterDeleting) {
auto nodekey = nodeStore->createNewLeafNode()->key();
auto node = nodeStore->load(nodekey);
EXPECT_NE(nullptr, node.get());
nodeStore->remove(std::move(node));
EXPECT_EQ(nullptr, nodeStore->load(nodekey).get());
EXPECT_NE(none, node);
nodeStore->remove(std::move(*node));
EXPECT_EQ(none, nodeStore->load(nodekey));
}
TEST_F(DataNodeStoreTest, NumNodesIsCorrectOnEmptyNodestore) {

View File

@ -9,14 +9,14 @@
using ::testing::Test;
using ::testing::WithParamInterface;
using ::testing::Values;
using std::unique_ptr;
using std::make_unique;
using std::string;
using blockstore::BlockStore;
using blockstore::testfake::FakeBlockStore;
using cpputils::Data;
using cpputils::DataFixture;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using namespace blobstore;
using namespace blobstore::onblocks;
using namespace blobstore::onblocks::datanodestore;
@ -26,7 +26,7 @@ public:
static constexpr uint32_t BLOCKSIZE_BYTES = 1024;
static constexpr uint32_t DATASIZE_BYTES = DataNodeLayout(DataNodeViewTest::BLOCKSIZE_BYTES).datasizeBytes();
unique_ptr<BlockStore> blockStore = make_unique<FakeBlockStore>();
unique_ref<BlockStore> blockStore = make_unique_ref<FakeBlockStore>();
};
class DataNodeViewDepthTest: public DataNodeViewTest, public WithParamInterface<uint8_t> {

View File

@ -3,11 +3,12 @@
#include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h"
#include "../../../../implementations/onblocks/datatreestore/DataTreeStore.h"
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
using blockstore::testfake::FakeBlockStore;
using blockstore::Key;
using blobstore::onblocks::datanodestore::DataNodeStore;
using std::make_unique;
using boost::none;
using namespace blobstore::onblocks::datatreestore;
@ -16,14 +17,14 @@ class DataTreeStoreTest: public DataTreeTest {
TEST_F(DataTreeStoreTest, CorrectKeyReturned) {
Key key = treeStore.createNewTree()->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(key, tree->key());
}
TEST_F(DataTreeStoreTest, CreatedTreeIsLoadable) {
auto key = treeStore.createNewTree()->key();
auto loaded = treeStore.load(key);
EXPECT_NE(nullptr, loaded.get());
EXPECT_NE(none, loaded);
}
TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
@ -35,19 +36,19 @@ TEST_F(DataTreeStoreTest, NewTreeIsLeafOnly) {
TEST_F(DataTreeStoreTest, TreeIsNotLoadableAfterRemove) {
Key key = treeStore.createNewTree()->key();
auto tree = treeStore.load(key);
EXPECT_NE(nullptr, tree.get());
treeStore.remove(std::move(tree));
EXPECT_EQ(nullptr, treeStore.load(key).get());
EXPECT_NE(none, tree);
treeStore.remove(std::move(*tree));
EXPECT_EQ(none, treeStore.load(key));
}
TEST_F(DataTreeStoreTest, RemovingTreeRemovesAllNodesOfTheTree) {
auto key = CreateThreeLevelMinData()->key();
auto tree1 = treeStore.load(key);
auto tree1 = std::move(treeStore.load(key).get());
auto tree2_key = treeStore.createNewTree()->key();
treeStore.remove(std::move(tree1));
//Check that the only remaining node is tree2
EXPECT_EQ(1, nodeStore->numNodes());
EXPECT_NE(nullptr, treeStore.load(tree2_key).get());
EXPECT_NE(none, treeStore.load(tree2_key));
}

View File

@ -12,8 +12,6 @@ using blobstore::onblocks::datanodestore::DataNodeLayout;
using blobstore::onblocks::datatreestore::DataTree;
using blockstore::Key;
using std::unique_ptr;
class DataTreeTest_NumStoredBytes: public DataTreeTest {
public:
};
@ -30,48 +28,48 @@ INSTANTIATE_TEST_CASE_P(FullLastLeaf, DataTreeTest_NumStoredBytes_P, Values(Data
TEST_P(DataTreeTest_NumStoredBytes_P, SingleLeaf) {
Key key = CreateLeafWithSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, TwoLeafTree) {
Key key = CreateTwoLeafWithSecondLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, FullTwolevelTree) {
Key key = CreateFullTwoLevelWithLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithOneChild) {
Key key = CreateThreeLevelWithOneChildAndLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithTwoChildren) {
Key key = CreateThreeLevelWithTwoChildrenAndLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, ThreeLevelTreeWithThreeChildren) {
Key key = CreateThreeLevelWithThreeChildrenAndLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(2*nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode() + nodeStore->layout().maxBytesPerLeaf() + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, FullThreeLevelTree) {
Key key = CreateFullThreeLevelWithLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + nodeStore->layout().maxBytesPerLeaf()*(nodeStore->layout().maxChildrenPerInnerNode()-1) + GetParam(), tree->numStoredBytes());
}
TEST_P(DataTreeTest_NumStoredBytes_P, FourLevelMinDataTree) {
Key key = CreateFourLevelMinDataWithLastLeafSize(GetParam())->key();
auto tree = treeStore.load(key);
auto tree = std::move(treeStore.load(key).get());
EXPECT_EQ(nodeStore->layout().maxBytesPerLeaf()*nodeStore->layout().maxChildrenPerInnerNode()*nodeStore->layout().maxChildrenPerInnerNode() + GetParam(), tree->numStoredBytes());
}

View File

@ -22,49 +22,50 @@ using blobstore::onblocks::datatreestore::DataTree;
using blobstore::onblocks::utils::ceilDivision;
using blockstore::Key;
using cpputils::Data;
using boost::none;
using std::unique_ptr;
using cpputils::unique_ref;
class DataTreeTest_ResizeByTraversing: public DataTreeTest {
public:
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
unique_ptr<DataTree> CreateTree(unique_ptr<DataNode> root) {
unique_ref<DataTree> CreateTree(unique_ref<DataNode> root) {
Key key = root->key();
root.reset();
return treeStore.load(key);
cpputils::to_unique_ptr(std::move(root)).reset(); //Destruct
return std::move(treeStore.load(key).get());
}
unique_ptr<DataTree> CreateLeafTreeWithSize(uint32_t size) {
unique_ref<DataTree> CreateLeafTreeWithSize(uint32_t size) {
return CreateTree(CreateLeafWithSize(size));
}
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
}
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
}
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
}
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
}
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
}
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
}
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
auto root = nodeStore->load(key);
auto root = std::move(nodeStore->load(key).get());
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
if (inner != nullptr) {
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
@ -75,7 +76,7 @@ public:
}
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
auto root = nodeStore->load(key);
auto root = std::move(nodeStore->load(key).get());
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
if (inner != nullptr) {
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
@ -89,7 +90,7 @@ public:
};
constexpr DataNodeLayout DataTreeTest_ResizeByTraversing::LAYOUT;
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ptr<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> {
class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> {
public:
DataTreeTest_ResizeByTraversing_P()
: oldLastLeafSize(get<1>(GetParam())),
@ -103,7 +104,7 @@ public:
void GrowTree(const Key &key, uint32_t numLeavesToAdd) {
auto tree = treeStore.load(key);
GrowTree(tree.get(), numLeavesToAdd);
GrowTree(tree.get().get(), numLeavesToAdd);
}
void GrowTree(DataTree *tree, uint32_t numLeavesToAdd) {
@ -114,18 +115,18 @@ public:
tree->flush();
}
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
auto root = nodeStore->load(key);
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
auto root = std::move(nodeStore->load(key).get());
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
if (leaf.get() != nullptr) {
return leaf;
if (leaf != none) {
return std::move(*leaf);
}
auto inner = dynamic_pointer_move<DataInnerNode>(root);
auto inner = std::move(dynamic_pointer_move<DataInnerNode>(root).get());
return LastLeaf(inner->LastChild()->key());
}
uint32_t oldLastLeafSize;
unique_ptr<DataTree> tree;
unique_ref<DataTree> tree;
uint32_t numberOfLeavesToAdd;
uint32_t newNumberOfLeaves;
Data ZEROES;
@ -133,7 +134,7 @@ public:
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeByTraversing_P, DataTreeTest_ResizeByTraversing_P,
Combine(
//Tree we're starting with
Values<function<unique_ptr<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>>(
Values<function<unique_ref<DataTree>(DataTreeTest_ResizeByTraversing*, uint32_t)>>(
mem_fn(&DataTreeTest_ResizeByTraversing::CreateLeafTreeWithSize),
mem_fn(&DataTreeTest_ResizeByTraversing::CreateTwoLeafTreeWithSecondLeafSize),
mem_fn(&DataTreeTest_ResizeByTraversing::CreateFullTwoLevelTreeWithLastLeafSize),
@ -191,10 +192,10 @@ TEST_P(DataTreeTest_ResizeByTraversing_P, DataStaysIntact) {
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
Key key = tree->key();
tree.reset();
data.FillInto(nodeStore->load(key).get());
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
data.FillInto(nodeStore->load(key).get().get());
GrowTree(key, newNumberOfLeaves);
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), oldNumberOfLeaves, oldLastLeafSize);
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
}

View File

@ -22,49 +22,50 @@ using blobstore::onblocks::datatreestore::DataTree;
using blobstore::onblocks::utils::ceilDivision;
using blockstore::Key;
using cpputils::Data;
using boost::none;
using std::unique_ptr;
using cpputils::unique_ref;
class DataTreeTest_ResizeNumBytes: public DataTreeTest {
public:
static constexpr DataNodeLayout LAYOUT = DataNodeLayout(BLOCKSIZE_BYTES);
unique_ptr<DataTree> CreateTree(unique_ptr<DataNode> root) {
unique_ref<DataTree> CreateTree(unique_ref<DataNode> root) {
Key key = root->key();
root.reset();
return treeStore.load(key);
cpputils::to_unique_ptr(std::move(root)).reset(); // Destruct
return std::move(treeStore.load(key).get());
}
unique_ptr<DataTree> CreateLeafTreeWithSize(uint32_t size) {
unique_ref<DataTree> CreateLeafTreeWithSize(uint32_t size) {
return CreateTree(CreateLeafWithSize(size));
}
unique_ptr<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
unique_ref<DataTree> CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) {
return CreateTree(CreateTwoLeafWithSecondLeafSize(size));
}
unique_ptr<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFullTwoLevelWithLastLeafSize(size));
}
unique_ptr<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) {
return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size));
}
unique_ptr<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) {
return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size));
}
unique_ptr<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFullThreeLevelWithLastLeafSize(size));
}
unique_ptr<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
unique_ref<DataTree> CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) {
return CreateTree(CreateFourLevelMinDataWithLastLeafSize(size));
}
void EXPECT_IS_LEFTMAXDATA_TREE(const Key &key) {
auto root = nodeStore->load(key);
auto root = std::move(nodeStore->load(key).get());
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
if (inner != nullptr) {
for (uint32_t i = 0; i < inner->numChildren()-1; ++i) {
@ -75,7 +76,7 @@ public:
}
void EXPECT_IS_MAXDATA_TREE(const Key &key) {
auto root = nodeStore->load(key);
auto root = std::move(nodeStore->load(key).get());
DataInnerNode *inner = dynamic_cast<DataInnerNode*>(root.get());
if (inner != nullptr) {
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
@ -89,7 +90,7 @@ public:
};
constexpr DataNodeLayout DataTreeTest_ResizeNumBytes::LAYOUT;
class DataTreeTest_ResizeNumBytes_P: public DataTreeTest_ResizeNumBytes, public WithParamInterface<tuple<function<unique_ptr<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>, uint32_t, uint32_t, uint32_t>> {
class DataTreeTest_ResizeNumBytes_P: public DataTreeTest_ResizeNumBytes, public WithParamInterface<tuple<function<unique_ref<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>, uint32_t, uint32_t, uint32_t>> {
public:
DataTreeTest_ResizeNumBytes_P()
: oldLastLeafSize(get<1>(GetParam())),
@ -103,21 +104,21 @@ public:
}
void ResizeTree(const Key &key, uint64_t size) {
treeStore.load(key)->resizeNumBytes(size);
treeStore.load(key).get()->resizeNumBytes(size);
}
unique_ptr<DataLeafNode> LastLeaf(const Key &key) {
auto root = nodeStore->load(key);
unique_ref<DataLeafNode> LastLeaf(const Key &key) {
auto root = std::move(nodeStore->load(key).get());
auto leaf = dynamic_pointer_move<DataLeafNode>(root);
if (leaf.get() != nullptr) {
return leaf;
if (leaf != none) {
return std::move(*leaf);
}
auto inner = dynamic_pointer_move<DataInnerNode>(root);
auto inner = std::move(dynamic_pointer_move<DataInnerNode>(root).get());
return LastLeaf(inner->LastChild()->key());
}
uint32_t oldLastLeafSize;
unique_ptr<DataTree> tree;
unique_ref<DataTree> tree;
uint32_t newNumberOfLeaves;
uint32_t newLastLeafSize;
uint64_t newSize;
@ -126,7 +127,7 @@ public:
INSTANTIATE_TEST_CASE_P(DataTreeTest_ResizeNumBytes_P, DataTreeTest_ResizeNumBytes_P,
Combine(
//Tree we're starting with
Values<function<unique_ptr<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>>(
Values<function<unique_ref<DataTree>(DataTreeTest_ResizeNumBytes*, uint32_t)>>(
mem_fn(&DataTreeTest_ResizeNumBytes::CreateLeafTreeWithSize),
mem_fn(&DataTreeTest_ResizeNumBytes::CreateTwoLeafTreeWithSecondLeafSize),
mem_fn(&DataTreeTest_ResizeNumBytes::CreateFullTwoLevelTreeWithLastLeafSize),
@ -193,15 +194,15 @@ TEST_P(DataTreeTest_ResizeNumBytes_P, DataStaysIntact) {
uint32_t oldNumberOfLeaves = std::max(1u, ceilDivision(tree->numStoredBytes(), nodeStore->layout().maxBytesPerLeaf()));
TwoLevelDataFixture data(nodeStore, TwoLevelDataFixture::SizePolicy::Unchanged);
Key key = tree->key();
tree.reset();
data.FillInto(nodeStore->load(key).get());
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
data.FillInto(nodeStore->load(key).get().get());
ResizeTree(key, newSize);
if (oldNumberOfLeaves < newNumberOfLeaves || (oldNumberOfLeaves == newNumberOfLeaves && oldLastLeafSize < newLastLeafSize)) {
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), oldNumberOfLeaves, oldLastLeafSize);
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), oldNumberOfLeaves, oldLastLeafSize);
} else {
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get(), newNumberOfLeaves, newLastLeafSize);
data.EXPECT_DATA_CORRECT(nodeStore->load(key).get().get(), newNumberOfLeaves, newLastLeafSize);
}
}
@ -211,7 +212,7 @@ TEST_F(DataTreeTest_ResizeNumBytes, ResizeToZero_NumBytesIsCorrect) {
auto tree = CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(10u);
tree->resizeNumBytes(0);
Key key = tree->key();
tree.reset();
cpputils::to_unique_ptr(std::move(tree)).reset(); // Call destructor
auto leaf = LoadLeafNode(key);
EXPECT_EQ(0u, leaf->numBytes());
}

View File

@ -9,7 +9,7 @@ using blobstore::onblocks::datanodestore::DataNode;
using blobstore::onblocks::datatreestore::DataTree;
using blockstore::Key;
using std::unique_ptr;
using cpputils::unique_ref;
class TraversorMock {
public:
@ -22,7 +22,7 @@ MATCHER_P(KeyEq, expected, "node key equals") {
class DataTreeTest_TraverseLeaves: public DataTreeTest {
public:
unique_ptr<DataInnerNode> CreateThreeLevel() {
unique_ref<DataInnerNode> CreateThreeLevel() {
return CreateInner({
CreateFullTwoLevel(),
CreateFullTwoLevel(),
@ -32,7 +32,7 @@ public:
CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})});
}
unique_ptr<DataInnerNode> CreateFourLevel() {
unique_ref<DataInnerNode> CreateFourLevel() {
return CreateInner({
CreateFullThreeLevel(),
CreateFullThreeLevel(),
@ -56,7 +56,7 @@ public:
void TraverseLeaves(DataNode *root, uint32_t beginIndex, uint32_t endIndex) {
root->flush();
auto tree = treeStore.load(root->key());
auto tree = std::move(treeStore.load(root->key()).get());
tree->traverseLeaves(beginIndex, endIndex, [this] (DataLeafNode *leaf, uint32_t nodeIndex) {
traversor.called(leaf, nodeIndex);
});

View File

@ -8,8 +8,6 @@
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
using ::testing::Test;
using std::unique_ptr;
using std::make_unique;
using std::pair;
using std::make_pair;
@ -28,7 +26,7 @@ public:
};
void check(const TestData &testData) {
auto root = nodeStore->load(testData.rootNode);
auto root = std::move(nodeStore->load(testData.rootNode).get());
auto result = GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(nodeStore, root.get());
EXPECT_EQ(testData.expectedResult, result->key());
}

View File

@ -8,8 +8,6 @@
#include "../../../../../implementations/onblocks/datatreestore/impl/algorithms.h"
using ::testing::Test;
using std::unique_ptr;
using std::make_unique;
using std::pair;
using std::make_pair;
@ -28,7 +26,7 @@ public:
};
void check(const TestData &testData) {
auto root = nodeStore->load(testData.rootNode);
auto root = std::move(nodeStore->load(testData.rootNode).get());
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, root.get());
EXPECT_EQ(testData.expectedResult, result->key());
}
@ -80,19 +78,19 @@ public:
};
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, Leaf) {
auto leaf = nodeStore->load(CreateLeafOnlyTree());
auto leaf = std::move(nodeStore->load(CreateLeafOnlyTree()).get());
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, leaf.get());
EXPECT_EQ(nullptr, result.get());
}
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, TwoRightBorderNodes) {
auto node = nodeStore->load(CreateTwoRightBorderNodes());
auto node = std::move(nodeStore->load(CreateTwoRightBorderNodes()).get());
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
EXPECT_EQ(nullptr, result.get());
}
TEST_F(GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest, ThreeRightBorderNodes) {
auto node = nodeStore->load(CreateThreeRightBorderNodes());
auto node = std::move(nodeStore->load(CreateThreeRightBorderNodes()).get());
auto result = GetLowestRightBorderNodeWithMoreThanOneChildOrNull(nodeStore, node.get());
EXPECT_EQ(nullptr, result.get());
}

View File

@ -2,6 +2,7 @@
#include "messmer/blockstore/implementations/testfake/FakeBlockStore.h"
#include <messmer/cpp-utils/pointer/cast.h>
#include <messmer/cpp-utils/pointer/unique_ref_boost_optional_gtest_workaround.h>
using blobstore::onblocks::datanodestore::DataNodeStore;
using blobstore::onblocks::datanodestore::DataNode;
@ -10,35 +11,36 @@ using blobstore::onblocks::datanodestore::DataLeafNode;
using blobstore::onblocks::datatreestore::DataTree;
using blockstore::testfake::FakeBlockStore;
using blockstore::Key;
using std::make_unique;
using std::unique_ptr;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using std::initializer_list;
using std::vector;
using boost::none;
using cpputils::dynamic_pointer_move;
constexpr uint32_t DataTreeTest::BLOCKSIZE_BYTES;
DataTreeTest::DataTreeTest()
:_nodeStore(make_unique<DataNodeStore>(make_unique<FakeBlockStore>(), BLOCKSIZE_BYTES)),
:_nodeStore(make_unique_ref<DataNodeStore>(make_unique_ref<FakeBlockStore>(), BLOCKSIZE_BYTES)),
nodeStore(_nodeStore.get()),
treeStore(std::move(_nodeStore)) {
}
unique_ptr<DataLeafNode> DataTreeTest::CreateLeaf() {
unique_ref<DataLeafNode> DataTreeTest::CreateLeaf() {
return nodeStore->createNewLeafNode();
}
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(initializer_list<unique_ptr<DataNode>> children) {
unique_ref<DataInnerNode> DataTreeTest::CreateInner(initializer_list<unique_ref<DataNode>> children) {
vector<const DataNode*> childrenVector(children.size());
std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ptr<DataNode> &ptr) {return ptr.get();});
std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ref<DataNode> &ptr) {return ptr.get();});
return CreateInner(childrenVector);
}
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(initializer_list<const DataNode*> children) {
unique_ref<DataInnerNode> DataTreeTest::CreateInner(initializer_list<const DataNode*> children) {
return CreateInner(vector<const DataNode*>(children));
}
unique_ptr<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
unique_ref<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> children) {
assert(children.size() >= 1);
auto node = nodeStore->createNewInnerNode(**children.begin());
for(auto child = children.begin()+1; child != children.end(); ++child) {
@ -47,9 +49,9 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateInner(vector<const DataNode*> chil
return node;
}
unique_ptr<DataTree> DataTreeTest::CreateLeafOnlyTree() {
unique_ref<DataTree> DataTreeTest::CreateLeafOnlyTree() {
auto key = CreateLeaf()->key();
return treeStore.load(key);
return std::move(treeStore.load(key).get());
}
void DataTreeTest::FillNode(DataInnerNode *node) {
@ -64,69 +66,69 @@ void DataTreeTest::FillNodeTwoLevel(DataInnerNode *node) {
}
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevel() {
unique_ref<DataInnerNode> DataTreeTest::CreateFullTwoLevel() {
auto root = CreateInner({CreateLeaf().get()});
FillNode(root.get());
return root;
}
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelMinData() {
return CreateInner({
CreateFullTwoLevel(),
CreateInner({CreateLeaf()})
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinData() {
return CreateInner({
CreateFullThreeLevel(),
CreateInner({CreateInner({CreateLeaf()})})
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
unique_ref<DataInnerNode> DataTreeTest::CreateFullThreeLevel() {
auto root = CreateInner({CreateFullTwoLevel().get()});
FillNodeTwoLevel(root.get());
return root;
}
unique_ptr<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
auto node = nodeStore->load(key);
unique_ref<DataInnerNode> DataTreeTest::LoadInnerNode(const Key &key) {
auto node = std::move(nodeStore->load(key).get());
auto casted = dynamic_pointer_move<DataInnerNode>(node);
EXPECT_NE(nullptr, casted.get()) << "Is not an inner node";
return casted;
EXPECT_NE(none, casted) << "Is not an inner node";
return std::move(*casted);
}
unique_ptr<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
auto node = nodeStore->load(key);
unique_ref<DataLeafNode> DataTreeTest::LoadLeafNode(const Key &key) {
auto node = std::move(nodeStore->load(key).get());
auto casted = dynamic_pointer_move<DataLeafNode>(node);
EXPECT_NE(nullptr, casted.get()) << "Is not a leaf node";
return casted;
EXPECT_NE(none, casted) << "Is not a leaf node";
return std::move(*casted);
}
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeaf() {
return CreateInner({CreateLeaf().get(), CreateLeaf().get()});
}
unique_ptr<DataTree> DataTreeTest::CreateTwoLeafTree() {
unique_ref<DataTree> DataTreeTest::CreateTwoLeafTree() {
auto key = CreateTwoLeaf()->key();
return treeStore.load(key);
return std::move(treeStore.load(key).get());
}
unique_ptr<DataLeafNode> DataTreeTest::CreateLeafWithSize(uint32_t size) {
unique_ref<DataLeafNode> DataTreeTest::CreateLeafWithSize(uint32_t size) {
auto leaf = CreateLeaf();
leaf->resize(size);
return leaf;
}
unique_ptr<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) {
return CreateInner({
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
CreateLeafWithSize(size)
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) {
auto root = CreateFullTwoLevel();
for (uint32_t i = 0; i < root->numChildren()-1; ++i) {
LoadLeafNode(root->getChild(i)->key())->resize(nodeStore->layout().maxBytesPerLeaf());
@ -135,7 +137,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint3
return root;
}
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) {
return CreateInner({
CreateInner({
CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()),
@ -144,7 +146,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafS
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) {
return CreateInner({
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
CreateInner({
@ -154,7 +156,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLe
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) {
return CreateInner({
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
@ -165,7 +167,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateThreeLevelWithThreeChildrenAndLast
});
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uint32_t size) {
auto root = CreateFullThreeLevel();
for (uint32_t i = 0; i < root->numChildren(); ++i) {
auto node = LoadInnerNode(root->getChild(i)->key());
@ -177,7 +179,7 @@ unique_ptr<DataInnerNode> DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uin
return root;
}
unique_ptr<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
unique_ref<DataInnerNode> DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) {
return CreateInner({
CreateFullThreeLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()),
CreateInner({CreateInner({CreateLeafWithSize(size)})})

View File

@ -16,35 +16,35 @@ public:
static constexpr uint32_t BLOCKSIZE_BYTES = 256;
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeaf();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::vector<const blobstore::onblocks::datanodestore::DataNode *> children);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<const blobstore::onblocks::datanodestore::DataNode *> children);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<std::unique_ptr<blobstore::onblocks::datanodestore::DataNode>> children);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeaf();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::vector<const blobstore::onblocks::datanodestore::DataNode *> children);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<const blobstore::onblocks::datanodestore::DataNode *> children);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateInner(std::initializer_list<cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNode>> children);
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
std::unique_ptr<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateLeafOnlyTree();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeaf();
cpputils::unique_ref<blobstore::onblocks::datatreestore::DataTree> CreateTwoLeafTree();
void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node);
void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevel();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevel();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelMinData();
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinData();
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> LoadInnerNode(const blockstore::Key &key);
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> LoadLeafNode(const blockstore::Key &key);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> LoadInnerNode(const blockstore::Key &key);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> LoadLeafNode(const blockstore::Key &key);
std::unique_ptr<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeafWithSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinDataWithLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataLeafNode> CreateLeafWithSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateTwoLeafWithSecondLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullTwoLevelWithLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFullThreeLevelWithLastLeafSize(uint32_t size);
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataInnerNode> CreateFourLevelMinDataWithLastLeafSize(uint32_t size);
std::unique_ptr<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
cpputils::unique_ref<blobstore::onblocks::datanodestore::DataNodeStore> _nodeStore;
blobstore::onblocks::datanodestore::DataNodeStore *nodeStore;
blobstore::onblocks::datatreestore::DataTreeStore treeStore;

View File

@ -50,7 +50,7 @@ private:
auto inner = dynamic_cast<blobstore::onblocks::datanodestore::DataInnerNode*>(node);
int leafIndex = firstLeafIndex;
for (uint32_t i = 0; i < inner->numChildren(); ++i) {
auto child = _dataNodeStore->load(inner->getChild(i)->key());
auto child = std::move(_dataNodeStore->load(inner->getChild(i)->key()).get());
leafIndex = ForEachLeaf(child.get(), leafIndex, endLeafIndex, action);
}
return leafIndex;

View File

@ -3,14 +3,12 @@
#include <messmer/blockstore/implementations/testfake/FakeBlockStore.h>
#include "../../../../implementations/onblocks/BlobStoreOnBlocks.h"
using std::make_unique;
using std::unique_ptr;
using blobstore::onblocks::BlobStoreOnBlocks;
using blockstore::testfake::FakeBlockStore;
using cpputils::make_unique_ref;
constexpr uint32_t BlobStoreTest::BLOCKSIZE_BYTES;
BlobStoreTest::BlobStoreTest()
: blobStore(make_unique<BlobStoreOnBlocks>(make_unique<FakeBlockStore>(), BLOCKSIZE_BYTES)) {
: blobStore(make_unique_ref<BlobStoreOnBlocks>(make_unique_ref<FakeBlockStore>(), BLOCKSIZE_BYTES)) {
}

View File

@ -8,7 +8,7 @@ public:
static constexpr uint32_t BLOCKSIZE_BYTES = 4096;
std::unique_ptr<blobstore::BlobStore> blobStore;
cpputils::unique_ref<blobstore::BlobStore> blobStore;
cpputils::unique_ref<blobstore::Blob> loadBlob(const blockstore::Key &key) {
auto loaded = blobStore->load(key);