Merge branch 'dev' of https://phabricator.tomicevic.com/diffusion/MG/memgraph into dev
This commit is contained in:
commit
5dcba58d2b
@ -418,6 +418,7 @@ set(memgraph_src_files
|
||||
${src_dir}/utils/string/transform.cpp
|
||||
${src_dir}/utils/string/join.cpp
|
||||
${src_dir}/utils/string/file.cpp
|
||||
${src_dir}/utils/iterator/iterator_base.cpp
|
||||
${src_dir}/query_engine/util.cpp
|
||||
${src_dir}/communication/bolt/v1/bolt.cpp
|
||||
${src_dir}/communication/bolt/v1/states.cpp
|
||||
|
@ -25,6 +25,7 @@ class EdgeIterator;
|
||||
|
||||
// TYPED ITERATORS
|
||||
class VertexAccessIterator;
|
||||
class EdgeAccessIterator;
|
||||
class OutEdgesIterator;
|
||||
class InEdgesIterator;
|
||||
|
||||
@ -63,8 +64,8 @@ using label_ref_t = ReferenceWrapper<const Label>;
|
||||
// Original class should have Sized barrier class if it can't be Unsized.
|
||||
// Sized barrier classes should:
|
||||
// --Have same name as original class.
|
||||
// --Inherit Sized class from common.hpp as private. Blueprint:
|
||||
// class class_name: Sized<size_of_t,aligment_of_t>
|
||||
// --Inherit Sized class from common.hpp as public. Blueprint:
|
||||
// class class_name: public Sized<size_of_t,aligment_of_t>
|
||||
// --Sized template arguments must be hardcoded numbers equal to sizeof(T) and
|
||||
// alignof(T) where T is original class.
|
||||
// --It should have undefined public constructor which is specialized in .cpp
|
||||
@ -82,7 +83,7 @@ using label_ref_t = ReferenceWrapper<const Label>;
|
||||
// --It should specify public methods which can be called on the original class.
|
||||
//
|
||||
// Blueprint:
|
||||
// class class_name : private Sized<,>
|
||||
// class class_name : public Sized<,>
|
||||
// {
|
||||
// public:
|
||||
// template <class T>
|
||||
@ -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,
|
||||
@ -278,7 +281,8 @@ public:
|
||||
void abort();
|
||||
};
|
||||
|
||||
class VertexIterator : private Sized<8, 8>
|
||||
class VertexIterator : public Sized<8, 8>,
|
||||
public IteratorBase<const VertexAccessor>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
@ -290,11 +294,14 @@ public:
|
||||
VertexIterator &operator=(const VertexIterator &other) = delete;
|
||||
VertexIterator &operator=(VertexIterator &&other) = delete;
|
||||
|
||||
Option<const VertexAccessor> next();
|
||||
Option<const VertexAccessor> next() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
// TODO: Find reasons of such great size ant try to decrease it.
|
||||
class VertexAccessIterator : private Sized<552, 8>
|
||||
class VertexAccessIterator : public Sized<560, 8>,
|
||||
public IteratorBase<const VertexAccessor>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
@ -306,10 +313,32 @@ public:
|
||||
VertexAccessIterator &operator=(const VertexAccessIterator &other) = delete;
|
||||
VertexAccessIterator &operator=(VertexAccessIterator &&other) = delete;
|
||||
|
||||
Option<const VertexAccessor> next();
|
||||
Option<const VertexAccessor> next() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
class OutEdgesIterator : private Sized<40, 8>
|
||||
// TODO: Find reasons of such great size ant try to decrease it.
|
||||
class EdgeAccessIterator : public Sized<560, 8>,
|
||||
public IteratorBase<const EdgeAccessor>
|
||||
{
|
||||
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() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
class OutEdgesIterator : public Sized<48, 8>,
|
||||
public IteratorBase<const EdgeAccessor>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
@ -321,10 +350,13 @@ public:
|
||||
OutEdgesIterator &operator=(const OutEdgesIterator &other) = delete;
|
||||
OutEdgesIterator &operator=(OutEdgesIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
Option<const EdgeAccessor> next() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
class InEdgesIterator : private Sized<56, 8>
|
||||
class InEdgesIterator : public Sized<64, 8>,
|
||||
public IteratorBase<const EdgeAccessor>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
@ -336,10 +368,12 @@ public:
|
||||
InEdgesIterator &operator=(const InEdgesIterator &other) = delete;
|
||||
InEdgesIterator &operator=(InEdgesIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
Option<const EdgeAccessor> next() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
class EdgeIterator : private Sized<8, 8>
|
||||
class EdgeIterator : public Sized<8, 8>, public IteratorBase<const EdgeAccessor>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
@ -351,7 +385,9 @@ public:
|
||||
EdgeIterator &operator=(const EdgeIterator &other) = delete;
|
||||
EdgeIterator &operator=(EdgeIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
Option<const EdgeAccessor> next() final;
|
||||
|
||||
Count count() final;
|
||||
};
|
||||
|
||||
class VertexPropertyKey : private Sized<8, 8>
|
||||
@ -442,10 +478,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();
|
||||
};
|
||||
|
@ -121,6 +121,18 @@ protected:
|
||||
"Border class aligment mismatch");
|
||||
}
|
||||
|
||||
public:
|
||||
typename std::aligned_storage<size_B, alignment_B>::type &_data_ref()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
typename std::aligned_storage<size_B, alignment_B>::type const &
|
||||
_data_ref_const() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
// Here is the aligned storage which imitates size and aligment of object of
|
||||
// original class from memgraph.
|
||||
|
@ -5,13 +5,15 @@
|
||||
// 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"
|
||||
|
||||
// This is the place for imports from memgraph .cpp
|
||||
|
||||
// **************************** HELPER DEFINES *******************************//
|
||||
// Creates 8 functions for transformation of refereces between types x and y.
|
||||
// Where x is a border type.
|
||||
@ -26,6 +28,21 @@
|
||||
y *trans(x *l) { return ptr_as<y>(l); } \
|
||||
y const *trans(x const *l) { return ptr_as<y const>(l); }
|
||||
|
||||
// Creates 4 functions for transformation of refereces between types x and y.
|
||||
// Where x is a sized border type.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_REF_SIZED(x, y) \
|
||||
y &trans(x &l) { return ref_as<y>(l._data_ref()); } \
|
||||
y const &trans(x const &l) \
|
||||
{ \
|
||||
return ref_as<y const>(l._data_ref_const()); \
|
||||
} \
|
||||
y *trans(x *l) { return ptr_as<y>(&(l->_data_ref())); } \
|
||||
y const *trans(x const *l) \
|
||||
{ \
|
||||
return ptr_as<y const>(&(l->_data_ref_const())); \
|
||||
}
|
||||
|
||||
// Creates 8 functions for transformation of refereces between types x and y.
|
||||
// Where both x and y are templates over T. Where x is a border type.
|
||||
// DANGEROUS
|
||||
@ -126,6 +143,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());
|
||||
|
||||
@ -155,13 +175,16 @@ TRANSFORM_REF(VertexPropertyKey,
|
||||
::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
TRANSFORM_REF(EdgePropertyKey,
|
||||
::EdgePropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
TRANSFORM_REF(VertexIterator,
|
||||
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
|
||||
TRANSFORM_REF(EdgeIterator,
|
||||
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
|
||||
TRANSFORM_REF(VertexAccessIterator, vertex_access_iterator_t);
|
||||
TRANSFORM_REF(OutEdgesIterator, out_edge_iterator_t);
|
||||
TRANSFORM_REF(InEdgesIterator, in_edge_iterator_t);
|
||||
|
||||
// ITERATORS
|
||||
TRANSFORM_REF_SIZED(VertexIterator,
|
||||
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
|
||||
TRANSFORM_REF_SIZED(EdgeIterator,
|
||||
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
|
||||
TRANSFORM_REF_SIZED(VertexAccessIterator, vertex_access_iterator_t);
|
||||
TRANSFORM_REF_SIZED(EdgeAccessIterator, edge_access_iterator_t);
|
||||
TRANSFORM_REF_SIZED(OutEdgesIterator, out_edge_iterator_t);
|
||||
TRANSFORM_REF_SIZED(InEdgesIterator, in_edge_iterator_t);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(VertexIndex<T>, VertexIndexBase<T>);
|
||||
@ -189,19 +212,22 @@ TRANSFORM_VALUE(EdgePropertyKey,
|
||||
TRANSFORM_VALUE(VertexPropertyKey,
|
||||
::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
TRANSFORM_VALUE_ONE(VertexAccessIterator, vertex_access_iterator_t);
|
||||
MOVE_CONSTRUCTOR_FORCED(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);
|
||||
// MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
|
||||
TRANSFORM_VALUE_ONE(InEdgesIterator, in_edge_iterator_t);
|
||||
MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
|
||||
// MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
|
||||
TRANSFORM_VALUE_ONE(VertexIterator,
|
||||
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
|
||||
MOVE_CONSTRUCTOR_FORCED(VertexIterator,
|
||||
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
|
||||
// MOVE_CONSTRUCTOR_FORCED(VertexIterator,
|
||||
// std::unique_ptr<IteratorBase<const
|
||||
// ::VertexAccessor>>);
|
||||
TRANSFORM_VALUE_ONE(EdgeIterator,
|
||||
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
|
||||
MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
|
||||
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
|
||||
// MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
|
||||
// std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_VALUE_ONE_RAW(
|
||||
|
@ -62,6 +62,8 @@ public:
|
||||
|
||||
~AccessorBase() {}
|
||||
|
||||
size_t size() { return accessor.size(); };
|
||||
|
||||
list_it begin() { return accessor.begin(); }
|
||||
|
||||
list_it_con begin() const { return accessor.cbegin(); }
|
||||
|
@ -281,6 +281,8 @@ public:
|
||||
|
||||
ConstIterator cend() { return ConstIterator(); }
|
||||
|
||||
std::size_t size() { return count.load(std::memory_order_consume); }
|
||||
|
||||
private:
|
||||
std::atomic<std::size_t> count{0};
|
||||
std::atomic<Node *> head{nullptr};
|
||||
|
@ -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);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <map>
|
||||
|
||||
#include "barrier/barrier.hpp"
|
||||
#include "utils/iterator/iterator_base.cpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -20,8 +21,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 +34,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 +52,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 +69,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 +86,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 +116,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 +130,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,21 +151,17 @@ 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
|
||||
auto match_all_nodes = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
iter::for_all(t.vertex_access(), [&](auto vertex) {
|
||||
if (vertex.fill()) {
|
||||
cout << vertex.id() << endl;
|
||||
}
|
||||
});
|
||||
t.vertex_access().fill().for_all(
|
||||
[&](auto vertex) { cout << vertex.id() << endl; });
|
||||
|
||||
return t.commit(), true;
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n:LABEL) RETURN n
|
||||
@ -183,12 +172,123 @@ auto load_queries(Db &db)
|
||||
auto prop_key = t.vertex_property_key("name", Flags::String);
|
||||
|
||||
cout << "VERTICES" << endl;
|
||||
iter::for_all(label.index().for_range(t),
|
||||
[&](auto a) { cout << a.at(prop_key) << endl; });
|
||||
label.index().for_range(t).for_all(
|
||||
[&](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);
|
||||
|
||||
t.vertex_access().fill().for_all([&](auto a) { 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");
|
||||
|
||||
label.index().for_range(t).for_all([&](auto a) { 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) = id 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);
|
||||
|
||||
t.edge_access().fill().for_all([&](auto a) { 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");
|
||||
|
||||
type.index().for_range(t).for_all([&](auto a) { a.remove(); });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n)-[:TYPE]->(m) WHERE ID(n) = id RETURN m
|
||||
auto match_id_type_return = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &type = t.type_find_or_create("TYPE");
|
||||
|
||||
auto ov = t.vertex_find(args[0]->as<Int64>().value);
|
||||
if (!option_fill(ov)) return t.commit(), false;
|
||||
auto v = ov.take();
|
||||
|
||||
auto results = v.out().fill().type(type).to();
|
||||
|
||||
// Example of Print resoult.
|
||||
// results.for_all([&](auto va) {
|
||||
// va is VertexAccessor
|
||||
// PRINT
|
||||
// });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN m
|
||||
auto match_name_type_return = [&db](const properties_t &args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &type = t.type_find_or_create("TYPE");
|
||||
|
||||
auto it_type = type.index().for_range(t);
|
||||
auto it_vertex = t.vertex_access();
|
||||
|
||||
// if(it_type.count().max>it_vertex.count().max){
|
||||
//
|
||||
// }
|
||||
|
||||
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 +299,13 @@ 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;
|
||||
queries[11675960684124428508u] = match_id_type_return;
|
||||
|
||||
return queries;
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ public:
|
||||
|
||||
void clear() { edges.clear(); }
|
||||
|
||||
std::size_t size() { return edges.size(); }
|
||||
|
||||
private:
|
||||
std::vector<EdgeRecord *> edges;
|
||||
};
|
||||
|
@ -28,6 +28,8 @@ public:
|
||||
|
||||
void clear() { edges.clear(); }
|
||||
|
||||
std::size_t size() { return edges.size(); }
|
||||
|
||||
private:
|
||||
RhHashMultiMap<VertexRecord *, EdgeRecord> edges;
|
||||
};
|
||||
|
21
include/utils/iterator/count.hpp
Normal file
21
include/utils/iterator/count.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
// Represents number of to be returned elements from iterator. Where acutal
|
||||
// number is probably somwhere in [min,max].
|
||||
class Count
|
||||
{
|
||||
|
||||
public:
|
||||
Count(size_t exact) : min(exact), max(exact) {}
|
||||
|
||||
Count(size_t min, size_t max) : min(min), max(max) {}
|
||||
|
||||
Count &min_zero()
|
||||
{
|
||||
min = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t min;
|
||||
size_t max;
|
||||
};
|
55
include/utils/iterator/filter.hpp
Normal file
55
include/utils/iterator/filter.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
#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. OP: T& -> bool
|
||||
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)) {}
|
||||
|
||||
// Return values for which filter return true.
|
||||
Option<T> next() final
|
||||
{
|
||||
auto item = Option<T>();
|
||||
do {
|
||||
item = iter.next();
|
||||
if (!item.is_present()) {
|
||||
return Option<T>();
|
||||
}
|
||||
} while (!op(item.get()));
|
||||
|
||||
return std::move(item);
|
||||
}
|
||||
|
||||
Count count() final { return iter.count().min_zero(); }
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/accessor.hpp"
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/iterator/filter.hpp"
|
||||
#include "utils/iterator/for_all.hpp"
|
||||
#include "utils/iterator/iterator_accessor.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
@ -17,12 +17,13 @@ public:
|
||||
IteratorAccessor() = delete;
|
||||
|
||||
IteratorAccessor(A &&acc)
|
||||
: begin(std::move(acc.begin())), acc(std::forward<A>(acc))
|
||||
: begin(std::move(acc.begin())), acc(std::forward<A>(acc)), returned(0)
|
||||
{
|
||||
}
|
||||
|
||||
IteratorAccessor(IteratorAccessor &&other)
|
||||
: begin(std::move(other.begin)), acc(std::forward<A>(other.acc))
|
||||
: begin(std::move(other.begin)), acc(std::forward<A>(other.acc)),
|
||||
returned(other.returned)
|
||||
{
|
||||
}
|
||||
|
||||
@ -37,15 +38,27 @@ public:
|
||||
if (begin != acc.end()) {
|
||||
auto ret = Option<T>(&(*(begin.operator->())));
|
||||
begin++;
|
||||
returned++;
|
||||
return ret;
|
||||
} else {
|
||||
return Option<T>();
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final
|
||||
{
|
||||
auto size = acc.size();
|
||||
if (size > returned) {
|
||||
return Count(0);
|
||||
} else {
|
||||
return Count(size - returned);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
I begin;
|
||||
A acc;
|
||||
size_t returned;
|
||||
};
|
||||
|
||||
// TODO: Join to make functions into one
|
||||
|
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
class EdgeType;
|
||||
|
||||
// Base iterator for next() kind iterator.
|
||||
// T - type of return value
|
||||
template <class T>
|
||||
@ -11,4 +14,26 @@ public:
|
||||
virtual ~IteratorBase(){};
|
||||
|
||||
virtual Option<T> next() = 0;
|
||||
|
||||
virtual Count count() { return Count(0, ~((size_t)0)); }
|
||||
|
||||
template <class OP>
|
||||
auto map(OP &&op);
|
||||
|
||||
template <class OP>
|
||||
auto filter(OP &&op);
|
||||
|
||||
// Maps with call to method to() and filters with call to fill.
|
||||
auto to();
|
||||
|
||||
// Filters with call to method fill()
|
||||
auto fill();
|
||||
|
||||
// Filters with type
|
||||
template <class TYPE>
|
||||
auto type(TYPE const &type);
|
||||
|
||||
// For all items calls OP.
|
||||
template <class OP>
|
||||
void for_all(OP &&op);
|
||||
};
|
||||
|
@ -11,26 +11,36 @@ template <class T, class F>
|
||||
class LambdaIterator : public IteratorBase<T>
|
||||
{
|
||||
public:
|
||||
LambdaIterator(F &&f) : func(std::move(f)) {}
|
||||
LambdaIterator(F &&f, size_t count) : func(std::move(f)), _count(count) {}
|
||||
|
||||
LambdaIterator(LambdaIterator &&other) : func(std::move(other.func)) {}
|
||||
LambdaIterator(LambdaIterator &&other)
|
||||
: func(std::move(other.func)), _count(other._count)
|
||||
{
|
||||
}
|
||||
|
||||
~LambdaIterator() final {}
|
||||
|
||||
Option<T> next() final { return func(); }
|
||||
Option<T> next() final
|
||||
{
|
||||
_count = _count > 0 ? _count - 1 : 0;
|
||||
return func();
|
||||
}
|
||||
|
||||
Count count() final { return Count(_count); }
|
||||
|
||||
private:
|
||||
F func;
|
||||
size_t _count;
|
||||
};
|
||||
|
||||
// Wraps lambda which returns options as an iterator.
|
||||
template <class F>
|
||||
auto make_iterator(F &&f)
|
||||
auto make_iterator(F &&f, size_t count)
|
||||
{
|
||||
// Because function isn't receving or in any way using type T from
|
||||
// FunctionIterator compiler can't deduce it thats way there is decltype in
|
||||
// construction of FunctionIterator. Resoulting type of iter.next().take()
|
||||
// is T.
|
||||
return LambdaIterator<decltype(f().take()), F>(std::move(f));
|
||||
return LambdaIterator<decltype(f().take()), F>(std::move(f), count);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Count count() final { return iter.count(); }
|
||||
|
||||
private:
|
||||
I iter;
|
||||
OP op;
|
||||
|
29
include/utils/iterator/query.hpp
Normal file
29
include/utils/iterator/query.hpp
Normal file
@ -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);
|
||||
}
|
||||
};
|
@ -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)
|
||||
{
|
||||
|
@ -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>();
|
||||
@ -435,6 +437,8 @@ Option<const VertexAccessor> VertexIterator::next()
|
||||
return HALF_CALL(get()->next()).map<const VertexAccessor>();
|
||||
}
|
||||
|
||||
Count VertexIterator::count() { return HALF_CALL(get()->count()); }
|
||||
|
||||
// ************************* EdgeIterator
|
||||
DESTRUCTOR(EdgeIterator, unique_ptr);
|
||||
|
||||
@ -443,6 +447,8 @@ Option<const EdgeAccessor> EdgeIterator::next()
|
||||
return HALF_CALL(get()->next()).map<const EdgeAccessor>();
|
||||
}
|
||||
|
||||
Count EdgeIterator::count() { return HALF_CALL(get()->count()); }
|
||||
|
||||
// ************************* OutEdgesIterator
|
||||
DESTRUCTOR(OutEdgesIterator, out_edge_iterator_t);
|
||||
|
||||
@ -451,6 +457,8 @@ Option<const EdgeAccessor> OutEdgesIterator::next()
|
||||
return HALF_CALL(next()).map<const EdgeAccessor>();
|
||||
}
|
||||
|
||||
Count OutEdgesIterator::count() { return HALF_CALL(count()); }
|
||||
|
||||
// ************************* InEdgesIterator
|
||||
DESTRUCTOR(InEdgesIterator, in_edge_iterator_t);
|
||||
|
||||
@ -459,6 +467,8 @@ Option<const EdgeAccessor> InEdgesIterator::next()
|
||||
return HALF_CALL(next()).map<const EdgeAccessor>();
|
||||
}
|
||||
|
||||
Count InEdgesIterator::count() { return HALF_CALL(count()); }
|
||||
|
||||
// ************************* VertexAccessIterator
|
||||
DESTRUCTOR(VertexAccessIterator, vertex_access_iterator_t);
|
||||
|
||||
@ -467,6 +477,18 @@ Option<const VertexAccessor> VertexAccessIterator::next()
|
||||
return HALF_CALL(next()).map<const VertexAccessor>();
|
||||
}
|
||||
|
||||
Count VertexAccessIterator::count() { return HALF_CALL(count()); }
|
||||
|
||||
// ************************* EdgeAccessIterator
|
||||
DESTRUCTOR(EdgeAccessIterator, edge_access_iterator_t);
|
||||
|
||||
Option<const EdgeAccessor> EdgeAccessIterator::next()
|
||||
{
|
||||
return HALF_CALL(next()).map<const EdgeAccessor>();
|
||||
}
|
||||
|
||||
Count EdgeAccessIterator::count() { return HALF_CALL(count()); }
|
||||
|
||||
// ************************* VertexPropertyKey
|
||||
DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey);
|
||||
|
||||
@ -596,7 +618,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 +636,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 +654,6 @@ void RecordStream<Stream>::chunk()
|
||||
}
|
||||
|
||||
template class RecordStream<io::Socket>;
|
||||
|
||||
}
|
||||
|
||||
// **************************** ERROR EXAMPLES ****************************** //
|
||||
|
@ -46,22 +46,26 @@ auto NonUniqueUnorderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
|
||||
Border<K> from_v,
|
||||
Border<K> to_v)
|
||||
{
|
||||
return iter::make_iterator([
|
||||
it = list.cbegin(), end = list.cend(), from = from_v, to = to_v, t = t_v
|
||||
]() mutable->auto {
|
||||
while (it != end) {
|
||||
const IndexRecord<T, K> &r = *it;
|
||||
if (from < r.key && to > r.key &&
|
||||
r.is_valid(t.db_transaction.trans)) {
|
||||
const typename T::accessor_t acc = r.access(t.db_transaction);
|
||||
return iter::make_iterator(
|
||||
[
|
||||
it = list.cbegin(), end = list.cend(), from = from_v, to = to_v,
|
||||
t = t_v
|
||||
]() mutable->auto {
|
||||
while (it != end) {
|
||||
const IndexRecord<T, K> &r = *it;
|
||||
if (from < r.key && to > r.key &&
|
||||
r.is_valid(t.db_transaction.trans)) {
|
||||
const typename T::accessor_t acc =
|
||||
r.access(t.db_transaction);
|
||||
it++;
|
||||
return make_option(std::move(acc));
|
||||
}
|
||||
it++;
|
||||
return make_option(std::move(acc));
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
return Option<const typename T::accessor_t>();
|
||||
});
|
||||
return Option<const typename T::accessor_t>();
|
||||
},
|
||||
list.size());
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
|
@ -64,23 +64,28 @@ auto UniqueOrderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
|
||||
} else {
|
||||
assert(this->order() != None);
|
||||
}
|
||||
// TODO: determine size on fact of border size.
|
||||
auto size = acc.size();
|
||||
|
||||
return iter::make_iterator([
|
||||
it = std::move(begin), b_end = std::move(end), t = t_v,
|
||||
hold_acc = std::move(acc)
|
||||
]() mutable->auto {
|
||||
while (b_end >= it->key) {
|
||||
const IndexRecord<T, K> &r = *it;
|
||||
if (r.is_valid(t.db_transaction.trans)) {
|
||||
const typename T::accessor_t acc = r.access(t.db_transaction);
|
||||
return iter::make_iterator(
|
||||
[
|
||||
it = std::move(begin), b_end = std::move(end), t = t_v,
|
||||
hold_acc = std::move(acc)
|
||||
]() mutable->auto {
|
||||
while (b_end >= it->key) {
|
||||
const IndexRecord<T, K> &r = *it;
|
||||
if (r.is_valid(t.db_transaction.trans)) {
|
||||
const typename T::accessor_t acc =
|
||||
r.access(t.db_transaction);
|
||||
it++;
|
||||
return make_option(std::move(acc));
|
||||
}
|
||||
it++;
|
||||
return make_option(std::move(acc));
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
return Option<const typename T::accessor_t>();
|
||||
});
|
||||
return Option<const typename T::accessor_t>();
|
||||
},
|
||||
size);
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
|
43
src/utils/iterator/iterator_base.cpp
Normal file
43
src/utils/iterator/iterator_base.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
|
||||
template <class T>
|
||||
template <class OP>
|
||||
auto IteratorBase<T>::map(OP &&op)
|
||||
{
|
||||
return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
|
||||
std::move(op));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class OP>
|
||||
auto IteratorBase<T>::filter(OP &&op)
|
||||
{
|
||||
return iter::make_filter<decltype(std::move(*this)), OP>(std::move(*this),
|
||||
std::move(op));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto IteratorBase<T>::to()
|
||||
{
|
||||
return map([](auto er) { return er.to(); }).fill();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto IteratorBase<T>::fill()
|
||||
{
|
||||
return filter([](auto &ra) { return ra.fill(); });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class TYPE>
|
||||
auto IteratorBase<T>::type(TYPE const &type)
|
||||
{
|
||||
return filter([&](auto &ra) { return ra.edge_type() == type; });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class OP>
|
||||
void IteratorBase<T>::for_all(OP &&op)
|
||||
{
|
||||
iter::for_all(std::move(*this), std::move(op));
|
||||
}
|
Loading…
Reference in New Issue
Block a user