Compare prev ptr as well

This commit is contained in:
jbajic 2023-02-02 15:50:03 +01:00
parent 8f660b0d44
commit bf44618b7a
2 changed files with 87 additions and 32 deletions

View File

@ -154,6 +154,8 @@ void Splitter::AdjustClonedTransaction(Transaction &cloned_transaction, const Tr
auto cloned_delta_it = cloned_transaction.deltas.begin();
while (delta_it != transaction.deltas.end()) {
// Only start iterating through deltas that are head of delta chain
// => they have prev pointer to vertex/edge
const auto *delta = &*delta_it;
auto *cloned_delta = &*cloned_delta_it;
while (delta->next != nullptr) {
@ -170,8 +172,6 @@ void Splitter::AdjustClonedTransaction(Transaction &cloned_transaction, const Tr
}
case PreviousPtr::Type::DELTA: {
// Same as for deltas except don't align next but prev
// auto cloned_transaction_it =
// cloned_transactions.find(ptr.delta->commit_info->start_or_commit_timestamp.logical_id);
auto cloned_transaction_it = std::ranges::find_if(cloned_transactions, [&ptr](const auto &elem) {
return elem.second->start_timestamp == ptr.delta->commit_info->start_or_commit_timestamp ||
elem.second->commit_info->start_or_commit_timestamp ==

View File

@ -82,9 +82,12 @@ void AssertEqVertexContainer(const VertexContainer &actual, const VertexContaine
auto *expected_delta = expected_it->second.delta;
auto *actual_delta = actual_it->second.delta;
// This asserts delta chain
while (expected_delta != nullptr) {
EXPECT_EQ(actual_delta->action, expected_delta->action);
EXPECT_EQ(actual_delta->uuid, expected_delta->uuid);
EXPECT_NE(&actual_delta, &expected_delta) << "Deltas must be different objects!";
switch (expected_delta->action) {
case Delta::Action::ADD_LABEL:
case Delta::Action::REMOVE_LABEL: {
@ -105,6 +108,33 @@ void AssertEqVertexContainer(const VertexContainer &actual, const VertexContaine
break;
}
}
const auto expected_prev = expected_delta->prev.Get();
const auto actual_prev = actual_delta->prev.Get();
switch (expected_prev.type) {
case PreviousPtr::Type::NULLPTR: {
ASSERT_EQ(actual_prev.type, PreviousPtr::Type::NULLPTR) << "Expected type is nullptr!";
break;
}
case PreviousPtr::Type::DELTA: {
ASSERT_EQ(actual_prev.type, PreviousPtr::Type::DELTA) << "Expected type is delta!";
EXPECT_EQ(actual_prev.delta->action, expected_prev.delta->action);
EXPECT_EQ(actual_prev.delta->uuid, expected_prev.delta->uuid);
EXPECT_NE(actual_prev.delta, expected_prev.delta) << "Prev deltas must be different objects!";
break;
}
case v3::PreviousPtr::Type::EDGE: {
ASSERT_EQ(actual_prev.type, PreviousPtr::Type::EDGE) << "Expected type is edge!";
EXPECT_EQ(actual_prev.edge->gid, expected_prev.edge->gid);
break;
}
case v3::PreviousPtr::Type::VERTEX: {
ASSERT_EQ(actual_prev.type, PreviousPtr::Type::VERTEX) << "Expected type is vertex!";
EXPECT_EQ(actual_prev.vertex->first, expected_prev.vertex->first);
break;
}
}
expected_delta = expected_delta->next;
actual_delta = actual_delta->next;
}
@ -115,6 +145,17 @@ void AssertEqVertexContainer(const VertexContainer &actual, const VertexContaine
}
}
void AssertEqDeltaLists(const std::list<Delta> &actual, const std::list<Delta> &expected) {
ASSERT_EQ(actual.size(), expected.size());
auto actual_it = actual.begin();
auto expected_it = expected.begin();
while (actual_it != actual.end()) {
EXPECT_EQ(actual_it->action, expected_it->action);
EXPECT_EQ(actual_it->uuid, expected_it->uuid);
EXPECT_NE(&*actual_it, &*expected_it) << "Deltas must be different objects!";
}
}
void AddDeltaToDeltaChain(Vertex *object, Delta *new_delta) {
auto *delta_holder = GetDeltaHolder(object);
@ -154,14 +195,27 @@ TEST_F(ShardSplitTest, TestBasicSplitWithVertices) {
Delta delta_delete3{Delta::DeleteObjectTag{}, &commit_info, 8, 3};
VertexContainer expected_vertices;
expected_vertices.emplace(PrimaryKey{PropertyValue{4}}, VertexData(&delta_delete1));
auto [it, inserted] = expected_vertices.emplace(PrimaryKey{PropertyValue{5}}, VertexData(&delta_delete2));
expected_vertices.emplace(PrimaryKey{PropertyValue{6}}, VertexData(&delta_delete3));
it->second.labels.push_back(secondary_label);
AddDeltaToDeltaChain(&*it, &delta_set_property);
AddDeltaToDeltaChain(&*it, &delta_remove_label);
auto [it_4, inserted1] = expected_vertices.emplace(PrimaryKey{PropertyValue{4}}, VertexData(&delta_delete1));
delta_delete1.prev.Set(&*it_4);
auto [it_5, inserted2] = expected_vertices.emplace(PrimaryKey{PropertyValue{5}}, VertexData(&delta_delete2));
delta_delete2.prev.Set(&*it_5);
auto [it_6, inserted3] = expected_vertices.emplace(PrimaryKey{PropertyValue{6}}, VertexData(&delta_delete3));
delta_delete3.prev.Set(&*it_6);
it_5->second.labels.push_back(secondary_label);
AddDeltaToDeltaChain(&*it_5, &delta_set_property);
AddDeltaToDeltaChain(&*it_5, &delta_remove_label);
AssertEqVertexContainer(splitted_data.vertices, expected_vertices);
// This is to ensure that the transaction that we have don't point to invalid
// object on the other shard
std::list<Delta> expected_deltas;
expected_deltas.emplace_back(Delta::DeleteObjectTag{}, &commit_info, 4, 1);
expected_deltas.emplace_back(Delta::DeleteObjectTag{}, &commit_info, 5, 2);
expected_deltas.emplace_back(Delta::RemoveLabelTag{}, secondary_label, &commit_info, 7, 4);
expected_deltas.emplace_back(Delta::SetPropertyTag{}, secondary_property, PropertyValue(), &commit_info, 6, 4);
expected_deltas.emplace_back(Delta::DeleteObjectTag{}, &commit_info, 8, 3);
// AssertEqDeltaLists(splitted_data.transactions.begin()->second->deltas, expected_deltas);
}
TEST_F(ShardSplitTest, TestBasicSplitVerticesAndEdges) {
@ -330,33 +384,34 @@ TEST_F(ShardSplitTest, TestBasicSplitWithLabelPropertyIndex) {
EXPECT_EQ(splitted_data.label_property_indices.size(), 1);
}
TEST_F(ShardSplitTest, TestBigSplit) {
int pk{0};
for (int64_t i{0}; i < 100000; ++i) {
auto acc = storage.Access(GetNextHlc());
EXPECT_FALSE(
acc.CreateVertexAndValidate({secondary_label}, {PropertyValue(pk++)}, {{secondary_property, PropertyValue(i)}})
.HasError());
EXPECT_FALSE(acc.CreateVertexAndValidate({}, {PropertyValue(pk++)}, {}).HasError());
// TEST_F(ShardSplitTest, TestBigSplit) {
// int pk{0};
// for (int64_t i{0}; i < 10'000; ++i) {
// auto acc = storage.Access(GetNextHlc());
// EXPECT_FALSE(
// acc.CreateVertexAndValidate({secondary_label}, {PropertyValue(pk++)}, {{secondary_property,
// PropertyValue(i)}})
// .HasError());
// EXPECT_FALSE(acc.CreateVertexAndValidate({}, {PropertyValue(pk++)}, {}).HasError());
EXPECT_FALSE(acc.CreateEdge(VertexId{primary_label, PrimaryKey{PropertyValue(pk - 2)}},
VertexId{primary_label, PrimaryKey{PropertyValue(pk - 1)}}, edge_type_id,
Gid::FromUint(pk))
.HasError());
acc.Commit(GetNextHlc());
}
storage.CreateIndex(secondary_label, secondary_property);
// EXPECT_FALSE(acc.CreateEdge(VertexId{primary_label, PrimaryKey{PropertyValue(pk - 2)}},
// VertexId{primary_label, PrimaryKey{PropertyValue(pk - 1)}}, edge_type_id,
// Gid::FromUint(pk))
// .HasError());
// acc.Commit(GetNextHlc());
// }
// storage.CreateIndex(secondary_label, secondary_property);
const auto split_value = pk / 2;
auto splitted_data = storage.PerformSplit({PropertyValue(split_value)}, 2);
// const auto split_value = pk / 2;
// auto splitted_data = storage.PerformSplit({PropertyValue(split_value)}, 2);
EXPECT_EQ(splitted_data.vertices.size(), 100000);
EXPECT_EQ(splitted_data.edges->size(), 50000);
EXPECT_EQ(splitted_data.transactions.size(), 50000);
EXPECT_EQ(splitted_data.label_indices.size(), 0);
EXPECT_EQ(splitted_data.label_property_indices.size(), 1);
// EXPECT_EQ(splitted_data.vertices.size(), 100000);
// EXPECT_EQ(splitted_data.edges->size(), 50000);
// EXPECT_EQ(splitted_data.transactions.size(), 50000);
// EXPECT_EQ(splitted_data.label_indices.size(), 0);
// EXPECT_EQ(splitted_data.label_property_indices.size(), 1);
AssertSplittedShard(std::move(splitted_data), split_value);
}
// AssertSplittedShard(std::move(splitted_data), split_value);
// }
} // namespace memgraph::storage::v3::tests