Fix DataTree::key() when called while traversing

This commit is contained in:
Sebastian Messmer 2016-07-14 17:56:44 +02:00
parent 6ff0839e90
commit f42e08a5f6
2 changed files with 5 additions and 2 deletions

View File

@ -40,14 +40,14 @@ namespace onblocks {
namespace datatreestore { namespace datatreestore {
DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode) DataTree::DataTree(DataNodeStore *nodeStore, unique_ref<DataNode> rootNode)
: _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)), _numLeavesCache(none) { : _mutex(), _nodeStore(nodeStore), _rootNode(std::move(rootNode)), _key(_rootNode->key()), _numLeavesCache(none) {
} }
DataTree::~DataTree() { DataTree::~DataTree() {
} }
const Key &DataTree::key() const { const Key &DataTree::key() const {
return _rootNode->key(); return _key;
} }
void DataTree::flush() const { void DataTree::flush() const {
@ -58,6 +58,7 @@ void DataTree::flush() const {
} }
unique_ref<DataNode> DataTree::releaseRootNode() { unique_ref<DataNode> DataTree::releaseRootNode() {
unique_lock<shared_mutex> lock(_mutex); // Lock ensures that the root node is currently set (traversing unsets it temporarily)
return std::move(_rootNode); return std::move(_rootNode);
} }
@ -75,6 +76,7 @@ uint32_t DataTree::_numLeaves() const {
} }
uint32_t DataTree::_forceComputeNumLeaves() const { uint32_t DataTree::_forceComputeNumLeaves() const {
unique_lock<shared_mutex> lock(_mutex); // Lock ensures that the root node is currently set (traversing unsets it temporarily)
_numLeavesCache = _computeNumLeaves(*_rootNode); _numLeavesCache = _computeNumLeaves(*_rootNode);
return *_numLeavesCache; return *_numLeavesCache;
} }

View File

@ -45,6 +45,7 @@ private:
mutable boost::shared_mutex _mutex; mutable boost::shared_mutex _mutex;
datanodestore::DataNodeStore *_nodeStore; datanodestore::DataNodeStore *_nodeStore;
cpputils::unique_ref<datanodestore::DataNode> _rootNode; cpputils::unique_ref<datanodestore::DataNode> _rootNode;
blockstore::Key _key; // Key is stored in a member variable, since _rootNode is nullptr while traversing, but we still want to be able to return the key.
mutable boost::optional<uint32_t> _numLeavesCache; mutable boost::optional<uint32_t> _numLeavesCache;
cpputils::unique_ref<datanodestore::DataNode> releaseRootNode(); cpputils::unique_ref<datanodestore::DataNode> releaseRootNode();