Properties system and core storage major refactor. STABLE STATE, unit tests added.
This commit is contained in:
parent
55f1912910
commit
a11ebef9c5
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -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_;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user