From 0f7d8a68dc8036cfc0b64dd3d2bea6203721b253 Mon Sep 17 00:00:00 2001 From: Kruno Tomola Fabro <krunotf@memgraph.io> Date: Tue, 23 Aug 2016 14:16:54 +0100 Subject: [PATCH 1/3] Tmp commit. --- include/utils/iterator/filter.hpp | 49 +++++++++++++++++++++++++++++ include/utils/iterator/iterator.hpp | 1 + include/utils/iterator/query.hpp | 29 +++++++++++++++++ poc/tool.cpp | 3 +- 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 include/utils/iterator/filter.hpp create mode 100644 include/utils/iterator/query.hpp diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp new file mode 100644 index 000000000..2a45d23fe --- /dev/null +++ b/include/utils/iterator/filter.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "utils/iterator/iterator_base.hpp" +#include "utils/option.hpp" + +namespace iter +{ + +// Class which filters values T returned by I iterator if OP returns true for +// them. +// T - type of return value +// I - iterator type +// OP - type of filter function +template <class T, class I, class OP> +class Filter : public IteratorBase<T> +{ + +public: + Filter() = delete; + + // Filter operation is designed to be used in chained calls which operate on + // a + // iterator. Filter will in that usecase receive other iterator by value and + // std::move is a optimization for it. + Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {} + + Option<T> next() final + { + auto item = iter.next(); + if (item.is_present() && op(item.get())) { + return std::move(item); + } else { + return Option<T>(); + } + } + +private: + I iter; + OP op; +}; + +template <class I, class OP> +auto make_filter(I &&iter, OP &&op) +{ + // Compiler cant deduce type T. decltype is here to help with it. + return Filter<decltype(iter.next().take()), I, OP>(std::move(iter), + std::move(op)); +} +} diff --git a/include/utils/iterator/iterator.hpp b/include/utils/iterator/iterator.hpp index 93e48a67d..8a42b10ac 100644 --- a/include/utils/iterator/iterator.hpp +++ b/include/utils/iterator/iterator.hpp @@ -1,6 +1,7 @@ #pragma once #include "utils/iterator/accessor.hpp" +#include "utils/iterator/filter.hpp" #include "utils/iterator/for_all.hpp" #include "utils/iterator/iterator_accessor.hpp" #include "utils/iterator/iterator_base.hpp" diff --git a/include/utils/iterator/query.hpp b/include/utils/iterator/query.hpp new file mode 100644 index 000000000..b3fa64365 --- /dev/null +++ b/include/utils/iterator/query.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "storage/vertex_accessor.hpp" +#include "utils/iterator/iterator.hpp" +#include "utils/option.hpp" + +namespace query_help +{ + +template <class A> +bool fill(A &a) +{ + return a.fill(); +} +}; + +// Base iterator for next() kind iterator. +// Vertex::Accessor - type of return value +template <> +class IteratorBase<Vertex::Accessor> +{ +public: + virtual Option<Vertex::Accessor> next() = 0; + + auto fill() + { + return iter::make_filter(std::move(*this), query_help::fill); + } +}; diff --git a/poc/tool.cpp b/poc/tool.cpp index 616db34f2..a60ee9ae7 100644 --- a/poc/tool.cpp +++ b/poc/tool.cpp @@ -13,6 +13,7 @@ #include "storage/record_accessor.cpp" #include "storage/vertex_accessor.cpp" #include "utils/command_line/arguments.hpp" +#include "utils/iterator/query.hpp" using namespace std; @@ -164,7 +165,7 @@ void oportunity_employe_company( const EdgeType &type_created, const EdgeType &type_works_in, const Label &label_company) { - iter::for_all_fill(va.in(), [&](auto opp_e) { + iter::for_all(va.in().fill(), [&](auto opp_e) { // cout << " oec.in()" << endl; from_fill(opp_e, type_created, [&](auto creator) { // cout << " type_created" << endl; 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 2/3] 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 ****************************** // From 57a3c053e82d564eedc2446047443e323f211418 Mon Sep 17 00:00:00 2001 From: Kruno Tomola Fabro <krunotf@memgraph.io> Date: Tue, 30 Aug 2016 02:32:53 +0100 Subject: [PATCH 3/3] tmp commit --- include/query_engine/hardcode/queries.hpp | 14 ++++++++++---- include/utils/iterator/filter.hpp | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp index 11b7bfa5a..8d1a0c86b 100644 --- a/include/query_engine/hardcode/queries.hpp +++ b/include/query_engine/hardcode/queries.hpp @@ -221,7 +221,7 @@ auto load_queries(Db &db) return t.commit(); }; - // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r + // MATCH ()-[r]-() WHERE ID(r) = id DELETE r auto match_edge_id_delete = [&db](const properties_t &args) { DbAccessor t(db); @@ -262,11 +262,17 @@ auto load_queries(Db &db) return t.commit(); }; - // MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r - auto = [&db](const properties_t &args) { + // MATCH (n)-[:TYPE]->(m) WHERE ID(n) = id RETURN m + auto match_type_id_return = [&db](const properties_t &args) { DbAccessor t(db); - return t.commit(); + auto ov = t.vertex_find(args[0]->as<Int64>().value); + if (!option_fill(ov)) return t.commit(), false; + auto v = ov.take(); + + auto resoults = iter::make_f` + + return t.commit(); }; // Blueprint: diff --git a/include/utils/iterator/filter.hpp b/include/utils/iterator/filter.hpp index ddbc45700..fc908f19c 100644 --- a/include/utils/iterator/filter.hpp +++ b/include/utils/iterator/filter.hpp @@ -6,26 +6,28 @@ namespace iter { -// Class which maps values returned by I iterator into value of type T with OP +// Class which filters 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> +class Filter : public IteratorBase<T> { public: - Map() = delete; + Filter() = 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 + // Filter operation is designed to be used in chained calls which operate on + // a + // iterator. Filter 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)) {} + Filter(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)) {} + Filter(Filter &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {} - ~Map() final {} + ~Filter() final {} Option<T> next() final { @@ -46,7 +48,7 @@ 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)); + return Filter<decltype(op(iter.next().take())), I, OP>(std::move(iter), + std::move(op)); } }