[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
#include "storage/v2/storage.hpp"
|
|
|
|
|
|
|
|
using testing::UnorderedElementsAre;
|
|
|
|
|
|
|
|
// TODO: We should implement a more sophisticated stress test to verify that GC
|
|
|
|
// is working properly in a multithreaded environment.
|
|
|
|
|
|
|
|
// A simple test trying to get GC to run while a transaction is still alive and
|
|
|
|
// then verify that GC didn't delete anything it shouldn't have.
|
|
|
|
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
|
|
|
TEST(StorageV2Gc, Sanity) {
|
|
|
|
storage::Storage storage(
|
|
|
|
storage::StorageGcConfig{.type = storage::StorageGcConfig::Type::PERIODIC,
|
|
|
|
.interval = std::chrono::milliseconds(100)});
|
|
|
|
|
|
|
|
std::vector<storage::Gid> vertices;
|
|
|
|
|
|
|
|
{
|
|
|
|
auto acc = storage.Access();
|
|
|
|
// Create some vertices, but delete some of them immediately.
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.CreateVertex();
|
|
|
|
vertices.push_back(vertex.Gid());
|
|
|
|
}
|
|
|
|
|
|
|
|
acc.AdvanceCommand();
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.FindVertex(vertices[i], storage::View::OLD);
|
|
|
|
ASSERT_TRUE(vertex.has_value());
|
|
|
|
if (i % 5 == 0) {
|
|
|
|
acc.DeleteVertex(&vertex.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for GC.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
|
|
|
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex_old = acc.FindVertex(vertices[i], storage::View::OLD);
|
|
|
|
auto vertex_new = acc.FindVertex(vertices[i], storage::View::NEW);
|
|
|
|
EXPECT_TRUE(vertex_old.has_value());
|
|
|
|
EXPECT_EQ(vertex_new.has_value(), i % 5 != 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
acc.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify existing vertices and add labels to some of them.
|
|
|
|
{
|
|
|
|
auto acc = storage.Access();
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.FindVertex(vertices[i], storage::View::OLD);
|
|
|
|
EXPECT_EQ(vertex.has_value(), i % 5 != 0);
|
|
|
|
|
|
|
|
if (vertex.has_value()) {
|
|
|
|
vertex->AddLabel(3 * i);
|
|
|
|
vertex->AddLabel(3 * i + 1);
|
|
|
|
vertex->AddLabel(3 * i + 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for GC.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
|
|
|
|
|
|
|
// Verify labels.
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.FindVertex(vertices[i], storage::View::NEW);
|
|
|
|
EXPECT_EQ(vertex.has_value(), i % 5 != 0);
|
|
|
|
|
|
|
|
if (vertex.has_value()) {
|
|
|
|
auto labels_old = vertex->Labels(storage::View::OLD);
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_TRUE(labels_old.HasValue());
|
|
|
|
EXPECT_TRUE(labels_old->empty());
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
|
|
|
|
auto labels_new = vertex->Labels(storage::View::NEW);
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_TRUE(labels_new.HasValue());
|
|
|
|
EXPECT_THAT(labels_new.GetValue(),
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
UnorderedElementsAre(3 * i, 3 * i + 1, 3 * i + 2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
acc.Commit();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add and remove some edges.
|
|
|
|
{
|
|
|
|
auto acc = storage.Access();
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto from_vertex = acc.FindVertex(vertices[i], storage::View::OLD);
|
|
|
|
auto to_vertex =
|
|
|
|
acc.FindVertex(vertices[(i + 1) % 1000], storage::View::OLD);
|
|
|
|
EXPECT_EQ(from_vertex.has_value(), i % 5 != 0);
|
|
|
|
EXPECT_EQ(to_vertex.has_value(), (i + 1) % 5 != 0);
|
|
|
|
|
|
|
|
if (from_vertex.has_value() && to_vertex.has_value()) {
|
|
|
|
acc.CreateEdge(&from_vertex.value(), &to_vertex.value(), i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Detach delete some vertices.
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.FindVertex(vertices[i], storage::View::NEW);
|
|
|
|
EXPECT_EQ(vertex.has_value(), i % 5 != 0);
|
|
|
|
if (vertex.has_value()) {
|
|
|
|
if (i % 3 == 0) {
|
|
|
|
acc.DetachDeleteVertex(&vertex.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for GC.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(300));
|
|
|
|
|
|
|
|
// Vertify edges.
|
|
|
|
for (uint64_t i = 0; i < 1000; ++i) {
|
|
|
|
auto vertex = acc.FindVertex(vertices[i], storage::View::NEW);
|
|
|
|
EXPECT_EQ(vertex.has_value(), i % 5 != 0 && i % 3 != 0);
|
|
|
|
if (vertex.has_value()) {
|
|
|
|
auto out_edges =
|
|
|
|
vertex->OutEdges(std::vector<uint64_t>{}, storage::View::NEW);
|
|
|
|
if (i % 5 != 4 && i % 3 != 2) {
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_EQ(out_edges.GetValue().size(), 1);
|
|
|
|
EXPECT_EQ(out_edges.GetValue().at(0).EdgeType(), i);
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
} else {
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_TRUE(out_edges->empty());
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
auto in_edges =
|
|
|
|
vertex->InEdges(std::vector<uint64_t>{}, storage::View::NEW);
|
|
|
|
if (i % 5 != 1 && i % 3 != 1) {
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_EQ(in_edges.GetValue().size(), 1);
|
|
|
|
EXPECT_EQ(in_edges.GetValue().at(0).EdgeType(), (i + 999) % 1000);
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
} else {
|
2019-07-17 16:32:06 +08:00
|
|
|
EXPECT_TRUE(in_edges->empty());
|
[StorageV2] Implement GC
Summary:
Here are some numbers from the benchmark:
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 8
Config: NoGc, Time: 25.9836
Config: OnFinishGc, Time: 49.012
Config: 100msPeriodicGc, Time: 45.9856
Config: 1000msPeriodicGc, Time: 40.3094
```
```
(TOOLCHAIN) mtomic@poso:~/memgraph/build_release$ tests/benchmark/storage_v2_gc --num-threads 7
Config: NoGc, Time: 20.4256
Config: OnFinishGc, Time: 39.6669
Config: 100msPeriodicGc, Time: 30.7956
Config: 1000msPeriodicGc, Time: 35.128
```
It is not that bad if there is a core dedicated to doing garbage collection.
Reviewers: mferencevic, teon.banek
Reviewed By: mferencevic, teon.banek
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D2168
2019-07-09 22:34:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
acc.Commit();
|
|
|
|
}
|
|
|
|
}
|