Properties system and core storage major refactor. STABLE STATE, unit tests added.

This commit is contained in:
florijan 2017-02-16 17:43:39 +01:00
parent 55f1912910
commit a11ebef9c5
5 changed files with 154 additions and 14 deletions

View File

@ -76,20 +76,23 @@ public:
*/
size_t PropsErase(GraphDb::Property key);
/**
* Returns the properties of this record.
* @return
*/
const TypedValueStore<GraphDb::Property> &Properties() const;
void PropertiesAccept(std::function<void(const GraphDb::Property key, const TypedValue &prop)> handler,
std::function<void()> finish = {}) const;
// Assumes same transaction
friend bool operator==(const RecordAccessor &a, const RecordAccessor &b) {
// TODO consider the legitimacy of this comparison
assert(&a.db_accessor_ == &b.db_accessor_); // assume the same db_accessor / transaction
return &a.vlist_ == &b.vlist_;
}
friend bool operator!=(const RecordAccessor &a, const RecordAccessor &b) {
// TODO consider the legitimacy of this comparison
return a != b;
assert(&a.db_accessor_ == &b.db_accessor_); // assume the same db_accessor / transaction
return !(a == b);
}
/**

View File

@ -1,6 +1,5 @@
#pragma once
#include <set>
#include <vector>
#include "database/graph_db.hpp"
@ -16,6 +15,6 @@ class Vertex : public mvcc::Record<Vertex> {
public:
std::vector<mvcc::VersionList<Edge>*> out_;
std::vector<mvcc::VersionList<Edge>*> in_;
std::set<GraphDb::Label> labels_;
std::vector<GraphDb::Label> labels_;
TypedValueStore<GraphDb::Property> properties_;
};

View File

@ -61,7 +61,7 @@ public:
* Returns all the Labels of the Vertex.
* @return
*/
const std::set<GraphDb::Label>& labels() const;
const std::vector<GraphDb::Label>& labels() const;
/**
* Returns EdgeAccessors for all incoming edges.

View File

@ -1,3 +1,5 @@
#include <algorithm>
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/util.hpp"
@ -11,19 +13,33 @@ size_t VertexAccessor::in_degree() const {
}
bool VertexAccessor::add_label(GraphDb::Label label) {
return update().labels_.emplace(label).second;
auto &labels_view = view().labels_;
auto found = std::find(labels_view.begin(), labels_view.end(), label);
if (found!= labels_view.end())
return false;
// not a duplicate label, add it
update().labels_.emplace_back(label);
return true;
}
size_t VertexAccessor::remove_label(GraphDb::Label label) {
return update().labels_.erase(label);
auto &labels = update().labels_;
auto found = std::find(labels.begin(), labels.end(), label);
if (found == labels.end())
return 0;
std::swap(*found, labels.back());
labels.pop_back();
return 1;
}
bool VertexAccessor::has_label(GraphDb::Label label) const {
auto &label_set = this->view().labels_;
return label_set.find(label) != label_set.end();
auto &labels = this->view().labels_;
return std::find(labels.begin(), labels.end(), label) != labels.end();
}
const std::set<GraphDb::Label>& VertexAccessor::labels() const {
const std::vector<GraphDb::Label>& VertexAccessor::labels() const {
return this->view().labels_;
}

View File

@ -1,3 +1,4 @@
#include <vector>
#include "gtest/gtest.h"
@ -10,15 +11,136 @@
#include "storage/edge_accessor.hpp"
TEST(RecordAccessor, PropertySet) {
TEST(RecordAccessor, Properties) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto vertex = dba.insert_vertex();
auto &properties = vertex.Properties();
auto property = dba.property("PropName");
auto property_other = dba.property("Other");
EXPECT_EQ(vertex.PropsAt(property).type_, TypedValue::Type::Null);
vertex.PropsSet(property, 42);
EXPECT_EQ(vertex.PropsAt(property).Value<int>(), 42);
EXPECT_TRUE((vertex.PropsAt(dba.property("Other")) == TypedValue::Null).Value<bool>());
EXPECT_EQ(properties.at(property).Value<int>(), 42);
EXPECT_EQ(vertex.PropsAt(property_other).type_, TypedValue::Type::Null);
EXPECT_EQ(properties.at(property_other).type_, TypedValue::Type::Null);
vertex.PropsErase(property);
EXPECT_EQ(vertex.PropsAt(property).type_, TypedValue::Type::Null);
EXPECT_EQ(properties.at(property).type_, TypedValue::Type::Null);
}
TEST(RecordAccessor, DbAccessor) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto vertex = dba.insert_vertex();
const auto& const_vertex_dba = vertex.db_accessor();
EXPECT_EQ(&dba, &const_vertex_dba);
auto& vertex_dba = vertex.db_accessor();
EXPECT_EQ(&dba, &vertex_dba);
}
TEST(RecordAccessor, RecordEquality) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto v1 = dba.insert_vertex();
auto v2 = dba.insert_vertex();
EXPECT_EQ(v1, v1);
EXPECT_NE(v1, v2);
auto e1 = dba.insert_edge(v1, v2, dba.edge_type("type"));
auto e2 = dba.insert_edge(v1, v2, dba.edge_type("type"));
EXPECT_EQ(e1, e1);
EXPECT_NE(e1, e2);
}
TEST(RecordAccessor, VertexLabels) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto v1 = dba.insert_vertex();
auto &labels = v1.labels();
EXPECT_EQ(v1.labels().size(), 0);
GraphDb::Label l1 = dba.label("label1");
GraphDb::Label l2 = dba.label("label2");
// adding labels
EXPECT_FALSE(v1.has_label(l1));
EXPECT_TRUE(v1.add_label(l1));
EXPECT_TRUE(v1.has_label(l1));
EXPECT_EQ(v1.labels().size(), 1);
EXPECT_EQ(labels.size(), 1);
EXPECT_FALSE(v1.add_label(l1));
EXPECT_EQ(v1.labels().size(), 1);
EXPECT_EQ(labels.size(), 1);
EXPECT_FALSE(v1.has_label(l2));
EXPECT_TRUE(v1.add_label(l2));
EXPECT_TRUE(v1.has_label(l2));
EXPECT_EQ(v1.labels().size(), 2);
EXPECT_EQ(labels.size(), 2);
// removing labels
GraphDb::Label l3 = dba.label("label3");
EXPECT_EQ(v1.remove_label(l3), 0);
EXPECT_EQ(labels.size(), 2);
EXPECT_EQ(v1.remove_label(l1), 1);
EXPECT_FALSE(v1.has_label(l1));
EXPECT_EQ(v1.labels().size(), 1);
EXPECT_EQ(v1.remove_label(l1), 0);
EXPECT_TRUE(v1.has_label(l2));
}
TEST(RecordAccessor, EdgeType) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto v1 = dba.insert_vertex();
auto v2 = dba.insert_vertex();
GraphDb::EdgeType likes = dba.edge_type("likes");
GraphDb::EdgeType hates = dba.edge_type("hates");
auto edge = dba.insert_edge(v1, v2, likes);
EXPECT_EQ(edge.edge_type(), likes);
EXPECT_NE(edge.edge_type(), hates);
edge.set_edge_type(hates);
EXPECT_EQ(edge.edge_type(), hates);
EXPECT_NE(edge.edge_type(), likes);
}
TEST(RecordAccessor, VertexEdgeConnections) {
Dbms dbms;
GraphDbAccessor dba = dbms.active();
auto v1 = dba.insert_vertex();
auto v2 = dba.insert_vertex();
auto edge = dba.insert_edge(v1, v2, dba.edge_type("likes"));
EXPECT_EQ(edge.from(), v1);
EXPECT_NE(edge.from(), v2);
EXPECT_EQ(edge.to(), v2);
EXPECT_NE(edge.to(), v1);
EXPECT_EQ(v1.in().size(), 0);
EXPECT_EQ(v1.out().size(), 1);
EXPECT_EQ(v2.in().size(), 1);
EXPECT_EQ(v2.out().size(), 0);
for (auto e : v1.out())
EXPECT_EQ(edge, e);
for (auto e : v2.in())
EXPECT_EQ(edge, e);
}