From 83a99aaf7d8c8244a6b2fd4b1a9c5a934c1ba6f6 Mon Sep 17 00:00:00 2001 From: Matej Ferencevic Date: Mon, 1 Jul 2019 16:11:12 +0200 Subject: [PATCH] Implement vertex deletion in storage v2 Reviewers: mtomic, teon.banek Reviewed By: mtomic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2157 --- src/storage/v2/delta.hpp | 1 + src/storage/v2/result.hpp | 9 +- src/storage/v2/storage.hpp | 4 + src/storage/v2/vertex.hpp | 6 +- src/storage/v2/vertex_accessor.hpp | 53 ++- tests/unit/storage_v2.cpp | 618 ++++++++++++++++++++++++----- 6 files changed, 580 insertions(+), 111 deletions(-) diff --git a/src/storage/v2/delta.hpp b/src/storage/v2/delta.hpp index c5bd92899..29cbccc9f 100644 --- a/src/storage/v2/delta.hpp +++ b/src/storage/v2/delta.hpp @@ -7,6 +7,7 @@ namespace storage { struct Delta { enum class Action { DELETE_OBJECT, + RECREATE_OBJECT, ADD_LABEL, REMOVE_LABEL, }; diff --git a/src/storage/v2/result.hpp b/src/storage/v2/result.hpp index 1987c3dac..77d335cd9 100644 --- a/src/storage/v2/result.hpp +++ b/src/storage/v2/result.hpp @@ -8,6 +8,7 @@ namespace storage { enum class Error : uint8_t { SERIALIZATION_ERROR, + DELETED_OBJECT, }; template @@ -20,14 +21,14 @@ class Result final { bool IsReturn() const { return return_.has_value(); } bool IsError() const { return error_.has_value(); } - TReturn *GetReturn() { + TReturn &GetReturn() { CHECK(return_) << "The storage result is an error!"; - return &*return_; + return return_.value(); } - const TReturn *GetReturn() const { + const TReturn &GetReturn() const { CHECK(return_) << "The storage result is an error!"; - return &*return_; + return return_.value(); } Error GetError() const { diff --git a/src/storage/v2/storage.hpp b/src/storage/v2/storage.hpp index 41588aeae..79388c895 100644 --- a/src/storage/v2/storage.hpp +++ b/src/storage/v2/storage.hpp @@ -146,6 +146,10 @@ class Storage final { CHECK(acc.remove(vertex->gid)) << "Invalid database state!"; break; } + case Delta::Action::RECREATE_OBJECT: { + vertex->deleted = false; + break; + } } current = current->next.load(std::memory_order_acquire); } diff --git a/src/storage/v2/vertex.hpp b/src/storage/v2/vertex.hpp index c369bece8..6923610fd 100644 --- a/src/storage/v2/vertex.hpp +++ b/src/storage/v2/vertex.hpp @@ -12,7 +12,7 @@ namespace storage { struct Vertex { - Vertex(Gid gid, Delta *delta) : gid(gid), delta(delta) { + Vertex(Gid gid, Delta *delta) : gid(gid), deleted(false), delta(delta) { CHECK(delta->action == Delta::Action::DELETE_OBJECT) << "Vertex must be created with an initial DELETE_OBJECT delta!"; } @@ -24,7 +24,9 @@ struct Vertex { // std::unordered_map properties; utils::SpinLock lock; - // uint32_t PAD; + bool deleted; + // uint8_t PAD; + // uint16_t PAD; Delta *delta; }; diff --git a/src/storage/v2/vertex_accessor.hpp b/src/storage/v2/vertex_accessor.hpp index defde8ba8..c6afeed06 100644 --- a/src/storage/v2/vertex_accessor.hpp +++ b/src/storage/v2/vertex_accessor.hpp @@ -21,18 +21,23 @@ class VertexAccessor final { static std::optional Create(Vertex *vertex, Transaction *transaction, View view) { + bool is_visible = true; Delta *delta = nullptr; { std::lock_guard guard(vertex->lock); + is_visible = !vertex->deleted; delta = vertex->delta; } - bool is_visible = true; ApplyDeltasForRead(transaction, delta, view, [&is_visible](const Delta &delta) { switch (delta.action) { case Delta::Action::ADD_LABEL: case Delta::Action::REMOVE_LABEL: break; + case Delta::Action::RECREATE_OBJECT: { + is_visible = true; + break; + } case Delta::Action::DELETE_OBJECT: { is_visible = false; break; @@ -43,12 +48,30 @@ class VertexAccessor final { return VertexAccessor{vertex, transaction}; } + Result Delete() { + std::lock_guard guard(vertex_->lock); + + if (!PrepareForWrite(transaction_, vertex_)) + return Result{Error::SERIALIZATION_ERROR}; + + if (vertex_->deleted) return Result{false}; + + CreateAndLinkDelta(transaction_, vertex_, Delta::Action::RECREATE_OBJECT, + 0); + + vertex_->deleted = true; + + return Result{true}; + } + Result AddLabel(uint64_t label) { std::lock_guard guard(vertex_->lock); if (!PrepareForWrite(transaction_, vertex_)) return Result{Error::SERIALIZATION_ERROR}; + if (vertex_->deleted) return Result{Error::DELETED_OBJECT}; + if (std::find(vertex_->labels.begin(), vertex_->labels.end(), label) != vertex_->labels.end()) return Result{false}; @@ -66,6 +89,8 @@ class VertexAccessor final { if (!PrepareForWrite(transaction_, vertex_)) return Result{Error::SERIALIZATION_ERROR}; + if (vertex_->deleted) return Result{Error::DELETED_OBJECT}; + auto it = std::find(vertex_->labels.begin(), vertex_->labels.end(), label); if (it == vertex_->labels.end()) return Result{false}; @@ -76,17 +101,19 @@ class VertexAccessor final { return Result{true}; } - bool HasLabel(uint64_t label, View view) { + Result HasLabel(uint64_t label, View view) { + bool deleted = false; bool has_label = false; Delta *delta = nullptr; { std::lock_guard guard(vertex_->lock); + deleted = vertex_->deleted; has_label = std::find(vertex_->labels.begin(), vertex_->labels.end(), label) != vertex_->labels.end(); delta = vertex_->delta; } ApplyDeltasForRead(transaction_, delta, view, - [&has_label, label](const Delta &delta) { + [&deleted, &has_label, label](const Delta &delta) { switch (delta.action) { case Delta::Action::REMOVE_LABEL: { if (delta.value == label) { @@ -106,21 +133,28 @@ class VertexAccessor final { LOG(FATAL) << "Invalid accessor!"; break; } + case Delta::Action::RECREATE_OBJECT: { + deleted = false; + break; + } } }); - return has_label; + if (deleted) return Result{Error::DELETED_OBJECT}; + return Result{has_label}; } - std::vector Labels(View view) { + Result> Labels(View view) { + bool deleted = false; std::vector labels; Delta *delta = nullptr; { std::lock_guard guard(vertex_->lock); + deleted = vertex_->deleted; labels = vertex_->labels; delta = vertex_->delta; } ApplyDeltasForRead( - transaction_, delta, view, [&labels](const Delta &delta) { + transaction_, delta, view, [&deleted, &labels](const Delta &delta) { switch (delta.action) { case Delta::Action::REMOVE_LABEL: { // Remove the label because we don't see the addition. @@ -141,9 +175,14 @@ class VertexAccessor final { LOG(FATAL) << "Invalid accessor!"; break; } + case Delta::Action::RECREATE_OBJECT: { + deleted = false; + break; + } } }); - return labels; + if (deleted) return Result>{Error::DELETED_OBJECT}; + return Result>{std::move(labels)}; } Gid Gid() const { return vertex_->gid; } diff --git a/tests/unit/storage_v2.cpp b/tests/unit/storage_v2.cpp index 602251efa..3d5d5315f 100644 --- a/tests/unit/storage_v2.cpp +++ b/tests/unit/storage_v2.cpp @@ -23,6 +23,22 @@ TEST(StorageV2, Commit) { ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); acc.Abort(); } + { + auto acc = store.Access(); + auto vertex = acc.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + auto res = vertex->Delete(); + ASSERT_FALSE(res.IsError()); + + acc.Commit(); + } + { + auto acc = store.Access(); + ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc.FindVertex(gid, storage::View::NEW).has_value()); + acc.Abort(); + } } // NOLINTNEXTLINE(hicpp-special-member-functions) @@ -174,6 +190,412 @@ TEST(StorageV2, AccessorMove) { } } +// NOLINTNEXTLINE(hicpp-special-member-functions) +TEST(StorageV2, VertexDeleteCommit) { + storage::Storage store; + storage::Gid gid = + storage::Gid::FromUint(std::numeric_limits::max()); + + auto acc1 = store.Access(); // read transaction + auto acc2 = store.Access(); // write transaction + + // Create the vertex in transaction 2 + { + auto vertex = acc2.CreateVertex(); + gid = vertex.Gid(); + ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + acc2.Commit(); + } + + auto acc3 = store.Access(); // read transaction + auto acc4 = store.Access(); // write transaction + + // Check whether the vertex exists in transaction 1 + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 3 + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + + // Delete the vertex in transaction 4 + { + auto vertex = acc4.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsReturn()); + + acc4.Commit(); + } + + auto acc5 = store.Access(); // read transaction + + // Check whether the vertex exists in transaction 1 + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 3 + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 5 + ASSERT_FALSE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc5.FindVertex(gid, storage::View::NEW).has_value()); +} + +// NOLINTNEXTLINE(hicpp-special-member-functions) +TEST(StorageV2, VertexDeleteAbort) { + storage::Storage store; + storage::Gid gid = + storage::Gid::FromUint(std::numeric_limits::max()); + + auto acc1 = store.Access(); // read transaction + auto acc2 = store.Access(); // write transaction + + // Create the vertex in transaction 2 + { + auto vertex = acc2.CreateVertex(); + gid = vertex.Gid(); + ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + acc2.Commit(); + } + + auto acc3 = store.Access(); // read transaction + auto acc4 = store.Access(); // write transaction (aborted) + + // Check whether the vertex exists in transaction 1 + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 3 + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + + // Delete the vertex in transaction 4, but abort the transaction + { + auto vertex = acc4.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsReturn()); + + acc4.Abort(); + } + + auto acc5 = store.Access(); // read transaction + auto acc6 = store.Access(); // write transaction + + // Check whether the vertex exists in transaction 1 + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 3 + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 5 + ASSERT_TRUE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc5.FindVertex(gid, storage::View::NEW).has_value()); + + // Delete the vertex in transaction 6 + { + auto vertex = acc6.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsReturn()); + + acc6.Commit(); + } + + auto acc7 = store.Access(); // read transaction + + // Check whether the vertex exists in transaction 1 + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 3 + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 5 + ASSERT_TRUE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc5.FindVertex(gid, storage::View::NEW).has_value()); + + // Check whether the vertex exists in transaction 7 + ASSERT_FALSE(acc7.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_FALSE(acc7.FindVertex(gid, storage::View::NEW).has_value()); + + // Commit all accessors + acc1.Commit(); + acc3.Commit(); + acc5.Commit(); + acc7.Commit(); +} + +// NOLINTNEXTLINE(hicpp-special-member-functions) +TEST(StorageV2, VertexDeleteSerializationError) { + storage::Storage store; + storage::Gid gid = + storage::Gid::FromUint(std::numeric_limits::max()); + + // Create vertex + { + auto acc = store.Access(); + auto vertex = acc.CreateVertex(); + gid = vertex.Gid(); + acc.Commit(); + } + + auto acc1 = store.Access(); + auto acc2 = store.Access(); + + // Delete vertex in accessor 1 + { + auto vertex = acc1.FindVertex(gid, storage::View::OLD); + ASSERT_TRUE(vertex); + + { + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsReturn()); + ASSERT_TRUE(res.GetReturn()); + } + + { + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsReturn()); + ASSERT_FALSE(res.GetReturn()); + } + } + + // Delete vertex in accessor 2 + { + auto vertex = acc2.FindVertex(gid, storage::View::OLD); + ASSERT_TRUE(vertex); + auto res = vertex->Delete(); + ASSERT_TRUE(res.IsError()); + ASSERT_EQ(res.GetError(), storage::Error::SERIALIZATION_ERROR); + } + + // Finalize both accessors + acc1.Commit(); + acc2.Abort(); + + // Check whether the vertex exists + { + auto acc = store.Access(); + auto vertex = acc.FindVertex(gid, storage::View::OLD); + ASSERT_FALSE(vertex); + acc.Commit(); + } +} + +// NOLINTNEXTLINE(hicpp-special-member-functions) +TEST(StorageV2, VertexDeleteSpecialCases) { + storage::Storage store; + storage::Gid gid1 = + storage::Gid::FromUint(std::numeric_limits::max()); + storage::Gid gid2 = + storage::Gid::FromUint(std::numeric_limits::max()); + + // Create vertex and delete it in the same transaction, but abort the + // transaction + { + auto acc = store.Access(); + auto vertex = acc.CreateVertex(); + gid1 = vertex.Gid(); + ASSERT_FALSE(acc.FindVertex(gid1, storage::View::OLD).has_value()); + ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); + auto res = vertex.Delete(); + ASSERT_TRUE(res.IsReturn()); + ASSERT_TRUE(res.GetReturn()); + acc.Abort(); + } + + // Create vertex and delete it in the same transaction + { + auto acc = store.Access(); + auto vertex = acc.CreateVertex(); + gid2 = vertex.Gid(); + ASSERT_FALSE(acc.FindVertex(gid2, storage::View::OLD).has_value()); + ASSERT_TRUE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + auto res = vertex.Delete(); + ASSERT_TRUE(res.IsReturn()); + ASSERT_TRUE(res.GetReturn()); + acc.Commit(); + } + + // Check whether the vertices exist + { + auto acc = store.Access(); + ASSERT_FALSE(acc.FindVertex(gid1, storage::View::OLD).has_value()); + ASSERT_FALSE(acc.FindVertex(gid1, storage::View::NEW).has_value()); + ASSERT_FALSE(acc.FindVertex(gid2, storage::View::OLD).has_value()); + ASSERT_FALSE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + acc.Abort(); + } +} + +// NOLINTNEXTLINE(hicpp-special-member-functions) +TEST(StorageV2, VertexDeleteLabel) { + storage::Storage store; + storage::Gid gid = + storage::Gid::FromUint(std::numeric_limits::max()); + + // Create the vertex + { + auto acc = store.Access(); + auto vertex = acc.CreateVertex(); + gid = vertex.Gid(); + ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + acc.Commit(); + } + + // Add label, delete the vertex and check the label API (same command) + { + auto acc = store.Access(); + auto vertex = acc.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + // Check whether label 5 exists + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); + + // Add label 5 + ASSERT_TRUE(vertex->AddLabel(5).GetReturn()); + + // Check whether label 5 exists + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + { + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); + ASSERT_EQ(labels.size(), 1); + ASSERT_EQ(labels[0], 5); + } + + // Delete the vertex + ASSERT_TRUE(vertex->Delete().GetReturn()); + + // Check whether label 5 exists + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_EQ(vertex->HasLabel(5, storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + + // Try to add the label + { + auto ret = vertex->AddLabel(5); + ASSERT_TRUE(ret.IsError()); + ASSERT_EQ(ret.GetError(), storage::Error::DELETED_OBJECT); + } + + // Try to remove the label + { + auto ret = vertex->RemoveLabel(5); + ASSERT_TRUE(ret.IsError()); + ASSERT_EQ(ret.GetError(), storage::Error::DELETED_OBJECT); + } + + acc.Abort(); + } + + // Add label, delete the vertex and check the label API (different command) + { + auto acc = store.Access(); + auto vertex = acc.FindVertex(gid, storage::View::NEW); + ASSERT_TRUE(vertex); + + // Check whether label 5 exists + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); + + // Add label 5 + ASSERT_TRUE(vertex->AddLabel(5).GetReturn()); + + // Check whether label 5 exists + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + { + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); + ASSERT_EQ(labels.size(), 1); + ASSERT_EQ(labels[0], 5); + } + + // Advance command + acc.AdvanceCommand(); + + // Check whether label 5 exists + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + { + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); + ASSERT_EQ(labels.size(), 1); + ASSERT_EQ(labels[0], 5); + } + { + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); + ASSERT_EQ(labels.size(), 1); + ASSERT_EQ(labels[0], 5); + } + + // Delete the vertex + ASSERT_TRUE(vertex->Delete().GetReturn()); + + // Check whether label 5 exists + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_EQ(vertex->HasLabel(5, storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + { + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); + ASSERT_EQ(labels.size(), 1); + ASSERT_EQ(labels[0], 5); + } + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + + // Advance command + acc.AdvanceCommand(); + + // Check whether label 5 exists + ASSERT_EQ(vertex->HasLabel(5, storage::View::OLD).GetError(), + storage::Error::DELETED_OBJECT); + ASSERT_EQ(vertex->HasLabel(5, storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetError(), + storage::Error::DELETED_OBJECT); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetError(), + storage::Error::DELETED_OBJECT); + + // Try to add the label + { + auto ret = vertex->AddLabel(5); + ASSERT_TRUE(ret.IsError()); + ASSERT_EQ(ret.GetError(), storage::Error::DELETED_OBJECT); + } + + // Try to remove the label + { + auto ret = vertex->RemoveLabel(5); + ASSERT_TRUE(ret.IsError()); + ASSERT_EQ(ret.GetError(), storage::Error::DELETED_OBJECT); + } + + acc.Abort(); + } +} + // NOLINTNEXTLINE(hicpp-special-member-functions) TEST(StorageV2, VertexLabelCommit) { storage::Storage store; @@ -184,18 +606,18 @@ TEST(StorageV2, VertexLabelCommit) { auto vertex = acc.CreateVertex(); gid = vertex.Gid(); - ASSERT_FALSE(vertex.HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex.Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex.HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex.Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex.AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex.HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex.HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex.Labels(storage::View::NEW); + auto labels = vertex.Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } @@ -203,7 +625,7 @@ TEST(StorageV2, VertexLabelCommit) { { auto res = vertex.AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Commit(); @@ -213,22 +635,22 @@ TEST(StorageV2, VertexLabelCommit) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -240,23 +662,23 @@ TEST(StorageV2, VertexLabelCommit) { { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Commit(); @@ -266,13 +688,13 @@ TEST(StorageV2, VertexLabelCommit) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -298,18 +720,18 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } @@ -317,7 +739,7 @@ TEST(StorageV2, VertexLabelAbort) { { auto res = vertex->AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Abort(); @@ -329,13 +751,13 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -346,18 +768,18 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } @@ -365,7 +787,7 @@ TEST(StorageV2, VertexLabelAbort) { { auto res = vertex->AddLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Commit(); @@ -377,22 +799,22 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -406,23 +828,23 @@ TEST(StorageV2, VertexLabelAbort) { { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Abort(); @@ -434,22 +856,22 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -463,23 +885,23 @@ TEST(StorageV2, VertexLabelAbort) { { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 5); } - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->RemoveLabel(5); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } acc.Commit(); @@ -491,13 +913,13 @@ TEST(StorageV2, VertexLabelAbort) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW)); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn()); acc.Abort(); } @@ -523,26 +945,26 @@ TEST(StorageV2, VertexLabelSerializationError) { auto vertex = acc1.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->AddLabel(1); ASSERT_TRUE(res.IsReturn()); - ASSERT_TRUE(*res.GetReturn()); + ASSERT_TRUE(res.GetReturn()); } - ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD)); - ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); + ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn()); + ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 1); } @@ -550,7 +972,7 @@ TEST(StorageV2, VertexLabelSerializationError) { { auto res = vertex->AddLabel(1); ASSERT_TRUE(res.IsReturn()); - ASSERT_FALSE(*res.GetReturn()); + ASSERT_FALSE(res.GetReturn()); } } @@ -559,12 +981,12 @@ TEST(StorageV2, VertexLabelSerializationError) { auto vertex = acc2.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW)); - ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0); - ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0); + ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn()); + ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0); + ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0); { auto res = vertex->AddLabel(1); @@ -583,18 +1005,18 @@ TEST(StorageV2, VertexLabelSerializationError) { auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); - ASSERT_TRUE(vertex->HasLabel(1, storage::View::OLD)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD)); + ASSERT_TRUE(vertex->HasLabel(1, storage::View::OLD).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn()); { - auto labels = vertex->Labels(storage::View::OLD); + auto labels = vertex->Labels(storage::View::OLD).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 1); } - ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW)); - ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW)); + ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW).GetReturn()); + ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn()); { - auto labels = vertex->Labels(storage::View::NEW); + auto labels = vertex->Labels(storage::View::NEW).GetReturn(); ASSERT_EQ(labels.size(), 1); ASSERT_EQ(labels[0], 1); }