From 4542b56c188b4ec2218df538497c41e1e08076e8 Mon Sep 17 00:00:00 2001 From: Kruno Tomola Fabro <krunotf@memgraph.io> Date: Tue, 30 Aug 2016 02:32:31 +0100 Subject: [PATCH] tmp commit --- include/barrier/barrier.hpp | 23 +++- include/barrier/trans.hpp | 8 +- include/database/db_accessor.hpp | 8 ++ include/query_engine/hardcode/queries.hpp | 134 ++++++++++++++++++---- include/utils/iterator/filter.hpp | 52 +++++++++ include/utils/iterator/for_all.hpp | 13 +++ poc/profile.hpp | 13 --- src/barrier/barrier.cpp | 15 ++- 8 files changed, 227 insertions(+), 39 deletions(-) create mode 100644 include/utils/iterator/filter.hpp diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp index e201b9d61..748358c54 100644 --- a/include/barrier/barrier.hpp +++ b/include/barrier/barrier.hpp @@ -25,6 +25,7 @@ class EdgeIterator; // TYPED ITERATORS class VertexAccessIterator; +class EdgeAccessIterator; class OutEdgesIterator; class InEdgesIterator; @@ -247,6 +248,8 @@ public: VertexAccessor vertex_insert(); + EdgeAccessIterator edge_access(); + Option<const EdgeAccessor> edge_find(const Id &id); EdgeAccessor edge_insert(VertexAccessor const &from, @@ -309,6 +312,22 @@ public: Option<const VertexAccessor> next(); }; +// TODO: Find reasons of such great size ant try to decrease it. +class EdgeAccessIterator : private Sized<552, 8> +{ +public: + template <class T> + EdgeAccessIterator(T &&d); + + EdgeAccessIterator(const EdgeAccessIterator &other) = delete; + EdgeAccessIterator(EdgeAccessIterator &&other); + ~EdgeAccessIterator(); + EdgeAccessIterator &operator=(const EdgeAccessIterator &other) = delete; + EdgeAccessIterator &operator=(EdgeAccessIterator &&other) = delete; + + Option<const EdgeAccessor> next(); +}; + class OutEdgesIterator : private Sized<40, 8> { public: @@ -442,10 +461,10 @@ public: void write_success_empty(); void write_ignored(); void write_fields(const std::vector<std::string> &fields); - void write_field(const std::string& field); + void write_field(const std::string &field); void write_list_header(size_t size); void write_record(); - void write_meta(const std::string& type); + void write_meta(const std::string &type); void send(); void chunk(); }; diff --git a/include/barrier/trans.hpp b/include/barrier/trans.hpp index af7c8ad76..2aa927d98 100644 --- a/include/barrier/trans.hpp +++ b/include/barrier/trans.hpp @@ -5,9 +5,9 @@ // This is the place for imports from memgraph .hpp #include "communication/bolt/v1/serialization/bolt_serializer.hpp" #include "communication/bolt/v1/serialization/record_stream.hpp" -#include "io/network/socket.hpp" #include "database/db.hpp" #include "database/db_accessor.hpp" +#include "io/network/socket.hpp" #include "storage/edge_type/edge_type.hpp" #include "storage/edge_x_vertex.hpp" #include "storage/label/label.hpp" @@ -126,6 +126,9 @@ using vertex_access_iterator_t = decltype(((::DbAccessor *)(std::nullptr_t()))->vertex_access()); +using edge_access_iterator_t = + decltype(((::DbAccessor *)(std::nullptr_t()))->edge_access()); + using out_edge_iterator_t = decltype(((::VertexAccessor *)(std::nullptr_t()))->out()); @@ -160,6 +163,7 @@ TRANSFORM_REF(VertexIterator, TRANSFORM_REF(EdgeIterator, std::unique_ptr<IteratorBase<const ::EdgeAccessor>>); TRANSFORM_REF(VertexAccessIterator, vertex_access_iterator_t); +TRANSFORM_REF(EdgeAccessIterator, edge_access_iterator_t); TRANSFORM_REF(OutEdgesIterator, out_edge_iterator_t); TRANSFORM_REF(InEdgesIterator, in_edge_iterator_t); @@ -190,6 +194,8 @@ TRANSFORM_VALUE(VertexPropertyKey, ::VertexPropertyFamily::PropertyType::PropertyFamilyKey); TRANSFORM_VALUE_ONE(VertexAccessIterator, vertex_access_iterator_t); MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t); +TRANSFORM_VALUE_ONE(EdgeAccessIterator, edge_access_iterator_t); +MOVE_CONSTRUCTOR_FORCED(EdgeAccessIterator, edge_access_iterator_t); TRANSFORM_VALUE_ONE(OutEdgesIterator, out_edge_iterator_t); MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t); TRANSFORM_VALUE_ONE(InEdgesIterator, in_edge_iterator_t); diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp index 8614a341a..8df93dfb8 100644 --- a/include/database/db_accessor.hpp +++ b/include/database/db_accessor.hpp @@ -69,6 +69,14 @@ public: VertexAccessor vertex_insert(); // ******************* EDGE METHODS + auto edge_access() + { + return iter::make_map( + iter::make_iter(this->db_transaction.db.graph.edges.access()), + [&](auto e) -> auto { + return EdgeAccessor(&(e->second), db_transaction); + }); + } Option<const EdgeAccessor> edge_find(const Id &id); diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp index f50d7c0c4..11b7bfa5a 100644 --- a/include/query_engine/hardcode/queries.hpp +++ b/include/query_engine/hardcode/queries.hpp @@ -20,8 +20,7 @@ auto load_queries(Db &db) auto vertex_accessor = t.vertex_insert(); vertex_accessor.set(prop_key, args[0]); - t.commit(); - return true; + return t.commit(); }; queries[11597417457737499503u] = create_node; @@ -34,8 +33,7 @@ auto load_queries(Db &db) vertex_accessor.set(prop_key, args[0]); vertex_accessor.add_label(label); // cout_properties(vertex_accessor.properties()); - t.commit(); - return true; + return t.commit(); }; auto create_account = [&db](const properties_t &args) { @@ -53,8 +51,7 @@ auto load_queries(Db &db) vertex_accessor.set(prop_created, args[3]); vertex_accessor.add_label(label); // cout_properties(vertex_accessor.properties()); - t.commit(); - return true; + return t.commit(); }; auto find_node_by_internal_id = [&db](const properties_t &args) { @@ -71,8 +68,7 @@ auto load_queries(Db &db) for (auto label_ref : vertex_accessor.labels()) { // cout << label_ref.get() << endl; } - t.commit(); - return true; + return t.commit(); }; auto create_edge = [&db](const properties_t &args) { @@ -89,13 +85,13 @@ auto load_queries(Db &db) edge_accessor.edge_type(edge_type); - t.commit(); + bool ret = t.commit(); // cout << edge_accessor.edge_type() << endl; // cout_properties(edge_accessor.properties()); - return true; + return ret; }; auto find_edge_by_internal_id = [&db](const properties_t &args) { @@ -119,9 +115,7 @@ auto load_queries(Db &db) cout << "TO:" << endl; // cout_properties(to->data.props); - t.commit(); - - return true; + return t.commit(); }; auto update_node = [&db](const properties_t &args) { @@ -135,9 +129,7 @@ auto load_queries(Db &db) v.set(prop_name, args[1]); // cout_properties(v.properties()); - t.commit(); - - return true; + return t.commit(); }; // MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25, @@ -158,8 +150,7 @@ auto load_queries(Db &db) auto &IS = t.type_find_or_create("IS"); r.edge_type(IS); - t.commit(); - return true; + return t.commit(); }; // MATCH (n) RETURN n @@ -172,7 +163,7 @@ auto load_queries(Db &db) } }); - return t.commit(), true; + return t.commit(); }; // MATCH (n:LABEL) RETURN n @@ -186,9 +177,106 @@ auto load_queries(Db &db) iter::for_all(label.index().for_range(t), [&](auto a) { cout << a.at(prop_key) << endl; }); - return t.commit(), true; + return t.commit(); }; + // MATCH (n) DELETE n + auto match_all_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + iter::for_all(t.vertex_access(), [&](auto a) { + if (a.fill()) { + a.remove(); + } + }); + + return t.commit(); + }; + + // MATCH (n:LABEL) DELETE n + auto match_label_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + auto &label = t.label_find_or_create("LABEL"); + + iter::for_all(label.index().for_range(t), [&](auto a) { + if (a.fill()) { + a.remove(); + } + }); + + return t.commit(); + }; + + // MATCH (n) WHERE ID(n) = id DELETE n + auto match_id_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + auto ov = t.vertex_find(args[0]->as<Int64>().value); + if (!option_fill(ov)) return t.commit(), false; + + auto v = ov.take(); + v.remove(); + + return t.commit(); + }; + + // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r + auto match_edge_id_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + auto ov = t.edge_find(args[0]->as<Int64>().value); + if (!option_fill(ov)) return t.commit(), false; + + auto v = ov.take(); + v.remove(); + + return t.commit(); + }; + + // MATCH ()-[r]-() DELETE r + auto match_edge_all_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + iter::for_all(t.edge_access(), [&](auto a) { + if (a.fill()) { + a.remove(); + } + }); + + return t.commit(); + }; + + // MATCH ()-[r:TYPE]-() DELETE r + auto match_edge_type_delete = [&db](const properties_t &args) { + DbAccessor t(db); + + auto &type = t.type_find_or_create("TYPE"); + + iter::for_all(type.index().for_range(t), [&](auto a) { + if (a.fill()) { + a.remove(); + } + }); + + return t.commit(); + }; + + // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r + auto = [&db](const properties_t &args) { + DbAccessor t(db); + + return t.commit(); + }; + + // Blueprint: + // auto = [&db](const properties_t &args) { + // DbAccessor t(db); + // + // + // return t.commit(); + // }; + queries[15284086425088081497u] = match_all_nodes; queries[4857652843629217005u] = match_by_label; queries[15648836733456301916u] = create_edge_v2; @@ -199,6 +287,12 @@ auto load_queries(Db &db) queries[11198568396549106428u] = find_node_by_internal_id; queries[8320600413058284114u] = find_edge_by_internal_id; queries[6813335159006269041u] = update_node; + queries[10506105811763742758u] = match_all_delete; + queries[13742779491897528506u] = match_label_delete; + queries[11349462498691305864u] = match_id_delete; + queries[6963549500479100885u] = match_edge_id_delete; + queries[14897166600223619735u] = match_edge_all_delete; + queries[16888549834923624215u] = match_edge_type_delete; return queries; } diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp new file mode 100644 index 000000000..ddbc45700 --- /dev/null +++ b/include/utils/iterator/filter.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "utils/iterator/iterator_base.hpp" +#include "utils/option.hpp" + +namespace iter +{ + +// Class which maps values returned by I iterator into value of type T with OP +// function. +// T - type of return value +// I - iterator type +// OP - type of mapper function +template <class T, class I, class OP> +class Map : public IteratorBase<T> +{ + +public: + Map() = delete; + + // Map operation is designed to be used in chained calls which operate on a + // iterator. Map will in that usecase receive other iterator by value and + // std::move is a optimization for it. + Map(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {} + + Map(Map &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {} + + ~Map() final {} + + Option<T> next() final + { + auto item = iter.next(); + if (item.is_present()) { + return Option<T>(op(item.take())); + } else { + return Option<T>(); + } + } + +private: + I iter; + OP op; +}; + +template <class I, class OP> +auto make_map(I &&iter, OP &&op) +{ + // Compiler cant deduce type T. decltype is here to help with it. + return Map<decltype(op(iter.next().take())), I, OP>(std::move(iter), + std::move(op)); +} +} diff --git a/include/utils/iterator/for_all.hpp b/include/utils/iterator/for_all.hpp index 043f2c882..d68344aff 100644 --- a/include/utils/iterator/for_all.hpp +++ b/include/utils/iterator/for_all.hpp @@ -25,4 +25,17 @@ void for_all(std::unique_ptr<I> &&iter, C &&consumer) e = iter->next(); } } + +template <class I, class C> +void find(I iter, C &&consumer) +{ + auto e = iter.next(); + while (e.is_present()) { + + if (consumer(e.take())) { + return; + } + e = iter.next(); + } +} } diff --git a/poc/profile.hpp b/poc/profile.hpp index 9e4548f21..0dea2abca 100644 --- a/poc/profile.hpp +++ b/poc/profile.hpp @@ -115,19 +115,6 @@ void for_all_fill(I iter, C &&consumer) } } -template <class I, class C> -void find(I iter, C &&consumer) -{ - auto e = iter.next(); - while (e.is_present()) { - - if (consumer(e.take())) { - return; - } - e = iter.next(); - } -} - template <class I, class C> void find_fill(I iter, C &&consumer) { diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp index 7031230bd..a2630d0a3 100644 --- a/src/barrier/barrier.cpp +++ b/src/barrier/barrier.cpp @@ -148,6 +148,8 @@ Option<const VertexAccessor> DbAccessor::vertex_find(const Id &id) VertexAccessor DbAccessor::vertex_insert() { return CALL(vertex_insert()); } +EdgeAccessIterator DbAccessor::edge_access() { return CALL(edge_access()); } + Option<const EdgeAccessor> DbAccessor::edge_find(const Id &id) { return HALF_CALL(edge_find(id)).map<const EdgeAccessor>(); @@ -467,6 +469,14 @@ Option<const VertexAccessor> VertexAccessIterator::next() return HALF_CALL(next()).map<const VertexAccessor>(); } +// ************************* EdgeAccessIterator +DESTRUCTOR(EdgeAccessIterator, edge_access_iterator_t); + +Option<const EdgeAccessor> EdgeAccessIterator::next() +{ + return HALF_CALL(next()).map<const EdgeAccessor>(); +} + // ************************* VertexPropertyKey DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey); @@ -596,7 +606,7 @@ void RecordStream<Stream>::write_fields(const std::vector<std::string> &fields) } template <class Stream> -void RecordStream<Stream>::write_field(const std::string& field) +void RecordStream<Stream>::write_field(const std::string &field) { HALF_CALL(write_field(field)); } @@ -614,7 +624,7 @@ void RecordStream<Stream>::write_record() } template <class Stream> -void RecordStream<Stream>::write_meta(const std::string& type) +void RecordStream<Stream>::write_meta(const std::string &type) { HALF_CALL(write_meta(type)); } @@ -632,7 +642,6 @@ void RecordStream<Stream>::chunk() } template class RecordStream<io::Socket>; - } // **************************** ERROR EXAMPLES ****************************** //