Implemented label-property index recovery.

Reviewers: buda, florijan, teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D530
This commit is contained in:
matej.gradicek 2017-07-12 12:35:22 +02:00
parent 6068a95a0e
commit 45922a987e
5 changed files with 90 additions and 2 deletions

View File

@ -308,6 +308,13 @@ class GraphDbAccessor {
LabelPropertyIndex::Key(label, property));
}
/**
* @brief - Returns vector of keys of label-property indices.
*/
std::vector<LabelPropertyIndex::Key> GetIndicesKeys() {
return db_.label_property_index_.GetIndicesKeys();
}
/**
* Return approximate number of all vertices in the database.
* Note that this is always an over-estimate and never an under-estimate.

View File

@ -282,6 +282,17 @@ class LabelPropertyIndex {
});
}
/**
* @brief - Returns vector of keys of label-property indice.
*/
std::vector<Key> GetIndicesKeys() {
std::vector<Key> indices;
for (auto index : indices_.access()) {
indices.push_back(index.first);
}
return indices;
}
private:
/**
* @brief - Contains value, vlist and vertex record to distinguish between

View File

@ -25,6 +25,19 @@ bool Recovery::Decode(const fs::path &snapshot_file,
}
std::unordered_map<uint64_t, VertexAccessor> vertices;
query::TypedValue tv;
if (!decoder.ReadTypedValue(&tv, query::TypedValue::Type::List)) {
buffer.Close();
return false;
}
auto &label_property_vector = tv.Value<std::vector<query::TypedValue>>();
for (int i = 0; i < label_property_vector.size(); i += 2) {
auto label = label_property_vector[i].Value<std::string>();
auto property = label_property_vector[i + 1].Value<std::string>();
db_accessor.BuildIndex(db_accessor.label(label),
db_accessor.property(property));
}
for (int64_t i = 0; i < summary.vertex_num_; ++i) {
communication::bolt::DecodedVertex vertex;
if (!decoder.ReadVertex(&vertex)) {

View File

@ -33,8 +33,17 @@ bool Snapshooter::Encode(const fs::path &snapshot_file,
// BaseEncoder encodes graph elements. Flag true is for storing vertex IDs.
communication::bolt::BaseEncoder<FileWriterBuffer> encoder(buffer, true);
int64_t vertex_num = 0, edge_num = 0;
buffer.Open(snapshot_file);
std::vector<query::TypedValue> label_property_vector;
for (const auto &key : db_accessor_.GetIndicesKeys()) {
query::TypedValue label(*key.label_);
query::TypedValue property(*key.property_);
label_property_vector.push_back(label);
label_property_vector.push_back(property);
}
encoder.WriteList(label_property_vector);
for (const auto &vertex : db_accessor_.vertices(false)) {
encoder.WriteVertex(vertex);
vertex_num++;

View File

@ -109,9 +109,11 @@ TEST_F(RecoveryTest, TestEncoding) {
snapshot::Summary summary;
buffer.Open(snapshot, summary);
query::TypedValue tv;
decoder.ReadTypedValue(&tv);
std::vector<int64_t> ids;
std::vector<std::string> edge_types;
for (int i = 0; i < summary.vertex_num_; ++i) {
communication::bolt::DecodedVertex vertex;
decoder.ReadVertex(&vertex);
@ -228,6 +230,52 @@ TEST_F(RecoveryTest, TestEncodingAndRecovering) {
dba_get->commit();
}
TEST_F(RecoveryTest, TestLabelPropertyIndexRecovery) {
// Creates snapshot of the graph with indices.
Dbms dbms;
auto dba = dbms.active();
dba->BuildIndex(dba->label("label"), dba->property("prop"));
dba->commit();
CreateBigGraph(dbms);
TakeSnapshot(dbms, max_retained_snapshots_);
std::string snapshot = GetLatestSnapshot();
Dbms dbms_recover;
auto dba_recover = dbms_recover.active();
Recovery recovery;
EXPECT_TRUE(recovery.Recover(snapshot, *dba_recover));
auto dba_get = dbms_recover.active();
EXPECT_EQ(dba_get->GetIndicesKeys().size(), 1);
EXPECT_TRUE(dba_get->LabelPropertyIndexExists(dba_get->label("label"),
dba_get->property("prop")));
int64_t vertex_count = 0;
for (const auto &vertex : dba_get->vertices(false)) {
EXPECT_EQ(vertex.labels().size(), 1);
EXPECT_TRUE(vertex.has_label(dba_get->label("label")));
query::TypedValue prop =
query::TypedValue(vertex.PropsAt(dba_get->property("prop")));
query::TypedValue expected_prop = query::TypedValue(PropertyValue("prop"));
EXPECT_TRUE((prop == expected_prop).Value<bool>());
vertex_count++;
}
EXPECT_EQ(vertex_count, 1000);
int64_t edge_count = 0;
for (const auto &edge : dba_get->edges(false)) {
EXPECT_EQ(edge.edge_type(), dba_get->edge_type("type"));
query::TypedValue prop =
query::TypedValue(edge.PropsAt(dba_get->property("prop")));
query::TypedValue expected_prop = query::TypedValue(PropertyValue("prop"));
EXPECT_TRUE((prop == expected_prop).Value<bool>());
edge_count++;
}
EXPECT_EQ(edge_count, 999);
dba_get->commit();
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();