This commit is contained in:
Marko Budiselic 2016-08-14 12:44:02 +01:00
commit 6d8fccde8f
20 changed files with 359 additions and 199 deletions

View File

@ -15,7 +15,7 @@ find_package(Threads REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
# glibcxx debug (useful for gdb)
# the problem is that the query engine doesn't work as it should work if
# the problem is that the query engine doesn't work as it should work if
# this flag is present
# TODO: find more appropriate way to use this flag only when it is needed
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
@ -288,7 +288,7 @@ endif()
# release flags
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} -march=native -Wall -Werror")
"${CMAKE_CXX_FLAGS_RELEASE} -march=native -Wall")
# -- configure defines -- default is ON | true | enabled ----------------------
# -- logging ------------------------------------------------------------------
@ -412,6 +412,10 @@ set(memgraph_src_files
${src_dir}/logging/default.cpp
${src_dir}/logging/log.cpp
${src_dir}/io/network/tls.cpp
${src_dir}/database/db.cpp
${src_dir}/database/db_accessor.cpp
${src_dir}/database/db_transaction.cpp
${src_dir}/storage/edge_accessor.cpp
)
# STATIC library used by memgraph executables
@ -434,7 +438,7 @@ endif()
# memgraph build name
execute_process(
OUTPUT_VARIABLE COMMIT_NO
OUTPUT_VARIABLE COMMIT_NO
COMMAND git rev-list --count HEAD
)
execute_process(

View File

@ -1,13 +1,13 @@
#pragma once
#include "communication/bolt/v1/transport/bolt_encoder.hpp"
#include "communication/bolt/v1/packing/codes.hpp"
#include "communication/bolt/v1/transport/bolt_encoder.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/model/properties/properties.hpp"
#include "storage/model/properties/all.hpp"
#include "storage/model/properties/properties.hpp"
namespace bolt
{
@ -22,7 +22,7 @@ class BoltSerializer
// friend void accept(const Property &property, Handler &h);
public:
BoltSerializer(Stream& stream) : encoder(stream) {}
BoltSerializer(Stream &stream) : encoder(stream) {}
/* Serializes the vertex accessor into the packstream format
*
@ -33,7 +33,7 @@ public:
* }
*
*/
void write(const Vertex::Accessor& vertex)
void write(const Vertex::Accessor &vertex)
{
// write signatures for the node struct and node data type
encoder.write_struct_header(3);
@ -47,7 +47,7 @@ public:
encoder.write_list_header(labels.size());
for(auto& label : labels)
for (auto &label : labels)
encoder.write_string(label.get());
// write the property map
@ -55,7 +55,7 @@ public:
encoder.write_map_header(props.size());
for(auto& prop : props) {
for (auto &prop : props) {
write(prop.first);
write(*prop.second);
}
@ -72,7 +72,7 @@ public:
* }
*
*/
void write(const Edge::Accessor& edge)
void write(const Edge::Accessor &edge)
{
// write signatures for the edge struct and edge data type
encoder.write_struct_header(5);
@ -82,8 +82,8 @@ public:
encoder.write_integer(edge.id());
// TODO refactor when from() and to() start returning Accessors
encoder.write_integer(edge.from()->id);
encoder.write_integer(edge.to()->id);
encoder.write_integer(edge.from_record()->id);
encoder.write_integer(edge.to_record()->id);
// write the type of the edge
encoder.write_string(edge.edge_type());
@ -93,65 +93,37 @@ public:
encoder.write_map_header(props.size());
for(auto& prop : props) {
for (auto &prop : props) {
write(prop.first);
write(*prop.second);
}
}
void write(const Property& prop)
{
accept(prop, *this);
}
void write(const Property &prop) { accept(prop, *this); }
void write_null()
{
encoder.write_null();
}
void write_null() { encoder.write_null(); }
void write(const Bool& prop)
{
encoder.write_bool(prop.value());
}
void write(const Bool &prop) { encoder.write_bool(prop.value()); }
void write(const Float& prop)
{
encoder.write_double(prop.value);
}
void write(const Float &prop) { encoder.write_double(prop.value); }
void write(const Double& prop)
{
encoder.write_double(prop.value);
}
void write(const Double &prop) { encoder.write_double(prop.value); }
void write(const Int32& prop)
{
encoder.write_integer(prop.value);
}
void write(const Int32 &prop) { encoder.write_integer(prop.value); }
void write(const Int64& prop)
{
encoder.write_integer(prop.value);
}
void write(const Int64 &prop) { encoder.write_integer(prop.value); }
void write(const std::string& value)
{
encoder.write_string(value);
}
void write(const std::string &value) { encoder.write_string(value); }
void write(const String& prop)
{
encoder.write_string(prop.value);
}
void write(const String &prop) { encoder.write_string(prop.value); }
template <class T>
void handle(const T& prop)
void handle(const T &prop)
{
write(prop);
}
protected:
Stream& encoder;
Stream &encoder;
};
}

View File

@ -1,25 +1,22 @@
#pragma once
#include "storage/graph.hpp"
// #include "transactions/commit_log.hpp"
#include "transactions/engine.hpp"
#include "transactions/commit_log.hpp"
class Db
{
public:
using sptr = std::shared_ptr<Db>;
Db() = default;
Db(const std::string& name) : name_(name) {}
Db(const Db& db) = delete;
Db();
Db(const std::string &name);
Db(const Db &db) = delete;
Graph graph;
tx::Engine tx_engine;
std::string& name()
{
return name_;
}
std::string &name();
private:
std::string name_;

View File

@ -0,0 +1,50 @@
#pragma once
#include "database/db.hpp"
#include "database/db_accessor.hpp"
#include "storage/record_accessor.hpp"
#include "storage/vertex.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/vertices.hpp"
#include "transactions/transaction.hpp"
class DbAccessor
{
public:
DbAccessor(Db &db);
// VERTEX METHODS
Vertices::vertices_t::Accessor vertex_access();
const Vertex::Accessor vertex_find(const Id &id);
const Vertex::Accessor vertex_first();
Vertex::Accessor vertex_insert();
// EDGE METHODS
Edge::Accessor edge_find(const Id &id);
Edge::Accessor edge_insert(VertexRecord *from, VertexRecord *to);
// LABEL METHODS
const Label &label_find_or_create(const std::string &name);
bool label_contains(const std::string &name);
VertexIndexRecordCollection &label_find_index(const Label &label);
// TYPE METHODS
const EdgeType &type_find_or_create(const std::string &name);
bool type_contains(const std::string &name);
// TRANSACTION METHODS
void commit();
void abort();
// EASE OF USE METHODS
tx::Transaction &operator*();
DbTransaction db;
};

View File

@ -0,0 +1,26 @@
#pragma once
#include "storage/indexes/index_record.hpp"
#include "storage/label/label.hpp"
#include "transactions/transaction.hpp"
class Db;
class DbAccessor;
// Inner structures local to transaction can hold ref to this structure and use
// its methods.
class DbTransaction
{
friend DbAccessor;
public:
DbTransaction(Db &db, tx::Transaction &trans) : db(db), trans(trans) {}
void update_label_index(const Label &label,
VertexIndexRecord &&index_record);
// protected:
// TRANSACTION METHODS
tx::Transaction &trans;
Db &db;
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "database/db.hpp"
#include "database/db_accessor.hpp"
#include "query_engine/query_stripper.hpp"
#include "query_engine/util.hpp"
#include "storage/model/properties/property.hpp"
@ -12,8 +13,8 @@ auto load_queries(Db &db)
// CREATE (n {prop: 0}) RETURN n)
auto create_node = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
auto vertex_accessor = db.graph.vertices.insert(t);
DbAccessor t(db);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.property("prop", args[0]);
t.commit();
return true;
@ -21,10 +22,10 @@ auto load_queries(Db &db)
queries[11597417457737499503u] = create_node;
auto create_labeled_and_named_node = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
auto vertex_accessor = db.graph.vertices.insert(t);
DbAccessor t(db);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.property("name", args[0]);
auto &label = db.graph.label_store.find_or_create("LABEL");
auto &label = t.label_find_or_create("LABEL");
vertex_accessor.add_label(label);
cout_properties(vertex_accessor.properties());
t.commit();
@ -32,13 +33,13 @@ auto load_queries(Db &db)
};
auto create_account = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
auto vertex_accessor = db.graph.vertices.insert(t);
DbAccessor t(db);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.property("id", args[0]);
vertex_accessor.property("name", args[1]);
vertex_accessor.property("country", args[2]);
vertex_accessor.property("created_at", args[3]);
auto &label = db.graph.label_store.find_or_create("ACCOUNT");
auto &label = t.label_find_or_create("ACCOUNT");
vertex_accessor.add_label(label);
cout_properties(vertex_accessor.properties());
t.commit();
@ -46,9 +47,9 @@ auto load_queries(Db &db)
};
auto find_node_by_internal_id = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto id = static_cast<Int32 &>(*args[0]);
auto vertex_accessor = db.graph.vertices.find(t, Id(id.value));
auto vertex_accessor = t.vertex_find(Id(id.value));
if (!vertex_accessor) {
cout << "vertex doesn't exist" << endl;
t.commit();
@ -64,20 +65,17 @@ auto load_queries(Db &db)
};
auto create_edge = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto v1 = db.graph.vertices.find(t, args[0]->as<Int32>().value);
auto v1 = t.vertex_find(args[0]->as<Int32>().value);
if (!v1) return t.commit(), false;
auto v2 = db.graph.vertices.find(t, args[1]->as<Int32>().value);
auto v2 = t.vertex_find(args[1]->as<Int32>().value);
if (!v2) return t.commit(), false;
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
auto &edge_type = db.graph.edge_type_store.find_or_create("IS");
auto &edge_type = t.type_find_or_create("IS");
edge_accessor.edge_type(edge_type);
t.commit();
@ -90,8 +88,8 @@ auto load_queries(Db &db)
};
auto find_edge_by_internal_id = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
auto edge_accessor = db.graph.edges.find(t, args[0]->as<Int32>().value);
DbAccessor t(db);
auto edge_accessor = t.edge_find(args[0]->as<Int32>().value);
if (!edge_accessor) return t.commit(), false;
// print edge type and properties
@ -99,11 +97,11 @@ auto load_queries(Db &db)
auto from = edge_accessor.from();
cout << "FROM:" << endl;
cout_properties(from->find(t)->data.props);
cout_properties(from.record->data.props);
auto to = edge_accessor.to();
cout << "TO:" << endl;
cout_properties(to->find(t)->data.props);
cout_properties(to.record->data.props);
t.commit();
@ -111,9 +109,9 @@ auto load_queries(Db &db)
};
auto update_node = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto v = db.graph.vertices.find(t, args[0]->as<Int32>().value);
auto v = t.vertex_find(args[0]->as<Int32>().value);
if (!v) return t.commit(), false;
v.property("name", args[1]);
@ -127,18 +125,17 @@ auto load_queries(Db &db)
// MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,
// weight: 70}]-(n2) RETURN r
auto create_edge_v2 = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
auto n1 = db.graph.vertices.find(t, args[0]->as<Int64>().value);
DbAccessor t(db);
auto n1 = t.vertex_find(args[0]->as<Int64>().value);
if (!n1) return t.commit(), false;
auto n2 = db.graph.vertices.find(t, args[1]->as<Int64>().value);
auto n2 = t.vertex_find(args[1]->as<Int64>().value);
if (!n2) return t.commit(), false;
auto r = db.graph.edges.insert(t, n2.vlist, n1.vlist);
auto r = t.edge_insert(n2.vlist, n1.vlist);
r.property("age", args[2]);
r.property("weight", args[3]);
auto &IS = db.graph.edge_type_store.find_or_create("IS");
auto &IS = t.type_find_or_create("IS");
r.edge_type(IS);
n2.vlist->update(t)->data.out.add(r.vlist);
n1.vlist->update(t)->data.in.add(r.vlist);
t.commit();
return true;
};
@ -146,11 +143,11 @@ auto load_queries(Db &db)
// MATCH (n) RETURN n
auto match_all_nodes = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto vertices_accessor = db.graph.vertices.access();
auto vertices_accessor = t.vertex_access();
for (auto &it : vertices_accessor) {
auto vertex = it.second.find(t);
auto vertex = it.second.find(*t);
if (vertex == nullptr) continue;
cout_properties(vertex->data.props);
}
@ -166,12 +163,11 @@ auto load_queries(Db &db)
// MATCH (n:LABEL) RETURN n
auto find_by_label = [&db](const properties_t &args) {
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto &label = db.graph.label_store.find_or_create("LABEL");
auto &label = t.label_find_or_create("LABEL");
auto &index_record_collection =
db.graph.vertices.find_label_index(label);
auto &index_record_collection = t.label_find_index(label);
auto accessor = index_record_collection.access();
cout << "VERTICES" << endl;
for (auto &v : accessor) {

View File

@ -3,31 +3,27 @@
#include "storage/edge.hpp"
#include "storage/edge_record.hpp"
#include "storage/record_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "utils/assert.hpp"
#include "utils/reference_wrapper.hpp"
class Edges;
// TODO: Edge, Db, Edge::Accessor
class Edge::Accessor
: public RecordAccessor<Edge, Edges, Edge::Accessor, EdgeRecord>
class Edge::Accessor : public RecordAccessor<Edge, Edge::Accessor, EdgeRecord>
{
public:
using RecordAccessor::RecordAccessor;
void edge_type(edge_type_ref_t edge_type)
{
this->record->data.edge_type = &edge_type.get();
}
void edge_type(edge_type_ref_t edge_type);
edge_type_ref_t edge_type() const
{
runtime_assert(this->record->data.edge_type != nullptr,
"EdgeType is null");
return edge_type_ref_t(*this->record->data.edge_type);
}
edge_type_ref_t edge_type() const;
auto from() const { return this->vlist->from(); }
Vertex::Accessor from() const;
auto to() const { return this->vlist->to(); }
Vertex::Accessor to() const;
VertexRecord *from_record() const;
VertexRecord *to_record() const;
};

View File

@ -8,8 +8,8 @@
class Edges
{
public:
Edge::Accessor find(tx::Transaction &t, const Id &id);
Edge::Accessor insert(tx::Transaction &t, VertexRecord *from,
Edge::Accessor find(DbTransaction &t, const Id &id);
Edge::Accessor insert(DbTransaction &t, VertexRecord *from,
VertexRecord *to);
private:

View File

@ -1,23 +1,29 @@
#pragma once
#include "database/db_transaction.hpp"
#include "mvcc/version_list.hpp"
#include "storage/model/properties/properties.hpp"
#include "storage/model/properties/property.hpp"
#include "transactions/transaction.hpp"
template <class T, class Store, class Derived,
class vlist_t = mvcc::VersionList<T>>
template <class T, class Derived, class vlist_t = mvcc::VersionList<T>>
class RecordAccessor
{
public:
RecordAccessor() = default;
RecordAccessor(DbTransaction &db) : db(db){};
RecordAccessor(T *record, vlist_t *vlist, Store *store)
: record(record), vlist(vlist), store(store)
RecordAccessor(T *t, vlist_t *vlist, DbTransaction &db)
: record(t), vlist(vlist), db(db)
{
assert(record != nullptr);
assert(vlist != nullptr);
}
RecordAccessor(vlist_t *vlist, DbTransaction &db)
: record(vlist->find(db.trans)), vlist(vlist), db(db)
{
assert(record != nullptr);
assert(vlist != nullptr);
assert(store != nullptr);
}
bool empty() const { return record == nullptr; }
@ -28,18 +34,18 @@ public:
return vlist->id;
}
Derived update(tx::Transaction &t) const
Derived update() const
{
assert(!empty());
return Derived(vlist->update(t), vlist, store);
return Derived(vlist->update(db.trans), vlist, db);
}
bool remove(tx::Transaction &t) const
bool remove() const
{
assert(!empty());
return vlist->remove(record, t);
return vlist->remove(record, db.trans);
}
const Property &property(const std::string &key) const
@ -65,5 +71,5 @@ public:
// protected:
T *const record{nullptr};
vlist_t *const vlist{nullptr};
Store *const store{nullptr};
DbTransaction &db;
};

View File

@ -5,8 +5,7 @@
class Vertices;
class Vertex::Accessor
: public RecordAccessor<Vertex, Vertices, Vertex::Accessor>
class Vertex::Accessor : public RecordAccessor<Vertex, Vertex::Accessor>
{
public:
using RecordAccessor::RecordAccessor;
@ -21,5 +20,5 @@ public:
bool has_label(const Label &label) const;
const std::set<label_ref_t>& labels() const;
const std::set<label_ref_t> &labels() const;
};

View File

@ -1,6 +1,7 @@
#pragma once
#include "data_structures/concurrent/concurrent_map.hpp"
#include "database/db_transaction.hpp"
#include "storage/common.hpp"
#include "storage/indexes/index.hpp"
#include "storage/indexes/index_record_collection.hpp"
@ -13,17 +14,17 @@ public:
vertices_t::Accessor access();
const Vertex::Accessor find(tx::Transaction &t, const Id &id);
const Vertex::Accessor find(DbTransaction &t, const Id &id);
const Vertex::Accessor first(tx::Transaction &t);
const Vertex::Accessor first(DbTransaction &t);
Vertex::Accessor insert(tx::Transaction &t);
Vertex::Accessor insert(DbTransaction &t);
void update_label_index(const Label &label,
VertexIndexRecord &&index_record);
VertexIndexRecordCollection& find_label_index(const Label& label);
VertexIndexRecordCollection &find_label_index(const Label &label);
private:
vertices_t vertices;
Index<label_ref_t, VertexIndexRecordCollection> label_index;

View File

@ -10,6 +10,7 @@
#include "data_structures/map/rh_hashmap.hpp"
#include "database/db.hpp"
#include "database/db_accessor.hpp"
using namespace std;
@ -92,20 +93,20 @@ double calc_heuristic_cost_dummy(Edge *edge, Vertex *vertex)
return 1 - vertex->data.props.at("score").as<Double>().value;
}
typedef bool (*EdgeFilter)(tx::Transaction &t, EdgeRecord *, Node *before);
typedef bool (*VertexFilter)(tx::Transaction &t, Vertex *, Node *before);
typedef bool (*EdgeFilter)(DbAccessor &t, EdgeRecord *, Node *before);
typedef bool (*VertexFilter)(DbAccessor &t, Vertex *, Node *before);
bool edge_filter_dummy(tx::Transaction &t, EdgeRecord *e, Node *before)
bool edge_filter_dummy(DbAccessor &t, EdgeRecord *e, Node *before)
{
return true;
}
bool vertex_filter_dummy(tx::Transaction &t, Vertex *v, Node *before)
bool vertex_filter_dummy(DbAccessor &t, Vertex *v, Node *before)
{
return true;
}
bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
bool vertex_filter_contained_dummy(DbAccessor &t, Vertex *v, Node *before)
{
bool found;
do {
@ -115,7 +116,7 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
return true;
}
for (auto edge : before->vertex->data.out) {
Vertex *e_v = edge->to()->find(t);
Vertex *e_v = edge->to()->find(*t);
if (e_v == v) {
found = true;
break;
@ -125,7 +126,7 @@ bool vertex_filter_contained_dummy(tx::Transaction &t, Vertex *v, Node *before)
return false;
}
bool vertex_filter_contained(tx::Transaction &t, Vertex *v, Node *before)
bool vertex_filter_contained(DbAccessor &t, Vertex *v, Node *before)
{
bool found;
do {
@ -146,14 +147,14 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
double (*calc_heuristic_cost)(Edge *edge, Vertex *vertex),
int limit)
{
auto &t = db.tx_engine.begin();
DbAccessor t(db);
RhHashMap<VertexRecord *, Node> visited;
auto cmp = [](Node *left, Node *right) { return left->cost > right->cost; };
std::priority_queue<Node *, std::vector<Node *>, decltype(cmp)> queue(cmp);
auto start_vr = db.graph.vertices.find(t, sys_id_start).vlist;
Node *start = new Node(start_vr->find(t), start_vr, 0);
auto start_vr = t.vertex_find(sys_id_start).vlist;
Node *start = new Node(start_vr->find(*t), start_vr, 0);
queue.push(start);
int count = 0;
do {
@ -175,11 +176,12 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
for (auto edge : now->vertex->data.out) {
if (e_filter[now->depth](t, edge, now)) {
Vertex *v = edge->to()->find(t);
Vertex *v = edge->to()->find(*t);
if (v_filter[now->depth](t, v, now)) {
Node *n = new Node(
v, edge->to(),
now->cost + calc_heuristic_cost(edge->find(t), v), now);
now->cost + calc_heuristic_cost(edge->find(*t), v),
now);
queue.push(n);
}
}
@ -207,7 +209,7 @@ void a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
int main()
{
Db db;
load_csv(db, "neo4j_nodes_export_2000.csv", "neo4j_edges_export_2000.csv");
load_csv(db, "graph_nodes_export.csv", "graph_edges_export.csv");
//
// load_graph_dummy(db);
//
@ -266,7 +268,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
std::string line;
auto &t = db.tx_engine.begin();
DbAccessor t(db);
int max_score = 1000000;
// VERTEX import
@ -276,7 +278,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
start_vertex_id = id;
}
auto vertex_accessor = db.graph.vertices.insert(t);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.property("id", std::make_shared<Int32>(id));
vertex_accessor.property("garment_id", std::make_shared<Int32>(gar_id));
vertex_accessor.property("garment_category_id",
@ -286,7 +288,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
"score", std::make_shared<Double>((std::rand() % max_score) /
(max_score + 0.0)));
for (auto l_name : labels) {
auto &label = db.graph.label_store.find_or_create(l_name);
auto &label = t.label_find_or_create(l_name);
vertex_accessor.add_label(label);
}
return vertex_accessor.id();
@ -309,7 +311,7 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
stoi(splited[splited.size() - 1]));
assert(va.size() == (uint64_t)id);
va.push_back(db.graph.vertices.find(t, id));
va.push_back(t.vertex_find(id));
}
// EDGE IMPORT
@ -318,12 +320,9 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
auto v2 = va[to - start_vertex_id];
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
auto &edge_type = t.type_find_or_create(type);
edge_accessor.edge_type(edge_type);
};
@ -343,9 +342,9 @@ void load_csv(Db &db, char *file_path, char *edge_file_path)
void load_graph_dummy(Db &db)
{
auto &t = db.tx_engine.begin();
DbAccessor t(db);
auto v = [&](auto id, auto score) {
auto vertex_accessor = db.graph.vertices.insert(t);
auto vertex_accessor = t.vertex_insert();
vertex_accessor.property("id", std::make_shared<Int32>(id));
vertex_accessor.property("score", std::make_shared<Double>(score));
return vertex_accessor.id();
@ -356,15 +355,13 @@ void load_graph_dummy(Db &db)
};
auto e = [&](auto from, auto type, auto to) {
auto v1 = db.graph.vertices.find(t, va[from]);
auto v1 = t.vertex_find(va[from]);
auto v2 = db.graph.vertices.find(t, va[to]);
auto v2 = t.vertex_find(va[to]);
auto edge_accessor = db.graph.edges.insert(t, v1.vlist, v2.vlist);
v1.vlist->update(t)->data.out.add(edge_accessor.vlist);
v2.vlist->update(t)->data.in.add(edge_accessor.vlist);
auto edge_accessor = t.edge_insert(v1.vlist, v2.vlist);
auto &edge_type = db.graph.edge_type_store.find_or_create(type);
auto &edge_type = t.type_find_or_create(type);
edge_accessor.edge_type(edge_type);
};

View File

@ -73,6 +73,6 @@ public:
build();
}
CypherLexer(CypherLexer& other) = delete;
CypherLexer(CypherLexer&& other) = default;
CypherLexer(CypherLexer &other) = delete;
CypherLexer(CypherLexer &&other) = default;
};

6
src/database/db.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "database/db.hpp"
Db::Db() = default;
Db::Db(const std::string &name) : name_(name) {}
std::string &Db::name() { return name_; }

View File

@ -0,0 +1,77 @@
#include "database/db_accessor.hpp"
DbAccessor::DbAccessor(Db &db) : db(DbTransaction(db, db.tx_engine.begin())) {}
// VERTEX METHODS
Vertices::vertices_t::Accessor DbAccessor::vertex_access()
{
return this->db.db.graph.vertices.access();
}
const Vertex::Accessor DbAccessor::vertex_find(const Id &id)
{
return this->db.db.graph.vertices.find(db, id);
}
const Vertex::Accessor DbAccessor::vertex_first()
{
return this->db.db.graph.vertices.first(db);
}
Vertex::Accessor DbAccessor::vertex_insert()
{
return this->db.db.graph.vertices.insert(db);
}
// EDGE METHODS
Edge::Accessor DbAccessor::edge_find(const Id &id)
{
return db.db.graph.edges.find(db, id);
}
Edge::Accessor DbAccessor::edge_insert(VertexRecord *from, VertexRecord *to)
{
auto edge_accessor = db.db.graph.edges.insert(db, from, to);
from->update(db.trans)->data.out.add(edge_accessor.vlist);
to->update(db.trans)->data.in.add(edge_accessor.vlist);
return edge_accessor;
}
// LABEL METHODS
const Label &DbAccessor::label_find_or_create(const std::string &name)
{
return db.db.graph.label_store.find_or_create(
std::forward<const std::string &>(name));
}
bool DbAccessor::label_contains(const std::string &name)
{
return db.db.graph.label_store.contains(
std::forward<const std::string &>(name));
}
VertexIndexRecordCollection &DbAccessor::label_find_index(const Label &label)
{
return db.db.graph.vertices.find_label_index(label);
}
// TYPE METHODS
const EdgeType &DbAccessor::type_find_or_create(const std::string &name)
{
return db.db.graph.edge_type_store.find_or_create(
std::forward<const std::string &>(name));
}
bool DbAccessor::type_contains(const std::string &name)
{
return db.db.graph.edge_type_store.contains(
std::forward<const std::string &>(name));
}
// TRANSACTION METHODS
void DbAccessor::commit() { db.trans.commit(); }
void DbAccessor::abort() { db.trans.abort(); }
// EASE OF USE METHODS
tx::Transaction &DbAccessor::operator*() { return db.trans; }

View File

@ -0,0 +1,8 @@
#include "database/db.hpp"
#include "database/db_transaction.hpp"
void DbTransaction::update_label_index(const Label &label,
VertexIndexRecord &&index_record)
{
db.graph.vertices.update_label_index(label, std::move(index_record));
}

View File

@ -0,0 +1,29 @@
#include "storage/edge_accessor.hpp"
void Edge::Accessor::edge_type(edge_type_ref_t edge_type)
{
this->record->data.edge_type = &edge_type.get();
}
edge_type_ref_t Edge::Accessor::edge_type() const
{
runtime_assert(this->record->data.edge_type != nullptr, "EdgeType is null");
return edge_type_ref_t(*this->record->data.edge_type);
}
Vertex::Accessor Edge::Accessor::from() const
{
return Vertex::Accessor(this->vlist->from(), this->db);
}
Vertex::Accessor Edge::Accessor::to() const
{
return Vertex::Accessor(this->vlist->to(), this->db);
}
VertexRecord *Edge::Accessor::from_record() const
{
return this->vlist->from();
}
VertexRecord *Edge::Accessor::to_record() const { return this->vlist->to(); }

View File

@ -1,21 +1,21 @@
#include "storage/edges.hpp"
Edge::Accessor Edges::find(tx::Transaction &t, const Id &id)
Edge::Accessor Edges::find(DbTransaction &t, const Id &id)
{
auto edges_accessor = edges.access();
auto edges_iterator = edges_accessor.find(id);
if (edges_iterator == edges_accessor.end()) return Edge::Accessor();
if (edges_iterator == edges_accessor.end()) return Edge::Accessor(t);
// find edge
auto edge = edges_iterator->second.find(t);
auto edge = edges_iterator->second.find(t.trans);
if (edge == nullptr) return Edge::Accessor();
if (edge == nullptr) return Edge::Accessor(t);
return Edge::Accessor(edge, &edges_iterator->second, this);
return Edge::Accessor(edge, &edges_iterator->second, t);
}
Edge::Accessor Edges::insert(tx::Transaction &t, VertexRecord *from,
Edge::Accessor Edges::insert(DbTransaction &t, VertexRecord *from,
VertexRecord *to)
{
// get next vertex id
@ -30,7 +30,7 @@ Edge::Accessor Edges::insert(tx::Transaction &t, VertexRecord *from,
// create new vertex
auto inserted_edge_record = result.first;
auto edge = inserted_edge_record->second.insert(t);
auto edge = inserted_edge_record->second.insert(t.trans);
return Edge::Accessor(edge, &inserted_edge_record->second, this);
return Edge::Accessor(edge, &inserted_edge_record->second, t);
}

View File

@ -1,5 +1,5 @@
#include "database/db.hpp"
#include "storage/vertex_accessor.hpp"
#include "storage/vertices.hpp"
size_t Vertex::Accessor::out_degree() const
@ -12,10 +12,7 @@ size_t Vertex::Accessor::in_degree() const
return this->record->data.in.degree();
}
size_t Vertex::Accessor::degree() const
{
return in_degree() + out_degree();
}
size_t Vertex::Accessor::degree() const { return in_degree() + out_degree(); }
void Vertex::Accessor::add_label(const Label &label)
{
@ -23,8 +20,8 @@ void Vertex::Accessor::add_label(const Label &label)
this->record->data.labels.add(label);
// update index
this->store->update_label_index(
label, VertexIndexRecord(this->record, this->vlist));
this->db.update_label_index(label,
VertexIndexRecord(this->record, this->vlist));
}
bool Vertex::Accessor::has_label(const Label &label) const
@ -32,7 +29,7 @@ bool Vertex::Accessor::has_label(const Label &label) const
return this->record->data.labels.has(label);
}
const std::set<label_ref_t>& Vertex::Accessor::labels() const
const std::set<label_ref_t> &Vertex::Accessor::labels() const
{
return this->record->data.labels();
}

View File

@ -1,41 +1,40 @@
#include "storage/vertices.hpp"
Vertices::vertices_t::Accessor Vertices::access()
{
return vertices.access();
}
Vertices::vertices_t::Accessor Vertices::access() { return vertices.access(); }
const Vertex::Accessor Vertices::find(tx::Transaction &t, const Id &id)
const Vertex::Accessor Vertices::find(DbTransaction &t, const Id &id)
{
auto vertices_accessor = vertices.access();
auto vertices_iterator = vertices_accessor.find(id);
if (vertices_iterator == vertices_accessor.end()) return Vertex::Accessor();
if (vertices_iterator == vertices_accessor.end())
return Vertex::Accessor(t);
// find vertex
auto vertex = vertices_iterator->second.find(t);
auto vertex = vertices_iterator->second.find(t.trans);
if (vertex == nullptr) return Vertex::Accessor();
if (vertex == nullptr) return Vertex::Accessor(t);
return Vertex::Accessor(vertex, &vertices_iterator->second, this);
return Vertex::Accessor(vertex, &vertices_iterator->second, t);
}
// TODO
const Vertex::Accessor Vertices::first(tx::Transaction &t)
const Vertex::Accessor Vertices::first(DbTransaction &t)
{
auto vertices_accessor = vertices.access();
auto vertices_iterator = vertices_accessor.begin();
if (vertices_iterator == vertices_accessor.end()) return Vertex::Accessor();
if (vertices_iterator == vertices_accessor.end())
return Vertex::Accessor(t);
auto vertex = vertices_iterator->second.find(t);
auto vertex = vertices_iterator->second.find(t.trans);
if (vertex == nullptr) return Vertex::Accessor();
if (vertex == nullptr) return Vertex::Accessor(t);
return Vertex::Accessor(vertex, &vertices_iterator->second, this);
return Vertex::Accessor(vertex, &vertices_iterator->second, t);
}
Vertex::Accessor Vertices::insert(tx::Transaction &t)
Vertex::Accessor Vertices::insert(DbTransaction &t)
{
// get next vertex id
auto next = counter.next();
@ -50,9 +49,9 @@ Vertex::Accessor Vertices::insert(tx::Transaction &t)
// create new vertex
auto inserted_vertex_record = result.first;
auto vertex = inserted_vertex_record->second.insert(t);
auto vertex = inserted_vertex_record->second.insert(t.trans);
return Vertex::Accessor(vertex, &inserted_vertex_record->second, this);
return Vertex::Accessor(vertex, &inserted_vertex_record->second, t);
}
void Vertices::update_label_index(const Label &label,