From 1849514159aee94f6783f957ae7a0c6a945ee068 Mon Sep 17 00:00:00 2001 From: Kruno Tomola Fabro <krunotf@memgraph.io> Date: Fri, 12 Aug 2016 23:01:39 +0100 Subject: [PATCH] First step in database accessor refactoring done. It's compiling. All tests with exception of integration_querys pass --- CMakeLists.txt | 10 ++- .../bolt/v1/serialization/bolt_serializer.hpp | 72 ++++++----------- include/database/db.hpp | 13 ++-- include/database/db_accessor.hpp | 50 ++++++++++++ include/database/db_transaction.hpp | 26 +++++++ include/query_engine/hardcode/queries.hpp | 72 ++++++++--------- include/storage/edge_accessor.hpp | 24 +++--- include/storage/edges.hpp | 4 +- include/storage/record_accessor.hpp | 28 ++++--- include/storage/vertex_accessor.hpp | 5 +- include/storage/vertices.hpp | 11 +-- poc/astar.cpp | 57 +++++++------- src/cypher/tokenizer/cypher_lexer.hpp | 4 +- src/database/db.cpp | 6 ++ src/database/db_accessor.cpp | 77 +++++++++++++++++++ src/database/db_transaction.cpp | 8 ++ src/storage/edge_accessor.cpp | 29 +++++++ src/storage/edges.cpp | 16 ++-- src/storage/vertex_accessor.cpp | 13 ++-- src/storage/vertices.cpp | 33 ++++---- 20 files changed, 359 insertions(+), 199 deletions(-) create mode 100644 include/database/db_accessor.hpp create mode 100644 include/database/db_transaction.hpp create mode 100644 src/database/db.cpp create mode 100644 src/database/db_accessor.cpp create mode 100644 src/database/db_transaction.cpp create mode 100644 src/storage/edge_accessor.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 74df3c068..9efec42c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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( diff --git a/include/communication/bolt/v1/serialization/bolt_serializer.hpp b/include/communication/bolt/v1/serialization/bolt_serializer.hpp index 6d7248b6f..f73f41d28 100644 --- a/include/communication/bolt/v1/serialization/bolt_serializer.hpp +++ b/include/communication/bolt/v1/serialization/bolt_serializer.hpp @@ -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; }; - } diff --git a/include/database/db.hpp b/include/database/db.hpp index 8cee20063..626bb7dd7 100644 --- a/include/database/db.hpp +++ b/include/database/db.hpp @@ -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_; diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp new file mode 100644 index 000000000..277a24171 --- /dev/null +++ b/include/database/db_accessor.hpp @@ -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; +}; diff --git a/include/database/db_transaction.hpp b/include/database/db_transaction.hpp new file mode 100644 index 000000000..5ddbbbc23 --- /dev/null +++ b/include/database/db_transaction.hpp @@ -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; +}; diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp index 0c19af658..9bce411e2 100644 --- a/include/query_engine/hardcode/queries.hpp +++ b/include/query_engine/hardcode/queries.hpp @@ -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) { diff --git a/include/storage/edge_accessor.hpp b/include/storage/edge_accessor.hpp index 192ce2884..b43612111 100644 --- a/include/storage/edge_accessor.hpp +++ b/include/storage/edge_accessor.hpp @@ -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; }; diff --git a/include/storage/edges.hpp b/include/storage/edges.hpp index 85e2e1cdd..5cc00b670 100644 --- a/include/storage/edges.hpp +++ b/include/storage/edges.hpp @@ -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: diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp index 327d43e27..bc65f4559 100644 --- a/include/storage/record_accessor.hpp +++ b/include/storage/record_accessor.hpp @@ -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; }; diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp index 6c02f2595..2d32b1f88 100644 --- a/include/storage/vertex_accessor.hpp +++ b/include/storage/vertex_accessor.hpp @@ -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; }; diff --git a/include/storage/vertices.hpp b/include/storage/vertices.hpp index 9b4909ebe..6f668514c 100644 --- a/include/storage/vertices.hpp +++ b/include/storage/vertices.hpp @@ -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; diff --git a/poc/astar.cpp b/poc/astar.cpp index f30f1664d..1b564c02c 100644 --- a/poc/astar.cpp +++ b/poc/astar.cpp @@ -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); }; diff --git a/src/cypher/tokenizer/cypher_lexer.hpp b/src/cypher/tokenizer/cypher_lexer.hpp index 42b4783ee..ed83cddfc 100644 --- a/src/cypher/tokenizer/cypher_lexer.hpp +++ b/src/cypher/tokenizer/cypher_lexer.hpp @@ -73,6 +73,6 @@ public: build(); } - CypherLexer(CypherLexer& other) = delete; - CypherLexer(CypherLexer&& other) = default; + CypherLexer(CypherLexer &other) = delete; + CypherLexer(CypherLexer &&other) = default; }; diff --git a/src/database/db.cpp b/src/database/db.cpp new file mode 100644 index 000000000..9ceb50a77 --- /dev/null +++ b/src/database/db.cpp @@ -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_; } diff --git a/src/database/db_accessor.cpp b/src/database/db_accessor.cpp new file mode 100644 index 000000000..588e10f82 --- /dev/null +++ b/src/database/db_accessor.cpp @@ -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; } diff --git a/src/database/db_transaction.cpp b/src/database/db_transaction.cpp new file mode 100644 index 000000000..3760ce479 --- /dev/null +++ b/src/database/db_transaction.cpp @@ -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)); +} diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp new file mode 100644 index 000000000..396234850 --- /dev/null +++ b/src/storage/edge_accessor.cpp @@ -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(); } diff --git a/src/storage/edges.cpp b/src/storage/edges.cpp index 22a3d4810..b4dc90fb7 100644 --- a/src/storage/edges.cpp +++ b/src/storage/edges.cpp @@ -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); } diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp index 380f30495..122ca7381 100644 --- a/src/storage/vertex_accessor.cpp +++ b/src/storage/vertex_accessor.cpp @@ -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(); } diff --git a/src/storage/vertices.cpp b/src/storage/vertices.cpp index ff94cb7dc..30634f67a 100644 --- a/src/storage/vertices.cpp +++ b/src/storage/vertices.cpp @@ -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,