diff --git a/src/storage/v2/storage.cpp b/src/storage/v2/storage.cpp index dda82bde5..e4d31844d 100644 --- a/src/storage/v2/storage.cpp +++ b/src/storage/v2/storage.cpp @@ -26,7 +26,8 @@ Storage::Accessor::Accessor(Storage *storage, uint64_t transaction_id, : storage_(storage), transaction_(transaction_id, start_timestamp), is_transaction_starter_(true), - is_transaction_active_(true) {} + is_transaction_active_(true), + storage_guard_(storage_->main_lock_) {} Storage::Accessor::Accessor(Accessor &&other) noexcept : storage_(other.storage_), diff --git a/src/storage/v2/storage.hpp b/src/storage/v2/storage.hpp index 504a8f9d7..5d2114ac4 100644 --- a/src/storage/v2/storage.hpp +++ b/src/storage/v2/storage.hpp @@ -1,6 +1,7 @@ #pragma once #include <optional> +#include <shared_mutex> #include "storage/v2/commit_log.hpp" #include "storage/v2/edge.hpp" @@ -11,6 +12,7 @@ #include "storage/v2/transaction.hpp" #include "storage/v2/vertex.hpp" #include "storage/v2/vertex_accessor.hpp" +#include "utils/rw_lock.hpp" #include "utils/scheduler.hpp" #include "utils/skip_list.hpp" @@ -99,6 +101,8 @@ class Storage final { Transaction transaction_; bool is_transaction_starter_; bool is_transaction_active_; + + std::shared_lock<utils::RWLock> storage_guard_; }; Accessor Access(); @@ -106,6 +110,14 @@ class Storage final { private: void CollectGarbage(); + // Main storage lock. + // + // Accessors take a shared lock when starting, so it is possible to block + // creation of new accessors by taking a unique lock. This is used when + // building a label-property index because it is much simpler to do when there + // are no parallel reads and writes. + utils::RWLock main_lock_{utils::RWLock::Priority::WRITE}; + // Main object storage utils::SkipList<storage::Vertex> vertices_; utils::SkipList<storage::Edge> edges_;