From 867f30d9b315a0f0e6415679fe526faeaf319bff Mon Sep 17 00:00:00 2001 From: Teon Banek Date: Mon, 22 Jul 2019 16:05:44 +0200 Subject: [PATCH] Add VerticesIterable to storage/v2 Reviewers: mtomic, mferencevic Reviewed By: mtomic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2229 --- src/storage/v2/storage.cpp | 35 ++++++++++++ src/storage/v2/storage.hpp | 39 +++++++++++++ tests/unit/storage_v2.cpp | 112 +++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) diff --git a/src/storage/v2/storage.cpp b/src/storage/v2/storage.cpp index 2d37297b8..81a505ac8 100644 --- a/src/storage/v2/storage.cpp +++ b/src/storage/v2/storage.cpp @@ -8,6 +8,41 @@ namespace storage { +namespace { + +auto AdvanceToVisibleVertex(utils::SkipList::Iterator it, + utils::SkipList::Iterator end, + Transaction *tx, View view) { + while (it != end) { + auto maybe_vertex = VertexAccessor::Create(&*it, tx, view); + if (!maybe_vertex) { + ++it; + continue; + } + break; + } + return it; +} + +} // namespace + +VerticesIterable::Iterator::Iterator(VerticesIterable *self, + utils::SkipList::Iterator it) + : self_(self), + it_(AdvanceToVisibleVertex(it, self->vertices_accessor_.end(), + self->transaction_, self->view_)) {} + +VertexAccessor VerticesIterable::Iterator::operator*() const { + return *VertexAccessor::Create(&*it_, self_->transaction_, self_->view_); +} + +VerticesIterable::Iterator &VerticesIterable::Iterator::operator++() { + ++it_; + it_ = AdvanceToVisibleVertex(it_, self_->vertices_accessor_.end(), + self_->transaction_, self_->view_); + return *this; +} + Storage::Storage(StorageGcConfig gc_config) : gc_config_(gc_config) { if (gc_config.type == StorageGcConfig::Type::PERIODIC) { gc_runner_.Run("Storage GC", gc_config.interval, diff --git a/src/storage/v2/storage.hpp b/src/storage/v2/storage.hpp index a33422130..a4f96ac9e 100644 --- a/src/storage/v2/storage.hpp +++ b/src/storage/v2/storage.hpp @@ -46,6 +46,40 @@ inline static constexpr StorageGcConfig DefaultGcConfig = { .type = StorageGcConfig::Type::PERIODIC, .interval = std::chrono::milliseconds(1000)}; +class VerticesIterable final { + utils::SkipList::Accessor vertices_accessor_; + Transaction *transaction_; + View view_; + + class Iterator final { + VerticesIterable *self_; + utils::SkipList::Iterator it_; + + public: + Iterator(VerticesIterable *self, utils::SkipList::Iterator it); + + VertexAccessor operator*() const; + + Iterator &operator++(); + + bool operator==(const Iterator &other) const { + return self_ == other.self_ && it_ == other.it_; + } + + bool operator!=(const Iterator &other) const { return !(*this == other); } + }; + + public: + VerticesIterable(utils::SkipList::Accessor vertices_accessor, + Transaction *transaction, View view) + : vertices_accessor_(std::move(vertices_accessor)), + transaction_(transaction), + view_(view) {} + + Iterator begin() { return Iterator(this, vertices_accessor_.begin()); } + Iterator end() { return Iterator(this, vertices_accessor_.end()); } +}; + class Storage final { public: explicit Storage(StorageGcConfig gc_config = DefaultGcConfig); @@ -74,6 +108,11 @@ class Storage final { std::optional FindVertex(Gid gid, View view); + VerticesIterable Vertices(View view) { + return VerticesIterable(storage_->vertices_.access(), &transaction_, + view); + } + Result DeleteVertex(VertexAccessor *vertex); Result DetachDeleteVertex(VertexAccessor *vertex); diff --git a/tests/unit/storage_v2.cpp b/tests/unit/storage_v2.cpp index c2aa638e4..c0bc69c1e 100644 --- a/tests/unit/storage_v2.cpp +++ b/tests/unit/storage_v2.cpp @@ -4,6 +4,14 @@ #include "storage/v2/storage.hpp" +size_t CountVertices(storage::Storage::Accessor *storage_accessor, + storage::View view) { + auto vertices = storage_accessor->Vertices(view); + size_t count = 0U; + for (auto it = vertices.begin(); it != vertices.end(); ++it) ++count; + return count; +} + // NOLINTNEXTLINE(hicpp-special-member-functions) TEST(StorageV2, Commit) { storage::Storage store; @@ -14,13 +22,17 @@ TEST(StorageV2, Commit) { auto vertex = acc.CreateVertex(); gid = vertex.Gid(); ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.Commit(); } { auto acc = store.Access(); ASSERT_TRUE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U); ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.Abort(); } { @@ -30,13 +42,17 @@ TEST(StorageV2, Commit) { auto res = acc.DeleteVertex(&*vertex); ASSERT_FALSE(res.HasError()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Commit(); } { auto acc = store.Access(); ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_FALSE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Abort(); } } @@ -51,13 +67,17 @@ TEST(StorageV2, Abort) { auto vertex = acc.CreateVertex(); gid = vertex.Gid(); ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.Abort(); } { auto acc = store.Access(); ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_FALSE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Abort(); } } @@ -75,14 +95,18 @@ TEST(StorageV2, AdvanceCommandCommit) { auto vertex1 = acc.CreateVertex(); gid1 = vertex1.Gid(); ASSERT_FALSE(acc.FindVertex(gid1, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.AdvanceCommand(); auto vertex2 = acc.CreateVertex(); gid2 = vertex2.Gid(); ASSERT_FALSE(acc.FindVertex(gid2, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U); ASSERT_TRUE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 2U); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::OLD).has_value()); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); @@ -95,6 +119,8 @@ TEST(StorageV2, AdvanceCommandCommit) { ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); ASSERT_TRUE(acc.FindVertex(gid2, storage::View::OLD).has_value()); ASSERT_TRUE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 2U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 2U); acc.Abort(); } } @@ -112,14 +138,18 @@ TEST(StorageV2, AdvanceCommandAbort) { auto vertex1 = acc.CreateVertex(); gid1 = vertex1.Gid(); ASSERT_FALSE(acc.FindVertex(gid1, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.AdvanceCommand(); auto vertex2 = acc.CreateVertex(); gid2 = vertex2.Gid(); ASSERT_FALSE(acc.FindVertex(gid2, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U); ASSERT_TRUE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 2U); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::OLD).has_value()); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); @@ -132,6 +162,8 @@ TEST(StorageV2, AdvanceCommandAbort) { 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()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Abort(); } } @@ -147,18 +179,26 @@ TEST(StorageV2, SnapshotIsolation) { auto gid = vertex.Gid(); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 1U); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 0U); acc1.Commit(); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 0U); acc2.Abort(); auto acc3 = store.Access(); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); acc3.Abort(); } @@ -173,19 +213,25 @@ TEST(StorageV2, AccessorMove) { gid = vertex.Gid(); ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); storage::Storage::Accessor moved(std::move(acc)); ASSERT_FALSE(moved.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&moved, storage::View::OLD), 0U); ASSERT_TRUE(moved.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&moved, storage::View::NEW), 1U); moved.Commit(); } { auto acc = store.Access(); ASSERT_TRUE(acc.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U); ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); acc.Abort(); } } @@ -204,7 +250,9 @@ TEST(StorageV2, VertexDeleteCommit) { auto vertex = acc2.CreateVertex(); gid = vertex.Gid(); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U); ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U); acc2.Commit(); } @@ -213,19 +261,27 @@ TEST(StorageV2, VertexDeleteCommit) { // Check whether the vertex exists in transaction 1 ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); // Check whether the vertex exists in transaction 3 ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); // Delete the vertex in transaction 4 { auto vertex = acc4.FindVertex(gid, storage::View::NEW); ASSERT_TRUE(vertex); + EXPECT_EQ(CountVertices(&acc4, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc4, storage::View::NEW), 1U); auto res = acc4.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasValue()); + EXPECT_EQ(CountVertices(&acc4, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc4, storage::View::NEW), 0U); acc4.Commit(); } @@ -234,15 +290,21 @@ TEST(StorageV2, VertexDeleteCommit) { // Check whether the vertex exists in transaction 1 ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); // Check whether the vertex exists in transaction 3 ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); // Check whether the vertex exists in transaction 5 ASSERT_FALSE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::OLD), 0U); ASSERT_FALSE(acc5.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::NEW), 0U); } // NOLINTNEXTLINE(hicpp-special-member-functions) @@ -259,7 +321,9 @@ TEST(StorageV2, VertexDeleteAbort) { auto vertex = acc2.CreateVertex(); gid = vertex.Gid(); ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U); ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U); acc2.Commit(); } @@ -268,19 +332,27 @@ TEST(StorageV2, VertexDeleteAbort) { // Check whether the vertex exists in transaction 1 ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); // Check whether the vertex exists in transaction 3 ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); // Delete the vertex in transaction 4, but abort the transaction { auto vertex = acc4.FindVertex(gid, storage::View::NEW); ASSERT_TRUE(vertex); + EXPECT_EQ(CountVertices(&acc4, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc4, storage::View::NEW), 1U); auto res = acc4.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasValue()); + EXPECT_EQ(CountVertices(&acc4, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc4, storage::View::NEW), 0U); acc4.Abort(); } @@ -290,23 +362,33 @@ TEST(StorageV2, VertexDeleteAbort) { // Check whether the vertex exists in transaction 1 ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); // Check whether the vertex exists in transaction 3 ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); // Check whether the vertex exists in transaction 5 ASSERT_TRUE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::OLD), 1U); ASSERT_TRUE(acc5.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::NEW), 1U); // Delete the vertex in transaction 6 { auto vertex = acc6.FindVertex(gid, storage::View::NEW); ASSERT_TRUE(vertex); + EXPECT_EQ(CountVertices(&acc6, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc6, storage::View::NEW), 1U); auto res = acc6.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasValue()); + EXPECT_EQ(CountVertices(&acc6, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc6, storage::View::NEW), 0U); acc6.Commit(); } @@ -315,19 +397,27 @@ TEST(StorageV2, VertexDeleteAbort) { // Check whether the vertex exists in transaction 1 ASSERT_FALSE(acc1.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 0U); ASSERT_FALSE(acc1.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); // Check whether the vertex exists in transaction 3 ASSERT_TRUE(acc3.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::OLD), 1U); ASSERT_TRUE(acc3.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc3, storage::View::NEW), 1U); // Check whether the vertex exists in transaction 5 ASSERT_TRUE(acc5.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::OLD), 1U); ASSERT_TRUE(acc5.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc5, storage::View::NEW), 1U); // Check whether the vertex exists in transaction 7 ASSERT_FALSE(acc7.FindVertex(gid, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc7, storage::View::OLD), 0U); ASSERT_FALSE(acc7.FindVertex(gid, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc7, storage::View::NEW), 0U); // Commit all accessors acc1.Commit(); @@ -357,17 +447,23 @@ TEST(StorageV2, VertexDeleteSerializationError) { { auto vertex = acc1.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 1U); { auto res = acc1.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasValue()); ASSERT_TRUE(res.GetValue()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); } { auto res = acc1.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasValue()); ASSERT_FALSE(res.GetValue()); + EXPECT_EQ(CountVertices(&acc1, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 0U); } } @@ -375,9 +471,13 @@ TEST(StorageV2, VertexDeleteSerializationError) { { auto vertex = acc2.FindVertex(gid, storage::View::OLD); ASSERT_TRUE(vertex); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U); auto res = acc2.DeleteVertex(&*vertex); ASSERT_TRUE(res.HasError()); ASSERT_EQ(res.GetError(), storage::Error::SERIALIZATION_ERROR); + EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 1U); + EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U); } // Finalize both accessors @@ -389,6 +489,8 @@ TEST(StorageV2, VertexDeleteSerializationError) { auto acc = store.Access(); auto vertex = acc.FindVertex(gid, storage::View::OLD); ASSERT_FALSE(vertex); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Commit(); } } @@ -408,10 +510,14 @@ TEST(StorageV2, VertexDeleteSpecialCases) { auto vertex = acc.CreateVertex(); gid1 = vertex.Gid(); ASSERT_FALSE(acc.FindVertex(gid1, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); auto res = acc.DeleteVertex(&vertex); ASSERT_TRUE(res.HasValue()); ASSERT_TRUE(res.GetValue()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Abort(); } @@ -421,10 +527,14 @@ TEST(StorageV2, VertexDeleteSpecialCases) { auto vertex = acc.CreateVertex(); gid2 = vertex.Gid(); ASSERT_FALSE(acc.FindVertex(gid2, storage::View::OLD).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); ASSERT_TRUE(acc.FindVertex(gid2, storage::View::NEW).has_value()); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U); auto res = acc.DeleteVertex(&vertex); ASSERT_TRUE(res.HasValue()); ASSERT_TRUE(res.GetValue()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Commit(); } @@ -435,6 +545,8 @@ TEST(StorageV2, VertexDeleteSpecialCases) { 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()); + EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U); + EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U); acc.Abort(); } }