DataTree is threadsafe

This commit is contained in:
Sebastian Messmer 2015-04-09 16:10:57 +02:00
parent 84401b9abf
commit 9a959cfab9
3 changed files with 13 additions and 1 deletions

View File

@ -3,6 +3,8 @@ INCLUDE(messmer/cmake/tools)
# Actually create targets: EXEcutables and libraries. # Actually create targets: EXEcutables and libraries.
ADD_BII_TARGETS() ADD_BII_TARGETS()
ADD_BOOST(thread)
ACTIVATE_CPP14() ACTIVATE_CPP14()
# You can safely delete lines from here... # You can safely delete lines from here...

View File

@ -21,6 +21,9 @@ using blobstore::onblocks::datanodestore::DataNodeLayout;
using std::unique_ptr; using std::unique_ptr;
using std::dynamic_pointer_cast; using std::dynamic_pointer_cast;
using std::function; using std::function;
using boost::shared_mutex;
using boost::shared_lock;
using boost::unique_lock;
using cpputils::dynamic_pointer_move; using cpputils::dynamic_pointer_move;
using cpputils::optional_ownership_ptr; using cpputils::optional_ownership_ptr;
@ -32,7 +35,7 @@ namespace onblocks {
namespace datatreestore { namespace datatreestore {
DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr<DataNode> rootNode) DataTree::DataTree(DataNodeStore *nodeStore, unique_ptr<DataNode> rootNode)
: _nodeStore(nodeStore), _rootNode(std::move(rootNode)) { : _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)) {
} }
DataTree::~DataTree() { DataTree::~DataTree() {
@ -109,6 +112,7 @@ unique_ptr<DataNode> DataTree::releaseRootNode() {
} }
void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (DataLeafNode*, uint32_t)> func) { void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (DataLeafNode*, uint32_t)> func) {
shared_lock<shared_mutex> lock(_mutex);
const_cast<const DataTree*>(this)->traverseLeaves(beginIndex, endIndex, [func](const DataLeafNode* leaf, uint32_t leafIndex) { const_cast<const DataTree*>(this)->traverseLeaves(beginIndex, endIndex, [func](const DataLeafNode* leaf, uint32_t leafIndex) {
func(const_cast<DataLeafNode*>(leaf), leafIndex); func(const_cast<DataLeafNode*>(leaf), leafIndex);
}); });
@ -116,6 +120,7 @@ void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<v
} }
void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (const DataLeafNode*, uint32_t)> func) const { void DataTree::traverseLeaves(uint32_t beginIndex, uint32_t endIndex, function<void (const DataLeafNode*, uint32_t)> func) const {
shared_lock<shared_mutex> lock(_mutex);
assert(beginIndex <= endIndex); assert(beginIndex <= endIndex);
//TODO assert(beginIndex <= numLeaves()); //TODO assert(beginIndex <= numLeaves());
//TODO assert(endIndex <= numLeaves()); //TODO assert(endIndex <= numLeaves());
@ -155,6 +160,7 @@ uint64_t DataTree::numStoredBytes() const {
} }
uint64_t DataTree::numStoredBytes(const DataNode &root) const { uint64_t DataTree::numStoredBytes(const DataNode &root) const {
shared_lock<shared_mutex> lock(_mutex);
const DataLeafNode *leaf = dynamic_cast<const DataLeafNode*>(&root); const DataLeafNode *leaf = dynamic_cast<const DataLeafNode*>(&root);
if (leaf != nullptr) { if (leaf != nullptr) {
return leaf->numBytes(); return leaf->numBytes();
@ -169,6 +175,7 @@ uint64_t DataTree::numStoredBytes(const DataNode &root) const {
} }
void DataTree::resizeNumBytes(uint64_t newNumBytes) { void DataTree::resizeNumBytes(uint64_t newNumBytes) {
unique_lock<shared_mutex> lock(_mutex);
//TODO Faster implementation possible (no addDataLeaf()/removeLastDataLeaf() in a loop, but directly resizing) //TODO Faster implementation possible (no addDataLeaf()/removeLastDataLeaf() in a loop, but directly resizing)
LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf()); LastLeaf(_rootNode.get())->resize(_nodeStore->layout().maxBytesPerLeaf());
uint64_t currentNumBytes = numStoredBytes(); uint64_t currentNumBytes = numStoredBytes();

View File

@ -6,6 +6,8 @@
#include <messmer/cpp-utils/macros.h> #include <messmer/cpp-utils/macros.h>
#include <messmer/cpp-utils/optional_ownership_ptr.h> #include <messmer/cpp-utils/optional_ownership_ptr.h>
#include "../datanodestore/DataNodeView.h" #include "../datanodestore/DataNodeView.h"
//TODO Replace with C++14 once std::shared_mutex is supported
#include <boost/thread/shared_mutex.hpp>
namespace blockstore { namespace blockstore {
class Key; class Key;
@ -36,6 +38,7 @@ public:
uint64_t numStoredBytes() const; uint64_t numStoredBytes() const;
private: private:
mutable boost::shared_mutex _mutex;
datanodestore::DataNodeStore *_nodeStore; datanodestore::DataNodeStore *_nodeStore;
std::unique_ptr<datanodestore::DataNode> _rootNode; std::unique_ptr<datanodestore::DataNode> _rootNode;