Implement vertex deletion in storage v2
Reviewers: mtomic, teon.banek Reviewed By: mtomic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2157
This commit is contained in:
parent
9e649794fc
commit
83a99aaf7d
@ -7,6 +7,7 @@ namespace storage {
|
|||||||
struct Delta {
|
struct Delta {
|
||||||
enum class Action {
|
enum class Action {
|
||||||
DELETE_OBJECT,
|
DELETE_OBJECT,
|
||||||
|
RECREATE_OBJECT,
|
||||||
ADD_LABEL,
|
ADD_LABEL,
|
||||||
REMOVE_LABEL,
|
REMOVE_LABEL,
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ namespace storage {
|
|||||||
|
|
||||||
enum class Error : uint8_t {
|
enum class Error : uint8_t {
|
||||||
SERIALIZATION_ERROR,
|
SERIALIZATION_ERROR,
|
||||||
|
DELETED_OBJECT,
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TReturn>
|
template <typename TReturn>
|
||||||
@ -20,14 +21,14 @@ class Result final {
|
|||||||
bool IsReturn() const { return return_.has_value(); }
|
bool IsReturn() const { return return_.has_value(); }
|
||||||
bool IsError() const { return error_.has_value(); }
|
bool IsError() const { return error_.has_value(); }
|
||||||
|
|
||||||
TReturn *GetReturn() {
|
TReturn &GetReturn() {
|
||||||
CHECK(return_) << "The storage result is an error!";
|
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!";
|
CHECK(return_) << "The storage result is an error!";
|
||||||
return &*return_;
|
return return_.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
Error GetError() const {
|
Error GetError() const {
|
||||||
|
@ -146,6 +146,10 @@ class Storage final {
|
|||||||
CHECK(acc.remove(vertex->gid)) << "Invalid database state!";
|
CHECK(acc.remove(vertex->gid)) << "Invalid database state!";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Delta::Action::RECREATE_OBJECT: {
|
||||||
|
vertex->deleted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
current = current->next.load(std::memory_order_acquire);
|
current = current->next.load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
namespace storage {
|
namespace storage {
|
||||||
|
|
||||||
struct Vertex {
|
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)
|
CHECK(delta->action == Delta::Action::DELETE_OBJECT)
|
||||||
<< "Vertex must be created with an initial DELETE_OBJECT delta!";
|
<< "Vertex must be created with an initial DELETE_OBJECT delta!";
|
||||||
}
|
}
|
||||||
@ -24,7 +24,9 @@ struct Vertex {
|
|||||||
// std::unordered_map<uint64_t, storage::PropertyValue> properties;
|
// std::unordered_map<uint64_t, storage::PropertyValue> properties;
|
||||||
|
|
||||||
utils::SpinLock lock;
|
utils::SpinLock lock;
|
||||||
// uint32_t PAD;
|
bool deleted;
|
||||||
|
// uint8_t PAD;
|
||||||
|
// uint16_t PAD;
|
||||||
|
|
||||||
Delta *delta;
|
Delta *delta;
|
||||||
};
|
};
|
||||||
|
@ -21,18 +21,23 @@ class VertexAccessor final {
|
|||||||
static std::optional<VertexAccessor> Create(Vertex *vertex,
|
static std::optional<VertexAccessor> Create(Vertex *vertex,
|
||||||
Transaction *transaction,
|
Transaction *transaction,
|
||||||
View view) {
|
View view) {
|
||||||
|
bool is_visible = true;
|
||||||
Delta *delta = nullptr;
|
Delta *delta = nullptr;
|
||||||
{
|
{
|
||||||
std::lock_guard<utils::SpinLock> guard(vertex->lock);
|
std::lock_guard<utils::SpinLock> guard(vertex->lock);
|
||||||
|
is_visible = !vertex->deleted;
|
||||||
delta = vertex->delta;
|
delta = vertex->delta;
|
||||||
}
|
}
|
||||||
bool is_visible = true;
|
|
||||||
ApplyDeltasForRead(transaction, delta, view,
|
ApplyDeltasForRead(transaction, delta, view,
|
||||||
[&is_visible](const Delta &delta) {
|
[&is_visible](const Delta &delta) {
|
||||||
switch (delta.action) {
|
switch (delta.action) {
|
||||||
case Delta::Action::ADD_LABEL:
|
case Delta::Action::ADD_LABEL:
|
||||||
case Delta::Action::REMOVE_LABEL:
|
case Delta::Action::REMOVE_LABEL:
|
||||||
break;
|
break;
|
||||||
|
case Delta::Action::RECREATE_OBJECT: {
|
||||||
|
is_visible = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Delta::Action::DELETE_OBJECT: {
|
case Delta::Action::DELETE_OBJECT: {
|
||||||
is_visible = false;
|
is_visible = false;
|
||||||
break;
|
break;
|
||||||
@ -43,12 +48,30 @@ class VertexAccessor final {
|
|||||||
return VertexAccessor{vertex, transaction};
|
return VertexAccessor{vertex, transaction};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<bool> Delete() {
|
||||||
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
|
||||||
|
if (!PrepareForWrite(transaction_, vertex_))
|
||||||
|
return Result<bool>{Error::SERIALIZATION_ERROR};
|
||||||
|
|
||||||
|
if (vertex_->deleted) return Result<bool>{false};
|
||||||
|
|
||||||
|
CreateAndLinkDelta(transaction_, vertex_, Delta::Action::RECREATE_OBJECT,
|
||||||
|
0);
|
||||||
|
|
||||||
|
vertex_->deleted = true;
|
||||||
|
|
||||||
|
return Result<bool>{true};
|
||||||
|
}
|
||||||
|
|
||||||
Result<bool> AddLabel(uint64_t label) {
|
Result<bool> AddLabel(uint64_t label) {
|
||||||
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
|
||||||
if (!PrepareForWrite(transaction_, vertex_))
|
if (!PrepareForWrite(transaction_, vertex_))
|
||||||
return Result<bool>{Error::SERIALIZATION_ERROR};
|
return Result<bool>{Error::SERIALIZATION_ERROR};
|
||||||
|
|
||||||
|
if (vertex_->deleted) return Result<bool>{Error::DELETED_OBJECT};
|
||||||
|
|
||||||
if (std::find(vertex_->labels.begin(), vertex_->labels.end(), label) !=
|
if (std::find(vertex_->labels.begin(), vertex_->labels.end(), label) !=
|
||||||
vertex_->labels.end())
|
vertex_->labels.end())
|
||||||
return Result<bool>{false};
|
return Result<bool>{false};
|
||||||
@ -66,6 +89,8 @@ class VertexAccessor final {
|
|||||||
if (!PrepareForWrite(transaction_, vertex_))
|
if (!PrepareForWrite(transaction_, vertex_))
|
||||||
return Result<bool>{Error::SERIALIZATION_ERROR};
|
return Result<bool>{Error::SERIALIZATION_ERROR};
|
||||||
|
|
||||||
|
if (vertex_->deleted) return Result<bool>{Error::DELETED_OBJECT};
|
||||||
|
|
||||||
auto it = std::find(vertex_->labels.begin(), vertex_->labels.end(), label);
|
auto it = std::find(vertex_->labels.begin(), vertex_->labels.end(), label);
|
||||||
if (it == vertex_->labels.end()) return Result<bool>{false};
|
if (it == vertex_->labels.end()) return Result<bool>{false};
|
||||||
|
|
||||||
@ -76,17 +101,19 @@ class VertexAccessor final {
|
|||||||
return Result<bool>{true};
|
return Result<bool>{true};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasLabel(uint64_t label, View view) {
|
Result<bool> HasLabel(uint64_t label, View view) {
|
||||||
|
bool deleted = false;
|
||||||
bool has_label = false;
|
bool has_label = false;
|
||||||
Delta *delta = nullptr;
|
Delta *delta = nullptr;
|
||||||
{
|
{
|
||||||
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
deleted = vertex_->deleted;
|
||||||
has_label = std::find(vertex_->labels.begin(), vertex_->labels.end(),
|
has_label = std::find(vertex_->labels.begin(), vertex_->labels.end(),
|
||||||
label) != vertex_->labels.end();
|
label) != vertex_->labels.end();
|
||||||
delta = vertex_->delta;
|
delta = vertex_->delta;
|
||||||
}
|
}
|
||||||
ApplyDeltasForRead(transaction_, delta, view,
|
ApplyDeltasForRead(transaction_, delta, view,
|
||||||
[&has_label, label](const Delta &delta) {
|
[&deleted, &has_label, label](const Delta &delta) {
|
||||||
switch (delta.action) {
|
switch (delta.action) {
|
||||||
case Delta::Action::REMOVE_LABEL: {
|
case Delta::Action::REMOVE_LABEL: {
|
||||||
if (delta.value == label) {
|
if (delta.value == label) {
|
||||||
@ -106,21 +133,28 @@ class VertexAccessor final {
|
|||||||
LOG(FATAL) << "Invalid accessor!";
|
LOG(FATAL) << "Invalid accessor!";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Delta::Action::RECREATE_OBJECT: {
|
||||||
|
deleted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return has_label;
|
if (deleted) return Result<bool>{Error::DELETED_OBJECT};
|
||||||
|
return Result<bool>{has_label};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint64_t> Labels(View view) {
|
Result<std::vector<uint64_t>> Labels(View view) {
|
||||||
|
bool deleted = false;
|
||||||
std::vector<uint64_t> labels;
|
std::vector<uint64_t> labels;
|
||||||
Delta *delta = nullptr;
|
Delta *delta = nullptr;
|
||||||
{
|
{
|
||||||
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
|
||||||
|
deleted = vertex_->deleted;
|
||||||
labels = vertex_->labels;
|
labels = vertex_->labels;
|
||||||
delta = vertex_->delta;
|
delta = vertex_->delta;
|
||||||
}
|
}
|
||||||
ApplyDeltasForRead(
|
ApplyDeltasForRead(
|
||||||
transaction_, delta, view, [&labels](const Delta &delta) {
|
transaction_, delta, view, [&deleted, &labels](const Delta &delta) {
|
||||||
switch (delta.action) {
|
switch (delta.action) {
|
||||||
case Delta::Action::REMOVE_LABEL: {
|
case Delta::Action::REMOVE_LABEL: {
|
||||||
// Remove the label because we don't see the addition.
|
// Remove the label because we don't see the addition.
|
||||||
@ -141,9 +175,14 @@ class VertexAccessor final {
|
|||||||
LOG(FATAL) << "Invalid accessor!";
|
LOG(FATAL) << "Invalid accessor!";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Delta::Action::RECREATE_OBJECT: {
|
||||||
|
deleted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return labels;
|
if (deleted) return Result<std::vector<uint64_t>>{Error::DELETED_OBJECT};
|
||||||
|
return Result<std::vector<uint64_t>>{std::move(labels)};
|
||||||
}
|
}
|
||||||
|
|
||||||
Gid Gid() const { return vertex_->gid; }
|
Gid Gid() const { return vertex_->gid; }
|
||||||
|
@ -23,6 +23,22 @@ TEST(StorageV2, Commit) {
|
|||||||
ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value());
|
ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value());
|
||||||
acc.Abort();
|
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)
|
// 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<uint64_t>::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<uint64_t>::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<uint64_t>::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<uint64_t>::max());
|
||||||
|
storage::Gid gid2 =
|
||||||
|
storage::Gid::FromUint(std::numeric_limits<uint64_t>::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<uint64_t>::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)
|
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||||
TEST(StorageV2, VertexLabelCommit) {
|
TEST(StorageV2, VertexLabelCommit) {
|
||||||
storage::Storage store;
|
storage::Storage store;
|
||||||
@ -184,18 +606,18 @@ TEST(StorageV2, VertexLabelCommit) {
|
|||||||
auto vertex = acc.CreateVertex();
|
auto vertex = acc.CreateVertex();
|
||||||
gid = vertex.Gid();
|
gid = vertex.Gid();
|
||||||
|
|
||||||
ASSERT_FALSE(vertex.HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex.HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex.Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex.Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex.AddLabel(5);
|
auto res = vertex.AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
@ -203,7 +625,7 @@ TEST(StorageV2, VertexLabelCommit) {
|
|||||||
{
|
{
|
||||||
auto res = vertex.AddLabel(5);
|
auto res = vertex.AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Commit();
|
acc.Commit();
|
||||||
@ -213,22 +635,22 @@ TEST(StorageV2, VertexLabelCommit) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -240,23 +662,23 @@ TEST(StorageV2, VertexLabelCommit) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Commit();
|
acc.Commit();
|
||||||
@ -266,13 +688,13 @@ TEST(StorageV2, VertexLabelCommit) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0);
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).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::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -298,18 +720,18 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(5);
|
auto res = vertex->AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
@ -317,7 +739,7 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(5);
|
auto res = vertex->AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
@ -329,13 +751,13 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0);
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).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::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -346,18 +768,18 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(5);
|
auto res = vertex->AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
@ -365,7 +787,7 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(5);
|
auto res = vertex->AddLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Commit();
|
acc.Commit();
|
||||||
@ -377,22 +799,22 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -406,23 +828,23 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
@ -434,22 +856,22 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -463,23 +885,23 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 5);
|
ASSERT_EQ(labels[0], 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->RemoveLabel(5);
|
auto res = vertex->RemoveLabel(5);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_FALSE(*res.GetReturn());
|
ASSERT_FALSE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.Commit();
|
acc.Commit();
|
||||||
@ -491,13 +913,13 @@ TEST(StorageV2, VertexLabelAbort) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(5, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0);
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).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::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(10, storage::View::NEW).GetReturn());
|
||||||
|
|
||||||
acc.Abort();
|
acc.Abort();
|
||||||
}
|
}
|
||||||
@ -523,26 +945,26 @@ TEST(StorageV2, VertexLabelSerializationError) {
|
|||||||
auto vertex = acc1.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc1.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0);
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(1);
|
auto res = vertex->AddLabel(1);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
ASSERT_TRUE(res.IsReturn());
|
||||||
ASSERT_TRUE(*res.GetReturn());
|
ASSERT_TRUE(res.GetReturn());
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn());
|
||||||
ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW));
|
ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 1);
|
ASSERT_EQ(labels[0], 1);
|
||||||
}
|
}
|
||||||
@ -550,7 +972,7 @@ TEST(StorageV2, VertexLabelSerializationError) {
|
|||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(1);
|
auto res = vertex->AddLabel(1);
|
||||||
ASSERT_TRUE(res.IsReturn());
|
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);
|
auto vertex = acc2.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(1, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(1, storage::View::NEW).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW));
|
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW).GetReturn());
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::OLD).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::OLD).GetReturn().size(), 0);
|
||||||
ASSERT_EQ(vertex->Labels(storage::View::NEW).size(), 0);
|
ASSERT_EQ(vertex->Labels(storage::View::NEW).GetReturn().size(), 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = vertex->AddLabel(1);
|
auto res = vertex->AddLabel(1);
|
||||||
@ -583,18 +1005,18 @@ TEST(StorageV2, VertexLabelSerializationError) {
|
|||||||
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
auto vertex = acc.FindVertex(gid, storage::View::OLD);
|
||||||
ASSERT_TRUE(vertex);
|
ASSERT_TRUE(vertex);
|
||||||
|
|
||||||
ASSERT_TRUE(vertex->HasLabel(1, storage::View::OLD));
|
ASSERT_TRUE(vertex->HasLabel(1, storage::View::OLD).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::OLD));
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 1);
|
ASSERT_EQ(labels[0], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW));
|
ASSERT_TRUE(vertex->HasLabel(1, storage::View::NEW).GetReturn());
|
||||||
ASSERT_FALSE(vertex->HasLabel(2, storage::View::NEW));
|
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.size(), 1);
|
||||||
ASSERT_EQ(labels[0], 1);
|
ASSERT_EQ(labels[0], 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user