From 3d1341114b89160980b07eed76c3008f809134f9 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 26 Jun 2015 15:59:18 +0200 Subject: [PATCH] Use unique_ref instead of unique_ptr --- implementations/onblocks/BlobOnBlocks.cpp | 6 +- implementations/onblocks/BlobOnBlocks.h | 6 +- .../onblocks/BlobStoreOnBlocks.cpp | 11 ++- implementations/onblocks/BlobStoreOnBlocks.h | 4 +- .../onblocks/datanodestore/DataInnerNode.cpp | 7 +- .../onblocks/datanodestore/DataInnerNode.h | 2 +- .../onblocks/datanodestore/DataLeafNode.cpp | 7 +- .../onblocks/datanodestore/DataLeafNode.h | 2 +- .../onblocks/datanodestore/DataNode.cpp | 5 +- .../onblocks/datanodestore/DataNode.h | 2 +- .../onblocks/datanodestore/DataNodeStore.cpp | 40 ++++++----- .../onblocks/datanodestore/DataNodeStore.h | 20 +++--- .../onblocks/datatreestore/DataTree.cpp | 64 ++++++++++------- .../onblocks/datatreestore/DataTree.h | 20 +++--- .../onblocks/datatreestore/DataTreeStore.cpp | 26 +++---- .../onblocks/datatreestore/DataTreeStore.h | 12 ++-- .../datatreestore/impl/algorithms.cpp | 16 +++-- .../ParallelAccessDataTreeStore.cpp | 15 ++-- .../ParallelAccessDataTreeStore.h | 10 +-- .../ParallelAccessDataTreeStoreAdapter.h | 4 +- .../datanodestore/DataInnerNodeTest.cpp | 40 +++++------ .../datanodestore/DataLeafNodeTest.cpp | 30 ++++---- .../datanodestore/DataNodeStoreTest.cpp | 22 +++--- .../datanodestore/DataNodeViewTest.cpp | 6 +- .../datatreestore/DataTreeStoreTest.cpp | 17 ++--- .../DataTreeTest_NumStoredBytes.cpp | 18 +++-- .../DataTreeTest_ResizeByTraversing.cpp | 51 +++++++------- .../DataTreeTest_ResizeNumBytes.cpp | 55 +++++++-------- .../DataTreeTest_TraverseLeaves.cpp | 8 +-- ...derNodeWithLessThanKChildrenOrNullTest.cpp | 4 +- ...rderNodeWithMoreThanOneChildOrNullTest.cpp | 10 ++- .../datatreestore/testutils/DataTreeTest.cpp | 68 ++++++++++--------- .../datatreestore/testutils/DataTreeTest.h | 44 ++++++------ .../testutils/TwoLevelDataFixture.h | 2 +- .../onblocks/testutils/BlobStoreTest.cpp | 6 +- .../onblocks/testutils/BlobStoreTest.h | 2 +- 36 files changed, 346 insertions(+), 316 deletions(-) diff --git a/implementations/onblocks/BlobOnBlocks.cpp b/implementations/onblocks/BlobOnBlocks.cpp index 71f00161..b850b456 100644 --- a/implementations/onblocks/BlobOnBlocks.cpp +++ b/implementations/onblocks/BlobOnBlocks.cpp @@ -5,8 +5,8 @@ #include "utils/Math.h" #include -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 datatree) +BlobOnBlocks::BlobOnBlocks(unique_ref datatree) : _datatree(std::move(datatree)) { } @@ -86,7 +86,7 @@ Key BlobOnBlocks::key() const { return _datatree->key(); } -unique_ptr BlobOnBlocks::releaseTree() { +unique_ref BlobOnBlocks::releaseTree() { return std::move(_datatree); } diff --git a/implementations/onblocks/BlobOnBlocks.h b/implementations/onblocks/BlobOnBlocks.h index 5bbb8d7f..5377061c 100644 --- a/implementations/onblocks/BlobOnBlocks.h +++ b/implementations/onblocks/BlobOnBlocks.h @@ -17,7 +17,7 @@ class DataTreeRef; class BlobOnBlocks: public Blob { public: - BlobOnBlocks(std::unique_ptr datatree); + BlobOnBlocks(cpputils::unique_ref datatree); virtual ~BlobOnBlocks(); blockstore::Key key() const override; @@ -31,14 +31,14 @@ public: void flush() override; - std::unique_ptr releaseTree(); + cpputils::unique_ref releaseTree(); private: void traverseLeaves(uint64_t offsetBytes, uint64_t sizeBytes, std::function) const; void resizeIfSmallerThan(uint64_t neededSize); - std::unique_ptr _datatree; + cpputils::unique_ref _datatree; }; } diff --git a/implementations/onblocks/BlobStoreOnBlocks.cpp b/implementations/onblocks/BlobStoreOnBlocks.cpp index b768cd56..86b3131a 100644 --- a/implementations/onblocks/BlobStoreOnBlocks.cpp +++ b/implementations/onblocks/BlobStoreOnBlocks.cpp @@ -9,9 +9,6 @@ #include "BlobOnBlocks.h" #include -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, uint32_t blocksizeBytes) -: _dataTreeStore(make_unique(make_unique(make_unique(make_unique(std::move(blockStore)), blocksizeBytes)))) { +BlobStoreOnBlocks::BlobStoreOnBlocks(unique_ref blockStore, uint32_t blocksizeBytes) +: _dataTreeStore(make_unique_ref(make_unique_ref(make_unique_ref(make_unique_ref(std::move(blockStore)), blocksizeBytes)))) { } BlobStoreOnBlocks::~BlobStoreOnBlocks() { @@ -42,10 +39,10 @@ unique_ref BlobStoreOnBlocks::create() { optional> BlobStoreOnBlocks::load(const Key &key) { auto tree = _dataTreeStore->load(key); - if (tree == nullptr) { + if (tree == none) { return none; } - return optional>(make_unique_ref(std::move(tree))); + return optional>(make_unique_ref(std::move(*tree))); } void BlobStoreOnBlocks::remove(unique_ref blob) { diff --git a/implementations/onblocks/BlobStoreOnBlocks.h b/implementations/onblocks/BlobStoreOnBlocks.h index a01922f5..62f1fc4d 100644 --- a/implementations/onblocks/BlobStoreOnBlocks.h +++ b/implementations/onblocks/BlobStoreOnBlocks.h @@ -15,7 +15,7 @@ class ParallelAccessDataTreeStore; class BlobStoreOnBlocks: public BlobStore { public: - BlobStoreOnBlocks(std::unique_ptr blockStore, uint32_t blocksizeBytes); + BlobStoreOnBlocks(cpputils::unique_ref blockStore, uint32_t blocksizeBytes); virtual ~BlobStoreOnBlocks(); cpputils::unique_ref create() override; @@ -24,7 +24,7 @@ public: void remove(cpputils::unique_ref blob) override; private: - std::unique_ptr _dataTreeStore; + cpputils::unique_ref _dataTreeStore; }; } diff --git a/implementations/onblocks/datanodestore/DataInnerNode.cpp b/implementations/onblocks/datanodestore/DataInnerNode.cpp index 352a9413..e508b1c1 100644 --- a/implementations/onblocks/datanodestore/DataInnerNode.cpp +++ b/implementations/onblocks/datanodestore/DataInnerNode.cpp @@ -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::InitializeNewNode(unique_ptr block, const DataNode &first_child) { +unique_ref DataInnerNode::InitializeNewNode(unique_ptr block, const DataNode &first_child) { DataNodeView node(std::move(block)); node.setDepth(first_child.depth() + 1); node.setSize(1); - auto result = make_unique(std::move(node)); + auto result = make_unique_ref(std::move(node)); result->ChildrenBegin()->setKey(first_child.key()); return result; } diff --git a/implementations/onblocks/datanodestore/DataInnerNode.h b/implementations/onblocks/datanodestore/DataInnerNode.h index f89f2888..6f814390 100644 --- a/implementations/onblocks/datanodestore/DataInnerNode.h +++ b/implementations/onblocks/datanodestore/DataInnerNode.h @@ -11,7 +11,7 @@ namespace datanodestore { class DataInnerNode: public DataNode { public: - static std::unique_ptr InitializeNewNode(std::unique_ptr block, const DataNode &first_child_key); + static cpputils::unique_ref InitializeNewNode(std::unique_ptr block, const DataNode &first_child_key); DataInnerNode(DataNodeView block); virtual ~DataInnerNode(); diff --git a/implementations/onblocks/datanodestore/DataLeafNode.cpp b/implementations/onblocks/datanodestore/DataLeafNode.cpp index 6a527bde..c88ee7f0 100644 --- a/implementations/onblocks/datanodestore/DataLeafNode.cpp +++ b/implementations/onblocks/datanodestore/DataLeafNode.cpp @@ -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::InitializeNewNode(unique_ptr block) { +unique_ref DataLeafNode::InitializeNewNode(unique_ptr 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(std::move(node)); + return make_unique_ref(std::move(node)); } void DataLeafNode::read(void *target, uint64_t offset, uint64_t size) const { diff --git a/implementations/onblocks/datanodestore/DataLeafNode.h b/implementations/onblocks/datanodestore/DataLeafNode.h index e9bede9a..f021d2a3 100644 --- a/implementations/onblocks/datanodestore/DataLeafNode.h +++ b/implementations/onblocks/datanodestore/DataLeafNode.h @@ -11,7 +11,7 @@ class DataInnerNode; class DataLeafNode: public DataNode { public: - static std::unique_ptr InitializeNewNode(std::unique_ptr block); + static cpputils::unique_ref InitializeNewNode(std::unique_ptr block); DataLeafNode(DataNodeView block); virtual ~DataLeafNode(); diff --git a/implementations/onblocks/datanodestore/DataNode.cpp b/implementations/onblocks/datanodestore/DataNode.cpp index 7d48a9ec..2d093963 100644 --- a/implementations/onblocks/datanodestore/DataNode.cpp +++ b/implementations/onblocks/datanodestore/DataNode.cpp @@ -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 DataNode::convertToNewInnerNode(unique_ptr node, const DataNode &first_child) { +unique_ref DataNode::convertToNewInnerNode(unique_ref node, const DataNode &first_child) { Key key = node->key(); auto block = node->_node.releaseBlock(); blockstore::utils::fillWithZeroes(block.get()); diff --git a/implementations/onblocks/datanodestore/DataNode.h b/implementations/onblocks/datanodestore/DataNode.h index 3d3276b7..17bbad62 100644 --- a/implementations/onblocks/datanodestore/DataNode.h +++ b/implementations/onblocks/datanodestore/DataNode.h @@ -19,7 +19,7 @@ public: uint8_t depth() const; - static std::unique_ptr convertToNewInnerNode(std::unique_ptr node, const DataNode &first_child); + static cpputils::unique_ref convertToNewInnerNode(cpputils::unique_ref node, const DataNode &first_child); void flush() const; diff --git a/implementations/onblocks/datanodestore/DataNodeStore.cpp b/implementations/onblocks/datanodestore/DataNodeStore.cpp index 409bbb61..513a6040 100644 --- a/implementations/onblocks/datanodestore/DataNodeStore.cpp +++ b/implementations/onblocks/datanodestore/DataNodeStore.cpp @@ -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, uint32_t blocksizeBytes) +DataNodeStore::DataNodeStore(unique_ref blockstore, uint32_t blocksizeBytes) : _blockstore(std::move(blockstore)), _layout(blocksizeBytes) { } DataNodeStore::~DataNodeStore() { } -unique_ptr DataNodeStore::load(unique_ptr block) { +unique_ref DataNodeStore::load(unique_ptr block) { assert(block->size() == _layout.blocksizeBytes()); DataNodeView node(std::move(block)); if (node.Depth() == 0) { - return unique_ptr(new DataLeafNode(std::move(node))); + return make_unique_ref(std::move(node)); } else if (node.Depth() <= MAX_DEPTH) { - return unique_ptr(new DataInnerNode(std::move(node))); + return make_unique_ref(std::move(node)); } else { throw runtime_error("Tree is to deep. Data corruption?"); } } -unique_ptr DataNodeStore::createNewInnerNode(const DataNode &first_child) { +unique_ref 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 DataNodeStore::createNewLeafNode() { +unique_ref 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 DataNodeStore::load(const Key &key) { +optional> DataNodeStore::load(const Key &key) { auto block = _blockstore->load(key); if (block == nullptr) { - return nullptr; + return none; } return load(std::move(block)); } -unique_ptr DataNodeStore::createNewNodeAsCopyFrom(const DataNode &source) { +unique_ref 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 DataNodeStore::overwriteNodeWith(unique_ptr target, const DataNode &source) { +unique_ref DataNodeStore::overwriteNodeWith(unique_ref 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 node) { +void DataNodeStore::remove(unique_ref 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 node) { +void DataNodeStore::removeSubtree(unique_ref node) { DataInnerNode *inner = dynamic_cast(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)); diff --git a/implementations/onblocks/datanodestore/DataNodeStore.h b/implementations/onblocks/datanodestore/DataNodeStore.h index 04925dfa..0cc07400 100644 --- a/implementations/onblocks/datanodestore/DataNodeStore.h +++ b/implementations/onblocks/datanodestore/DataNodeStore.h @@ -21,33 +21,33 @@ class DataInnerNode; class DataNodeStore { public: - DataNodeStore(std::unique_ptr blockstore, uint32_t blocksizeBytes); + DataNodeStore(cpputils::unique_ref blockstore, uint32_t blocksizeBytes); virtual ~DataNodeStore(); static constexpr uint8_t MAX_DEPTH = 10; DataNodeLayout layout() const; - std::unique_ptr load(const blockstore::Key &key); + boost::optional> load(const blockstore::Key &key); - std::unique_ptr createNewLeafNode(); - std::unique_ptr createNewInnerNode(const DataNode &first_child); + cpputils::unique_ref createNewLeafNode(); + cpputils::unique_ref createNewInnerNode(const DataNode &first_child); - std::unique_ptr createNewNodeAsCopyFrom(const DataNode &source); + cpputils::unique_ref createNewNodeAsCopyFrom(const DataNode &source); - std::unique_ptr overwriteNodeWith(std::unique_ptr target, const DataNode &source); + cpputils::unique_ref overwriteNodeWith(cpputils::unique_ref target, const DataNode &source); - void remove(std::unique_ptr node); + void remove(cpputils::unique_ref node); - void removeSubtree(std::unique_ptr node); + void removeSubtree(cpputils::unique_ref node); uint64_t numNodes() const; //TODO Test overwriteNodeWith(), createNodeAsCopyFrom(), removeSubtree() private: - std::unique_ptr load(std::unique_ptr block); + cpputils::unique_ref load(std::unique_ptr block); - std::unique_ptr _blockstore; + cpputils::unique_ref _blockstore; const DataNodeLayout _layout; DISALLOW_COPY_AND_ASSIGN(DataNodeStore); diff --git a/implementations/onblocks/datatreestore/DataTree.cpp b/implementations/onblocks/datatreestore/DataTree.cpp index 65e90e07..337c2a77 100644 --- a/implementations/onblocks/datatreestore/DataTree.cpp +++ b/implementations/onblocks/datatreestore/DataTree.cpp @@ -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 rootNode) +DataTree::DataTree(DataNodeStore *nodeStore, unique_ref 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 DataTree::addDataLeaf() { +unique_ref DataTree::addDataLeaf() { auto insertPosOrNull = algorithms::GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNull(_nodeStore, _rootNode.get()); if (insertPosOrNull) { return addDataLeafAt(insertPosOrNull.get()); @@ -76,7 +79,7 @@ unique_ptr DataTree::addDataLeaf() { } } -unique_ptr DataTree::addDataLeafAt(DataInnerNode *insertPos) { +unique_ref 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 DataTree::addDataLeafAt(DataInnerNode *insertPos) { } optional_ownership_ptr 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 chain = cpputils::WithoutOwnership(child); for(unsigned int i=0; icreateNewInnerNode(*chain); - chain = cpputils::WithOwnership(std::move(newnode)); + //TODO Don't use to_unique_ptr, but make optional_ownership_ptr work with unique_ref + chain = cpputils::WithOwnership(cpputils::to_unique_ptr(std::move(newnode))); } return chain; } -unique_ptr DataTree::createChainOfInnerNodes(unsigned int num, unique_ptr child) { - unique_ptr chain = std::move(child); +unique_ref DataTree::createChainOfInnerNodes(unsigned int num, unique_ref child) { + unique_ref chain = std::move(child); for(unsigned int i=0; icreateNewInnerNode(*chain); } @@ -111,7 +115,7 @@ DataInnerNode* DataTree::increaseTreeDepth(unsigned int levels) { return result; } -unique_ptr DataTree::addDataLeafToFullTree() { +unique_ref DataTree::addDataLeafToFullTree() { DataInnerNode *rootNode = increaseTreeDepth(1); auto newLeaf = addDataLeafAt(rootNode); return newLeaf; @@ -125,7 +129,7 @@ void DataTree::flush() const { _rootNode->flush(); } -unique_ptr DataTree::releaseRootNode() { +unique_ref DataTree::releaseRootNode() { return std::move(_rootNode); } @@ -143,7 +147,8 @@ uint32_t DataTree::_numLeaves(const DataNode &node) const { const DataInnerNode &inner = dynamic_cast(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> children = getOrCreateChildren(inner, beginChild, endChild); + vector> 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> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) { - vector> children; +vector> DataTree::getOrCreateChildren(DataInnerNode *node, uint32_t begin, uint32_t end) { + vector> 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> DataTree::getOrCreateChildren(DataInnerNode *node, return children; } -unique_ptr DataTree::addChildTo(DataInnerNode *node) { +unique_ref 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(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 DataTree::LastLeaf(DataNode *root) { } DataInnerNode *inner = dynamic_cast(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 DataTree::LastLeaf(unique_ptr root) { +unique_ref DataTree::LastLeaf(unique_ref root) { auto leaf = dynamic_pointer_move(root); - if (leaf.get() != nullptr) { - return leaf; + if (leaf != none) { + return std::move(*leaf); } auto inner = dynamic_pointer_move(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 { diff --git a/implementations/onblocks/datatreestore/DataTree.h b/implementations/onblocks/datatreestore/DataTree.h index 18ce1ff8..d1b780ec 100644 --- a/implementations/onblocks/datatreestore/DataTree.h +++ b/implementations/onblocks/datatreestore/DataTree.h @@ -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 rootNode); + DataTree(datanodestore::DataNodeStore *nodeStore, cpputils::unique_ref 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 _rootNode; + cpputils::unique_ref _rootNode; - std::unique_ptr addDataLeaf(); + cpputils::unique_ref addDataLeaf(); void removeLastDataLeaf(); - std::unique_ptr releaseRootNode(); + cpputils::unique_ref releaseRootNode(); friend class DataTreeStore; - std::unique_ptr addDataLeafAt(datanodestore::DataInnerNode *insertPos); + cpputils::unique_ref addDataLeafAt(datanodestore::DataInnerNode *insertPos); cpputils::optional_ownership_ptr createChainOfInnerNodes(unsigned int num, datanodestore::DataNode *child); - std::unique_ptr createChainOfInnerNodes(unsigned int num, std::unique_ptr child); - std::unique_ptr addDataLeafToFullTree(); + cpputils::unique_ref createChainOfInnerNodes(unsigned int num, cpputils::unique_ref child); + cpputils::unique_ref 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 LastLeaf(datanodestore::DataNode *root); - std::unique_ptr LastLeaf(std::unique_ptr root); + cpputils::unique_ref LastLeaf(cpputils::unique_ref root); datanodestore::DataInnerNode* increaseTreeDepth(unsigned int levels); - std::vector> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end); - std::unique_ptr addChildTo(datanodestore::DataInnerNode *node); + std::vector> getOrCreateChildren(datanodestore::DataInnerNode *node, uint32_t begin, uint32_t end); + cpputils::unique_ref addChildTo(datanodestore::DataInnerNode *node); DISALLOW_COPY_AND_ASSIGN(DataTree); }; diff --git a/implementations/onblocks/datatreestore/DataTreeStore.cpp b/implementations/onblocks/datatreestore/DataTreeStore.cpp index 6a561644..d1b1c07f 100644 --- a/implementations/onblocks/datatreestore/DataTreeStore.cpp +++ b/implementations/onblocks/datatreestore/DataTreeStore.cpp @@ -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 nodeStore) +DataTreeStore::DataTreeStore(unique_ref nodeStore) : _nodeStore(std::move(nodeStore)) { } DataTreeStore::~DataTreeStore() { } -unique_ptr DataTreeStore::load(const blockstore::Key &key) { +optional> DataTreeStore::load(const blockstore::Key &key) { auto node = _nodeStore->load(key); - if (node.get() == nullptr) { - return nullptr; - } else { - return make_unique(_nodeStore.get(), std::move(node)); + if (node == none) { + return none; } + return make_unique_ref(_nodeStore.get(), std::move(*node)); } -unique_ptr DataTreeStore::createNewTree() { - unique_ptr newleaf = _nodeStore->createNewLeafNode(); - return make_unique(_nodeStore.get(), std::move(newleaf)); +unique_ref DataTreeStore::createNewTree() { + auto newleaf = _nodeStore->createNewLeafNode(); + return make_unique_ref(_nodeStore.get(), std::move(newleaf)); } -void DataTreeStore::remove(unique_ptr tree) { +void DataTreeStore::remove(unique_ref tree) { auto root = tree->releaseRootNode(); - tree.reset(); + to_unique_ptr(std::move(tree)).reset(); // Destruct tree _nodeStore->removeSubtree(std::move(root)); } diff --git a/implementations/onblocks/datatreestore/DataTreeStore.h b/implementations/onblocks/datatreestore/DataTreeStore.h index 54e4c24b..39cd5211 100644 --- a/implementations/onblocks/datatreestore/DataTreeStore.h +++ b/implementations/onblocks/datatreestore/DataTreeStore.h @@ -4,7 +4,9 @@ #include #include +#include #include +#include namespace blobstore { namespace onblocks { @@ -16,17 +18,17 @@ class DataTree; class DataTreeStore { public: - DataTreeStore(std::unique_ptr nodeStore); + DataTreeStore(cpputils::unique_ref nodeStore); virtual ~DataTreeStore(); - std::unique_ptr load(const blockstore::Key &key); + boost::optional> load(const blockstore::Key &key); - std::unique_ptr createNewTree(); + cpputils::unique_ref createNewTree(); - void remove(std::unique_ptr tree); + void remove(cpputils::unique_ref tree); private: - std::unique_ptr _nodeStore; + cpputils::unique_ref _nodeStore; DISALLOW_COPY_AND_ASSIGN(DataTreeStore); }; diff --git a/implementations/onblocks/datatreestore/impl/algorithms.cpp b/implementations/onblocks/datatreestore/impl/algorithms.cpp index aafb41fa..75d62ee2 100644 --- a/implementations/onblocks/datatreestore/impl/algorithms.cpp +++ b/implementations/onblocks/datatreestore/impl/algorithms.cpp @@ -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 getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) { +optional> getLastChildAsInnerNode(DataNodeStore *nodeStore, const DataInnerNode &node) { Key key = node.LastChild()->key(); auto lastChild = nodeStore->load(key); - return dynamic_pointer_move(lastChild); + assert(lastChild != none); + return dynamic_pointer_move(*lastChild); } //Returns the lowest right border node meeting the condition specified (exclusive the leaf). @@ -31,11 +34,16 @@ optional_ownership_ptr GetLowestInnerRightBorderNodeWithCondition optional_ownership_ptr currentNode = cpputils::WithoutOwnership(dynamic_cast(rootNode)); optional_ownership_ptr result = cpputils::null(); 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(i) == rootNode->depth()-1); + if (lastChild != none) { + currentNode = cpputils::to_unique_ptr(std::move(*lastChild)); + } } return result; diff --git a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.cpp b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.cpp index bbabb550..3061e359 100644 --- a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.cpp +++ b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.cpp @@ -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(std::move(dataTreeStore)), _parallelAccessStore(make_unique(_dataTreeStore.get())) { +ParallelAccessDataTreeStore::ParallelAccessDataTreeStore(unique_ref dataTreeStore) + : _dataTreeStore(std::move(dataTreeStore)), _parallelAccessStore(make_unique_ref(_dataTreeStore.get())) { } ParallelAccessDataTreeStore::~ParallelAccessDataTreeStore() { } -unique_ptr ParallelAccessDataTreeStore::load(const blockstore::Key &key) { +optional> ParallelAccessDataTreeStore::load(const blockstore::Key &key) { return _parallelAccessStore.load(key); } -unique_ptr ParallelAccessDataTreeStore::createNewTree() { +unique_ref ParallelAccessDataTreeStore::createNewTree() { auto dataTree = _dataTreeStore->createNewTree(); Key key = dataTree->key(); return _parallelAccessStore.add(key, std::move(dataTree)); } -void ParallelAccessDataTreeStore::remove(unique_ptr tree) { +void ParallelAccessDataTreeStore::remove(unique_ref tree) { Key key = tree->key(); return _parallelAccessStore.remove(key, std::move(tree)); } diff --git a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.h b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.h index 03ebee7f..80614118 100644 --- a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.h +++ b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStore.h @@ -20,17 +20,17 @@ class DataTreeRef; class ParallelAccessDataTreeStore { public: - ParallelAccessDataTreeStore(std::unique_ptr dataTreeStore); + ParallelAccessDataTreeStore(cpputils::unique_ref dataTreeStore); virtual ~ParallelAccessDataTreeStore(); - std::unique_ptr load(const blockstore::Key &key); + boost::optional> load(const blockstore::Key &key); - std::unique_ptr createNewTree(); + cpputils::unique_ref createNewTree(); - void remove(std::unique_ptr tree); + void remove(cpputils::unique_ref tree); private: - std::unique_ptr _dataTreeStore; + cpputils::unique_ref _dataTreeStore; parallelaccessstore::ParallelAccessStore _parallelAccessStore; DISALLOW_COPY_AND_ASSIGN(ParallelAccessDataTreeStore); diff --git a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStoreAdapter.h b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStoreAdapter.h index 1691562a..8130dbe3 100644 --- a/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStoreAdapter.h +++ b/implementations/onblocks/parallelaccessdatatreestore/ParallelAccessDataTreeStoreAdapter.h @@ -16,11 +16,11 @@ public: :_baseDataTreeStore(std::move(baseDataTreeStore)) { } - std::unique_ptr loadFromBaseStore(const blockstore::Key &key) override { + boost::optional> loadFromBaseStore(const blockstore::Key &key) override { return _baseDataTreeStore->load(key); } - void removeFromBaseStore(std::unique_ptr dataTree) override { + void removeFromBaseStore(cpputils::unique_ref dataTree) override { return _baseDataTreeStore->remove(std::move(dataTree)); } diff --git a/test/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp b/test/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp index 785a178d..53f46a88 100644 --- a/test/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp +++ b/test/implementations/onblocks/datanodestore/DataInnerNodeTest.cpp @@ -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()), + _blockStore(make_unique_ref()), blockStore(_blockStore.get()), - nodeStore(make_unique(std::move(_blockStore), BLOCKSIZE_BYTES)), + nodeStore(make_unique_ref(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 LoadInnerNode(const Key &key) { - auto node = nodeStore->load(key); - return dynamic_pointer_move(node); + unique_ref LoadInnerNode(const Key &key) { + auto node = std::move(nodeStore->load(key).get()); + return std::move(dynamic_pointer_move(node).get()); } Key CreateNewInnerNodeReturnKey(const DataNode &firstChild) { return nodeStore->createNewInnerNode(firstChild)->key(); } - unique_ptr CreateNewInnerNode() { + unique_ref CreateNewInnerNode() { auto new_leaf = nodeStore->createNewLeafNode(); return nodeStore->createNewInnerNode(*new_leaf); } - unique_ptr CreateAndLoadNewInnerNode(const DataNode &firstChild) { + unique_ref CreateAndLoadNewInnerNode(const DataNode &firstChild) { auto key = CreateNewInnerNodeReturnKey(firstChild); return LoadInnerNode(key); } - unique_ptr CreateNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) { + unique_ref 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 CreateAndLoadNewInnerNode(const DataNode &firstChild, const DataNode &secondChild) { + unique_ref 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 converted = DataNode::convertToNewInnerNode(std::move(node), *child); + unique_ref converted = DataNode::convertToNewInnerNode(std::move(node), *child); return converted->key(); } - unique_ptr CopyInnerNode(const DataInnerNode &node) { + unique_ref CopyInnerNode(const DataInnerNode &node) { auto copied = nodeStore->createNewNodeAsCopyFrom(node); - return dynamic_pointer_move(copied); + return std::move(dynamic_pointer_move(copied).get()); } Key InitializeInnerNodeAddLeafReturnKey() { @@ -100,12 +100,12 @@ public: return node->key(); } - unique_ptr _blockStore; + unique_ref _blockStore; BlockStore *blockStore; - unique_ptr nodeStore; + unique_ref nodeStore; Data ZEROES; - unique_ptr leaf; - unique_ptr node; + unique_ref leaf; + unique_ref 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 converted = DataNode::convertToNewInnerNode(std::move(node), *child); + unique_ref converted = DataNode::convertToNewInnerNode(std::move(node), *child); EXPECT_EQ(1u, converted->numChildren()); EXPECT_EQ(child->key(), converted->getChild(0)->key()); diff --git a/test/implementations/onblocks/datanodestore/DataLeafNodeTest.cpp b/test/implementations/onblocks/datanodestore/DataLeafNodeTest.cpp index b0dfe3fe..8927fa6a 100644 --- a/test/implementations/onblocks/datanodestore/DataLeafNodeTest.cpp +++ b/test/implementations/onblocks/datanodestore/DataLeafNodeTest.cpp @@ -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()), + _blockStore(make_unique_ref()), blockStore(_blockStore.get()), - nodeStore(make_unique(std::move(_blockStore), BLOCKSIZE_BYTES)), + nodeStore(make_unique_ref(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 LoadLeafNode(const Key &key) { - auto leaf = nodeStore->load(key); - return dynamic_pointer_move(leaf); + unique_ref LoadLeafNode(const Key &key) { + auto leaf = std::move(nodeStore->load(key).get()); + return std::move(dynamic_pointer_move(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 converted = DataNode::convertToNewInnerNode(std::move(leaf), *child); + unique_ref converted = DataNode::convertToNewInnerNode(std::move(leaf), *child); return converted->key(); } - unique_ptr CopyLeafNode(const DataLeafNode &node) { + unique_ref CopyLeafNode(const DataLeafNode &node) { auto copied = nodeStore->createNewNodeAsCopyFrom(node); - return dynamic_pointer_move(copied); + return std::move(dynamic_pointer_move(copied).get()); } Key InitializeLeafGrowAndReturnKey() { @@ -106,12 +106,12 @@ public: return leaf->key(); } - unique_ptr _blockStore; + unique_ref _blockStore; BlockStore *blockStore; - unique_ptr nodeStore; + unique_ref nodeStore; Data ZEROES; Data randomData; - unique_ptr leaf; + unique_ref 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 converted = DataNode::convertToNewInnerNode(std::move(leaf), *child); + unique_ref converted = DataNode::convertToNewInnerNode(std::move(leaf), *child); EXPECT_EQ(1u, converted->numChildren()); EXPECT_EQ(child->key(), converted->getChild(0)->key()); diff --git a/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp b/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp index 71c7fc74..3f524f3f 100644 --- a/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp +++ b/test/implementations/onblocks/datanodestore/DataNodeStoreTest.cpp @@ -7,11 +7,13 @@ #include "messmer/blockstore/implementations/testfake/FakeBlockStore.h" #include "messmer/blockstore/implementations/testfake/FakeBlock.h" +#include 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 = make_unique(); + unique_ref _blockStore = make_unique_ref(); BlockStore *blockStore = _blockStore.get(); - unique_ptr nodeStore = make_unique(std::move(_blockStore), BLOCKSIZE_BYTES); + unique_ref nodeStore = make_unique_ref(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) { diff --git a/test/implementations/onblocks/datanodestore/DataNodeViewTest.cpp b/test/implementations/onblocks/datanodestore/DataNodeViewTest.cpp index 71838474..bf43eb9f 100644 --- a/test/implementations/onblocks/datanodestore/DataNodeViewTest.cpp +++ b/test/implementations/onblocks/datanodestore/DataNodeViewTest.cpp @@ -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 = make_unique(); + unique_ref blockStore = make_unique_ref(); }; class DataNodeViewDepthTest: public DataNodeViewTest, public WithParamInterface { diff --git a/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp b/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp index 273dd2fb..4fa03128 100644 --- a/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp +++ b/test/implementations/onblocks/datatreestore/DataTreeStoreTest.cpp @@ -3,11 +3,12 @@ #include "../../../../implementations/onblocks/datanodestore/DataNodeStore.h" #include "../../../../implementations/onblocks/datatreestore/DataTreeStore.h" #include +#include 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)); } diff --git a/test/implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp b/test/implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp index 84aebeed..9042209d 100644 --- a/test/implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp +++ b/test/implementations/onblocks/datatreestore/DataTreeTest_NumStoredBytes.cpp @@ -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()); } diff --git a/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp b/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp index 28718519..2c71ee90 100644 --- a/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp +++ b/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeByTraversing.cpp @@ -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 CreateTree(unique_ptr root) { + unique_ref CreateTree(unique_ref 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 CreateLeafTreeWithSize(uint32_t size) { + unique_ref CreateLeafTreeWithSize(uint32_t size) { return CreateTree(CreateLeafWithSize(size)); } - unique_ptr CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) { + unique_ref CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) { return CreateTree(CreateTwoLeafWithSecondLeafSize(size)); } - unique_ptr CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) { + unique_ref CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) { return CreateTree(CreateFullTwoLevelWithLastLeafSize(size)); } - unique_ptr CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) { + unique_ref CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) { return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size)); } - unique_ptr CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) { + unique_ref CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) { return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size)); } - unique_ptr CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) { + unique_ref CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) { return CreateTree(CreateFullThreeLevelWithLastLeafSize(size)); } - unique_ptr CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) { + unique_ref 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(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(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(DataTreeTest_ResizeByTraversing*, uint32_t)>, uint32_t, uint32_t>> { +class DataTreeTest_ResizeByTraversing_P: public DataTreeTest_ResizeByTraversing, public WithParamInterface(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 LastLeaf(const Key &key) { - auto root = nodeStore->load(key); + unique_ref LastLeaf(const Key &key) { + auto root = std::move(nodeStore->load(key).get()); auto leaf = dynamic_pointer_move(root); - if (leaf.get() != nullptr) { - return leaf; + if (leaf != none) { + return std::move(*leaf); } - auto inner = dynamic_pointer_move(root); + auto inner = std::move(dynamic_pointer_move(root).get()); return LastLeaf(inner->LastChild()->key()); } uint32_t oldLastLeafSize; - unique_ptr tree; + unique_ref 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(DataTreeTest_ResizeByTraversing*, uint32_t)>>( + Values(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); } diff --git a/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp b/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp index 843f9642..1d469c52 100644 --- a/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp +++ b/test/implementations/onblocks/datatreestore/DataTreeTest_ResizeNumBytes.cpp @@ -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 CreateTree(unique_ptr root) { + unique_ref CreateTree(unique_ref 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 CreateLeafTreeWithSize(uint32_t size) { + unique_ref CreateLeafTreeWithSize(uint32_t size) { return CreateTree(CreateLeafWithSize(size)); } - unique_ptr CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) { + unique_ref CreateTwoLeafTreeWithSecondLeafSize(uint32_t size) { return CreateTree(CreateTwoLeafWithSecondLeafSize(size)); } - unique_ptr CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) { + unique_ref CreateFullTwoLevelTreeWithLastLeafSize(uint32_t size) { return CreateTree(CreateFullTwoLevelWithLastLeafSize(size)); } - unique_ptr CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) { + unique_ref CreateThreeLevelTreeWithTwoChildrenAndLastLeafSize(uint32_t size) { return CreateTree(CreateThreeLevelWithTwoChildrenAndLastLeafSize(size)); } - unique_ptr CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) { + unique_ref CreateThreeLevelTreeWithThreeChildrenAndLastLeafSize(uint32_t size) { return CreateTree(CreateThreeLevelWithThreeChildrenAndLastLeafSize(size)); } - unique_ptr CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) { + unique_ref CreateFullThreeLevelTreeWithLastLeafSize(uint32_t size) { return CreateTree(CreateFullThreeLevelWithLastLeafSize(size)); } - unique_ptr CreateFourLevelMinDataTreeWithLastLeafSize(uint32_t size) { + unique_ref 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(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(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(DataTreeTest_ResizeNumBytes*, uint32_t)>, uint32_t, uint32_t, uint32_t>> { +class DataTreeTest_ResizeNumBytes_P: public DataTreeTest_ResizeNumBytes, public WithParamInterface(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 LastLeaf(const Key &key) { - auto root = nodeStore->load(key); + unique_ref LastLeaf(const Key &key) { + auto root = std::move(nodeStore->load(key).get()); auto leaf = dynamic_pointer_move(root); - if (leaf.get() != nullptr) { - return leaf; + if (leaf != none) { + return std::move(*leaf); } - auto inner = dynamic_pointer_move(root); + auto inner = std::move(dynamic_pointer_move(root).get()); return LastLeaf(inner->LastChild()->key()); } uint32_t oldLastLeafSize; - unique_ptr tree; + unique_ref 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(DataTreeTest_ResizeNumBytes*, uint32_t)>>( + Values(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()); } diff --git a/test/implementations/onblocks/datatreestore/DataTreeTest_TraverseLeaves.cpp b/test/implementations/onblocks/datatreestore/DataTreeTest_TraverseLeaves.cpp index 3fe21614..80ca7d3d 100644 --- a/test/implementations/onblocks/datatreestore/DataTreeTest_TraverseLeaves.cpp +++ b/test/implementations/onblocks/datatreestore/DataTreeTest_TraverseLeaves.cpp @@ -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 CreateThreeLevel() { + unique_ref CreateThreeLevel() { return CreateInner({ CreateFullTwoLevel(), CreateFullTwoLevel(), @@ -32,7 +32,7 @@ public: CreateInner({CreateLeaf(), CreateLeaf(), CreateLeaf()})}); } - unique_ptr CreateFourLevel() { + unique_ref 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); }); diff --git a/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp b/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp index 447fc4f4..e64532c6 100644 --- a/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp +++ b/test/implementations/onblocks/datatreestore/impl/GetLowestInnerRightBorderNodeWithLessThanKChildrenOrNullTest.cpp @@ -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()); } diff --git a/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp b/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp index 38111835..d3c7b399 100644 --- a/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp +++ b/test/implementations/onblocks/datatreestore/impl/GetLowestRightBorderNodeWithMoreThanOneChildOrNullTest.cpp @@ -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()); } diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp index 4fa57946..f9626acd 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.cpp @@ -2,6 +2,7 @@ #include "messmer/blockstore/implementations/testfake/FakeBlockStore.h" #include +#include 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(make_unique(), BLOCKSIZE_BYTES)), + :_nodeStore(make_unique_ref(make_unique_ref(), BLOCKSIZE_BYTES)), nodeStore(_nodeStore.get()), treeStore(std::move(_nodeStore)) { } -unique_ptr DataTreeTest::CreateLeaf() { +unique_ref DataTreeTest::CreateLeaf() { return nodeStore->createNewLeafNode(); } -unique_ptr DataTreeTest::CreateInner(initializer_list> children) { +unique_ref DataTreeTest::CreateInner(initializer_list> children) { vector childrenVector(children.size()); - std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ptr &ptr) {return ptr.get();}); + std::transform(children.begin(), children.end(), childrenVector.begin(), [](const unique_ref &ptr) {return ptr.get();}); return CreateInner(childrenVector); } -unique_ptr DataTreeTest::CreateInner(initializer_list children) { +unique_ref DataTreeTest::CreateInner(initializer_list children) { return CreateInner(vector(children)); } -unique_ptr DataTreeTest::CreateInner(vector children) { +unique_ref DataTreeTest::CreateInner(vector 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 DataTreeTest::CreateInner(vector chil return node; } -unique_ptr DataTreeTest::CreateLeafOnlyTree() { +unique_ref 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 DataTreeTest::CreateFullTwoLevel() { +unique_ref DataTreeTest::CreateFullTwoLevel() { auto root = CreateInner({CreateLeaf().get()}); FillNode(root.get()); return root; } -unique_ptr DataTreeTest::CreateThreeLevelMinData() { +unique_ref DataTreeTest::CreateThreeLevelMinData() { return CreateInner({ CreateFullTwoLevel(), CreateInner({CreateLeaf()}) }); } -unique_ptr DataTreeTest::CreateFourLevelMinData() { +unique_ref DataTreeTest::CreateFourLevelMinData() { return CreateInner({ CreateFullThreeLevel(), CreateInner({CreateInner({CreateLeaf()})}) }); } -unique_ptr DataTreeTest::CreateFullThreeLevel() { +unique_ref DataTreeTest::CreateFullThreeLevel() { auto root = CreateInner({CreateFullTwoLevel().get()}); FillNodeTwoLevel(root.get()); return root; } -unique_ptr DataTreeTest::LoadInnerNode(const Key &key) { - auto node = nodeStore->load(key); +unique_ref DataTreeTest::LoadInnerNode(const Key &key) { + auto node = std::move(nodeStore->load(key).get()); auto casted = dynamic_pointer_move(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 DataTreeTest::LoadLeafNode(const Key &key) { - auto node = nodeStore->load(key); +unique_ref DataTreeTest::LoadLeafNode(const Key &key) { + auto node = std::move(nodeStore->load(key).get()); auto casted = dynamic_pointer_move(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 DataTreeTest::CreateTwoLeaf() { +unique_ref DataTreeTest::CreateTwoLeaf() { return CreateInner({CreateLeaf().get(), CreateLeaf().get()}); } -unique_ptr DataTreeTest::CreateTwoLeafTree() { +unique_ref DataTreeTest::CreateTwoLeafTree() { auto key = CreateTwoLeaf()->key(); - return treeStore.load(key); + return std::move(treeStore.load(key).get()); } -unique_ptr DataTreeTest::CreateLeafWithSize(uint32_t size) { +unique_ref DataTreeTest::CreateLeafWithSize(uint32_t size) { auto leaf = CreateLeaf(); leaf->resize(size); return leaf; } -unique_ptr DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) { +unique_ref DataTreeTest::CreateTwoLeafWithSecondLeafSize(uint32_t size) { return CreateInner({ CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()), CreateLeafWithSize(size) }); } -unique_ptr DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint32_t size) { +unique_ref 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 DataTreeTest::CreateFullTwoLevelWithLastLeafSize(uint3 return root; } -unique_ptr DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) { +unique_ref DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size) { return CreateInner({ CreateInner({ CreateLeafWithSize(nodeStore->layout().maxBytesPerLeaf()), @@ -144,7 +146,7 @@ unique_ptr DataTreeTest::CreateThreeLevelWithOneChildAndLastLeafS }); } -unique_ptr DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) { +unique_ref DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size) { return CreateInner({ CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()), CreateInner({ @@ -154,7 +156,7 @@ unique_ptr DataTreeTest::CreateThreeLevelWithTwoChildrenAndLastLe }); } -unique_ptr DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) { +unique_ref DataTreeTest::CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size) { return CreateInner({ CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()), CreateFullTwoLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()), @@ -165,7 +167,7 @@ unique_ptr DataTreeTest::CreateThreeLevelWithThreeChildrenAndLast }); } -unique_ptr DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uint32_t size) { +unique_ref 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 DataTreeTest::CreateFullThreeLevelWithLastLeafSize(uin return root; } -unique_ptr DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) { +unique_ref DataTreeTest::CreateFourLevelMinDataWithLastLeafSize(uint32_t size) { return CreateInner({ CreateFullThreeLevelWithLastLeafSize(nodeStore->layout().maxBytesPerLeaf()), CreateInner({CreateInner({CreateLeafWithSize(size)})}) diff --git a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h index 0d2d4c31..9b0002a1 100644 --- a/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h +++ b/test/implementations/onblocks/datatreestore/testutils/DataTreeTest.h @@ -16,35 +16,35 @@ public: static constexpr uint32_t BLOCKSIZE_BYTES = 256; - std::unique_ptr CreateLeaf(); - std::unique_ptr CreateInner(std::vector children); - std::unique_ptr CreateInner(std::initializer_list children); - std::unique_ptr CreateInner(std::initializer_list> children); + cpputils::unique_ref CreateLeaf(); + cpputils::unique_ref CreateInner(std::vector children); + cpputils::unique_ref CreateInner(std::initializer_list children); + cpputils::unique_ref CreateInner(std::initializer_list> children); - std::unique_ptr CreateLeafOnlyTree(); - std::unique_ptr CreateTwoLeaf(); - std::unique_ptr CreateTwoLeafTree(); + cpputils::unique_ref CreateLeafOnlyTree(); + cpputils::unique_ref CreateTwoLeaf(); + cpputils::unique_ref CreateTwoLeafTree(); void FillNode(blobstore::onblocks::datanodestore::DataInnerNode *node); void FillNodeTwoLevel(blobstore::onblocks::datanodestore::DataInnerNode *node); - std::unique_ptr CreateFullTwoLevel(); - std::unique_ptr CreateFullThreeLevel(); + cpputils::unique_ref CreateFullTwoLevel(); + cpputils::unique_ref CreateFullThreeLevel(); - std::unique_ptr CreateThreeLevelMinData(); - std::unique_ptr CreateFourLevelMinData(); + cpputils::unique_ref CreateThreeLevelMinData(); + cpputils::unique_ref CreateFourLevelMinData(); - std::unique_ptr LoadInnerNode(const blockstore::Key &key); - std::unique_ptr LoadLeafNode(const blockstore::Key &key); + cpputils::unique_ref LoadInnerNode(const blockstore::Key &key); + cpputils::unique_ref LoadLeafNode(const blockstore::Key &key); - std::unique_ptr CreateLeafWithSize(uint32_t size); - std::unique_ptr CreateTwoLeafWithSecondLeafSize(uint32_t size); - std::unique_ptr CreateFullTwoLevelWithLastLeafSize(uint32_t size); - std::unique_ptr CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size); - std::unique_ptr CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size); - std::unique_ptr CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size); - std::unique_ptr CreateFullThreeLevelWithLastLeafSize(uint32_t size); - std::unique_ptr CreateFourLevelMinDataWithLastLeafSize(uint32_t size); + cpputils::unique_ref CreateLeafWithSize(uint32_t size); + cpputils::unique_ref CreateTwoLeafWithSecondLeafSize(uint32_t size); + cpputils::unique_ref CreateFullTwoLevelWithLastLeafSize(uint32_t size); + cpputils::unique_ref CreateThreeLevelWithOneChildAndLastLeafSize(uint32_t size); + cpputils::unique_ref CreateThreeLevelWithTwoChildrenAndLastLeafSize(uint32_t size); + cpputils::unique_ref CreateThreeLevelWithThreeChildrenAndLastLeafSize(uint32_t size); + cpputils::unique_ref CreateFullThreeLevelWithLastLeafSize(uint32_t size); + cpputils::unique_ref CreateFourLevelMinDataWithLastLeafSize(uint32_t size); - std::unique_ptr _nodeStore; + cpputils::unique_ref _nodeStore; blobstore::onblocks::datanodestore::DataNodeStore *nodeStore; blobstore::onblocks::datatreestore::DataTreeStore treeStore; diff --git a/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h b/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h index 9e9c49df..007b74b6 100644 --- a/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h +++ b/test/implementations/onblocks/datatreestore/testutils/TwoLevelDataFixture.h @@ -50,7 +50,7 @@ private: auto inner = dynamic_cast(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; diff --git a/test/implementations/onblocks/testutils/BlobStoreTest.cpp b/test/implementations/onblocks/testutils/BlobStoreTest.cpp index be927dcf..fc8d42f4 100644 --- a/test/implementations/onblocks/testutils/BlobStoreTest.cpp +++ b/test/implementations/onblocks/testutils/BlobStoreTest.cpp @@ -3,14 +3,12 @@ #include #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(make_unique(), BLOCKSIZE_BYTES)) { + : blobStore(make_unique_ref(make_unique_ref(), BLOCKSIZE_BYTES)) { } diff --git a/test/implementations/onblocks/testutils/BlobStoreTest.h b/test/implementations/onblocks/testutils/BlobStoreTest.h index 2c664646..2b2bb2c8 100644 --- a/test/implementations/onblocks/testutils/BlobStoreTest.h +++ b/test/implementations/onblocks/testutils/BlobStoreTest.h @@ -8,7 +8,7 @@ public: static constexpr uint32_t BLOCKSIZE_BYTES = 4096; - std::unique_ptr blobStore; + cpputils::unique_ref blobStore; cpputils::unique_ref loadBlob(const blockstore::Key &key) { auto loaded = blobStore->load(key);