Dressipi CRUD queries are dummy implemented; Fixes T99 and T131
Summary: Dressipi CRUD queries are dummy implemented; Fixes T99 and T131 Test Plan: manual Reviewers: sale Subscribers: buda, sale Maniphest Tasks: T131, T99 Differential Revision: https://memgraph.phacility.com/D9
This commit is contained in:
@@ -1,588 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef BARRIER
|
||||
|
||||
#include "barrier/common.hpp"
|
||||
|
||||
// This namespace is holding header parts of barrier classes. Barrier class
|
||||
// object is in fact object from other class inside memgraph. Main purpose of
|
||||
// barrier classes is to hide real classes from outside viewers. This header
|
||||
// should be only to be included from memgraph into generated/compiled query.
|
||||
// And this header must ensure that it defines all classes and methods required
|
||||
// for querys.
|
||||
namespace barrier
|
||||
{
|
||||
// Every class from database which must be visible to outside the barrier should
|
||||
// have there barrier class defined here.
|
||||
|
||||
// ************ Here should be forward declarations of Sized barrier classes
|
||||
// ACCESSORS
|
||||
class DbAccessor;
|
||||
class VertexAccessor;
|
||||
class EdgeAccessor;
|
||||
|
||||
// GENERIC ITERATORS
|
||||
class VertexIterator;
|
||||
class EdgeIterator;
|
||||
|
||||
// TYPED ITERATORS
|
||||
class VertexAccessIterator;
|
||||
class EdgeAccessIterator;
|
||||
class OutEdgesIterator;
|
||||
class InEdgesIterator;
|
||||
|
||||
// PROPERTY
|
||||
class VertexPropertyKey;
|
||||
class EdgePropertyKey;
|
||||
template <class T>
|
||||
class VertexPropertyType;
|
||||
template <class T>
|
||||
class EdgePropertyType;
|
||||
|
||||
// BOLT
|
||||
template <class Stream>
|
||||
class RecordStream;
|
||||
|
||||
// ************ Here should be forward declarations of Unsized barrier classes
|
||||
// COMMON
|
||||
class Db;
|
||||
class Label;
|
||||
class EdgeType;
|
||||
|
||||
// GENERIC INDEXES
|
||||
template <class K>
|
||||
class VertexIndex;
|
||||
template <class K>
|
||||
class EdgeIndex;
|
||||
|
||||
// PROPERTY
|
||||
class VertexPropertyFamily;
|
||||
class EdgePropertyFamily;
|
||||
|
||||
// ************* Here should be defined usings
|
||||
using label_ref_t = ReferenceWrapper<const Label>;
|
||||
using VertexStoredProperty = PropertyHolder<VertexPropertyKey>;
|
||||
using EdgeStoredProperty = PropertyHolder<EdgePropertyKey>;
|
||||
|
||||
// ************ Here should be definitions of Sized barrier classes
|
||||
// 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 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
|
||||
// Blueprint:
|
||||
// public:
|
||||
// template<class T> class_name(T &&d);
|
||||
// --It should delete or specify following methods depending on the behavior of
|
||||
// the original class:
|
||||
// public:
|
||||
// class_name(const class_name &other);
|
||||
// class_name(class_name &&other);
|
||||
// ~class_name();
|
||||
// class_name &operator=(const class_name &other);
|
||||
// class_name &operator=(class_name &&other);
|
||||
// --It should specify public methods which can be called on the original class.
|
||||
//
|
||||
// Blueprint:
|
||||
// class class_name : public Sized<,>
|
||||
// {
|
||||
// public:
|
||||
// template <class T>
|
||||
// class_name(T &&d);
|
||||
//
|
||||
// class_name(const class_name &other);
|
||||
// class_name(class_name &&other);
|
||||
// ~class_name();
|
||||
//
|
||||
// class_name &operator=(const class_name &other);
|
||||
// class_name &operator=(class_name &&other);
|
||||
//
|
||||
// };
|
||||
|
||||
// TODO: Extract methods od RecordAccessor for VertexAccessor and EdgeAccessor
|
||||
// into joined class.
|
||||
class VertexAccessor : private Sized<24, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
VertexAccessor(T &&d);
|
||||
|
||||
VertexAccessor(VertexAccessor &other);
|
||||
VertexAccessor(const VertexAccessor &other);
|
||||
VertexAccessor(VertexAccessor &&other);
|
||||
VertexAccessor(VertexAccessor const &&other);
|
||||
~VertexAccessor();
|
||||
|
||||
VertexAccessor &operator=(const VertexAccessor &other);
|
||||
VertexAccessor &operator=(VertexAccessor &&other);
|
||||
|
||||
bool isolated() const;
|
||||
|
||||
size_t out_degree() const;
|
||||
|
||||
size_t in_degree() const;
|
||||
|
||||
size_t degree() const;
|
||||
|
||||
bool add_label(const Label &label);
|
||||
|
||||
bool remove_label(const Label &label);
|
||||
|
||||
bool has_label(const Label &label) const;
|
||||
|
||||
const std::vector<label_ref_t> &labels() const;
|
||||
|
||||
OutEdgesIterator out() const;
|
||||
|
||||
InEdgesIterator in() const;
|
||||
|
||||
bool in_contains(VertexAccessor const &other) const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
bool fill() const;
|
||||
|
||||
const Id &id() const;
|
||||
|
||||
VertexAccessor update() const;
|
||||
|
||||
void remove() const;
|
||||
|
||||
// template <class TG>
|
||||
// bool contains(property_key<TG> &key) const;
|
||||
|
||||
const VertexStoredProperty &at(VertexPropertyFamily &key) const;
|
||||
|
||||
const VertexStoredProperty &at(VertexPropertyKey &key) const;
|
||||
|
||||
template <class V>
|
||||
OptionPtr<const V> at(VertexPropertyType<V> &key) const;
|
||||
|
||||
void set(VertexPropertyKey &key, Property &&value);
|
||||
|
||||
void clear(VertexPropertyKey &key);
|
||||
|
||||
void clear(VertexPropertyFamily &key);
|
||||
|
||||
template <class Handler>
|
||||
void accept(Handler &handler) const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
friend bool operator==(const VertexAccessor &a, const VertexAccessor &b);
|
||||
|
||||
friend bool operator!=(const VertexAccessor &a, const VertexAccessor &b);
|
||||
};
|
||||
|
||||
class EdgeAccessor : private Sized<24, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
EdgeAccessor(T &&d);
|
||||
|
||||
EdgeAccessor(EdgeAccessor &other);
|
||||
EdgeAccessor(const EdgeAccessor &other);
|
||||
EdgeAccessor(EdgeAccessor &&other);
|
||||
EdgeAccessor(EdgeAccessor const &&other);
|
||||
~EdgeAccessor();
|
||||
|
||||
EdgeAccessor &operator=(const EdgeAccessor &other);
|
||||
EdgeAccessor &operator=(EdgeAccessor &&other);
|
||||
|
||||
void edge_type(const EdgeType &edge_type);
|
||||
|
||||
const EdgeType &edge_type() const;
|
||||
|
||||
const VertexAccessor from() const;
|
||||
|
||||
const VertexAccessor to() const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
bool fill() const;
|
||||
|
||||
const Id &id() const;
|
||||
|
||||
EdgeAccessor update() const;
|
||||
|
||||
void remove() const;
|
||||
|
||||
const EdgeStoredProperty &at(EdgePropertyFamily &key) const;
|
||||
|
||||
const EdgeStoredProperty &at(EdgePropertyKey &key) const;
|
||||
|
||||
template <class V>
|
||||
OptionPtr<const V> at(EdgePropertyType<V> &key) const;
|
||||
|
||||
void set(EdgePropertyKey &key, Property &&value);
|
||||
|
||||
void clear(EdgePropertyKey &key);
|
||||
|
||||
void clear(EdgePropertyFamily &key);
|
||||
|
||||
template <class Handler>
|
||||
void accept(Handler &handler) const;
|
||||
|
||||
explicit operator bool() const;
|
||||
|
||||
friend bool operator==(const EdgeAccessor &a, const EdgeAccessor &b);
|
||||
|
||||
friend bool operator!=(const EdgeAccessor &a, const EdgeAccessor &b);
|
||||
};
|
||||
|
||||
class DbAccessor : protected Sized<40, 8>
|
||||
{
|
||||
public:
|
||||
DbAccessor(Db &d);
|
||||
|
||||
DbAccessor(const DbAccessor &other) = delete;
|
||||
DbAccessor(DbAccessor &&other) = delete;
|
||||
~DbAccessor();
|
||||
|
||||
DbAccessor &operator=(const DbAccessor &other) = delete;
|
||||
DbAccessor &operator=(DbAccessor &&other) = delete;
|
||||
|
||||
VertexAccessIterator vertex_access();
|
||||
|
||||
Option<const VertexAccessor> vertex_find(const Id &id);
|
||||
|
||||
VertexAccessor vertex_insert();
|
||||
|
||||
EdgeAccessIterator edge_access();
|
||||
|
||||
Option<const EdgeAccessor> edge_find(const Id &id);
|
||||
|
||||
EdgeAccessor edge_insert(VertexAccessor const &from,
|
||||
VertexAccessor const &to);
|
||||
|
||||
const Label &label_find_or_create(const char *name);
|
||||
|
||||
bool label_contains(const char *name);
|
||||
|
||||
const EdgeType &type_find_or_create(const char *name);
|
||||
|
||||
bool type_contains(const char *name);
|
||||
|
||||
VertexPropertyFamily &vertex_property_family_get(const std::string &name);
|
||||
|
||||
EdgePropertyFamily &edge_property_family_get(const std::string &name);
|
||||
|
||||
VertexPropertyKey vertex_property_key(const std::string &name, Type type);
|
||||
|
||||
EdgePropertyKey edge_property_key(const std::string &name, Type type);
|
||||
|
||||
template <class T>
|
||||
VertexPropertyType<T> vertex_property_key(const std::string &name);
|
||||
|
||||
template <class T>
|
||||
EdgePropertyType<T> edge_property_key(const std::string &name);
|
||||
|
||||
bool commit();
|
||||
void abort();
|
||||
};
|
||||
|
||||
class VertexIterator
|
||||
: public Sized<8, 8>,
|
||||
public iter::Composable<const VertexAccessor, VertexIterator>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
VertexIterator(T &&d);
|
||||
|
||||
VertexIterator(const VertexIterator &other) = delete;
|
||||
VertexIterator(VertexIterator &&other);
|
||||
~VertexIterator();
|
||||
VertexIterator &operator=(const VertexIterator &other) = delete;
|
||||
VertexIterator &operator=(VertexIterator &&other) = delete;
|
||||
|
||||
Option<const VertexAccessor> next();
|
||||
|
||||
Count count();
|
||||
};
|
||||
|
||||
// NOTE: This large size is because of SkipList accessor which is embeded into
|
||||
// iterator. The accessor has 64 fields of pointers which is in total 512 B.
|
||||
class VertexAccessIterator
|
||||
: public Sized<560, 8>,
|
||||
public iter::Composable<const VertexAccessor, VertexAccessIterator>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
VertexAccessIterator(T &&d);
|
||||
|
||||
VertexAccessIterator(const VertexAccessIterator &other) = delete;
|
||||
VertexAccessIterator(VertexAccessIterator &&other);
|
||||
~VertexAccessIterator();
|
||||
VertexAccessIterator &operator=(const VertexAccessIterator &other) = delete;
|
||||
VertexAccessIterator &operator=(VertexAccessIterator &&other) = delete;
|
||||
|
||||
Option<const VertexAccessor> next();
|
||||
|
||||
Count count();
|
||||
};
|
||||
|
||||
// NOTE: This large size is because of SkipList accessor which is embeded into
|
||||
// iterator. The accessor has 64 fields of pointers which is in total 512 B.
|
||||
class EdgeAccessIterator
|
||||
: public Sized<560, 8>,
|
||||
public iter::Composable<const EdgeAccessor, EdgeAccessIterator>
|
||||
{
|
||||
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();
|
||||
|
||||
Count count();
|
||||
};
|
||||
|
||||
class OutEdgesIterator
|
||||
: public Sized<48, 8>,
|
||||
public iter::Composable<const EdgeAccessor, OutEdgesIterator>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
OutEdgesIterator(T &&d);
|
||||
|
||||
OutEdgesIterator(const OutEdgesIterator &other) = delete;
|
||||
OutEdgesIterator(OutEdgesIterator &&other);
|
||||
~OutEdgesIterator();
|
||||
OutEdgesIterator &operator=(const OutEdgesIterator &other) = delete;
|
||||
OutEdgesIterator &operator=(OutEdgesIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
|
||||
Count count();
|
||||
};
|
||||
|
||||
class InEdgesIterator
|
||||
: public Sized<64, 8>,
|
||||
public iter::Composable<const EdgeAccessor, InEdgesIterator>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
InEdgesIterator(T &&d);
|
||||
|
||||
InEdgesIterator(const InEdgesIterator &other) = delete;
|
||||
InEdgesIterator(InEdgesIterator &&other);
|
||||
~InEdgesIterator();
|
||||
InEdgesIterator &operator=(const InEdgesIterator &other) = delete;
|
||||
InEdgesIterator &operator=(InEdgesIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
|
||||
Count count();
|
||||
};
|
||||
|
||||
class EdgeIterator : public Sized<8, 8>,
|
||||
public iter::Composable<const EdgeAccessor, EdgeIterator>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
EdgeIterator(T &&d);
|
||||
|
||||
EdgeIterator(const EdgeIterator &other) = delete;
|
||||
EdgeIterator(EdgeIterator &&other);
|
||||
~EdgeIterator();
|
||||
EdgeIterator &operator=(const EdgeIterator &other) = delete;
|
||||
EdgeIterator &operator=(EdgeIterator &&other) = delete;
|
||||
|
||||
Option<const EdgeAccessor> next();
|
||||
|
||||
Count count();
|
||||
|
||||
EdgeIterator &operator->() { return *this; }
|
||||
};
|
||||
|
||||
class VertexPropertyKey : private Sized<8, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
VertexPropertyKey(T &&d);
|
||||
|
||||
VertexPropertyKey(const VertexPropertyKey &other) = default;
|
||||
VertexPropertyKey(VertexPropertyKey &&other) = default;
|
||||
~VertexPropertyKey();
|
||||
|
||||
VertexPropertyKey &operator=(const VertexPropertyKey &other) = default;
|
||||
VertexPropertyKey &operator=(VertexPropertyKey &&other) = default;
|
||||
|
||||
Type get_type() const;
|
||||
};
|
||||
|
||||
class EdgePropertyKey : private Sized<8, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
EdgePropertyKey(T &&d);
|
||||
|
||||
EdgePropertyKey(const EdgePropertyKey &other) = default;
|
||||
EdgePropertyKey(EdgePropertyKey &&other) = default;
|
||||
~EdgePropertyKey();
|
||||
|
||||
EdgePropertyKey &operator=(const EdgePropertyKey &other) = default;
|
||||
EdgePropertyKey &operator=(EdgePropertyKey &&other) = default;
|
||||
|
||||
Type get_type() const;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
class VertexPropertyType : private Sized<8, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
VertexPropertyType(T &&d);
|
||||
|
||||
VertexPropertyType(const VertexPropertyType &other) = default;
|
||||
VertexPropertyType(VertexPropertyType &&other) = default;
|
||||
~VertexPropertyType(){};
|
||||
|
||||
VertexPropertyType &operator=(const VertexPropertyType &other) = default;
|
||||
VertexPropertyType &operator=(VertexPropertyType &&other) = default;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
class EdgePropertyType : private Sized<8, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
EdgePropertyType(T &&d);
|
||||
|
||||
EdgePropertyType(const EdgePropertyType &other) = default;
|
||||
EdgePropertyType(EdgePropertyType &&other) = default;
|
||||
~EdgePropertyType(){};
|
||||
|
||||
EdgePropertyType &operator=(const EdgePropertyType &other) = default;
|
||||
EdgePropertyType &operator=(EdgePropertyType &&other) = default;
|
||||
};
|
||||
|
||||
template <class Stream>
|
||||
class RecordStream : private Sized<8, 8>
|
||||
{
|
||||
public:
|
||||
template <class T>
|
||||
RecordStream(T &&d);
|
||||
|
||||
RecordStream(const RecordStream &other) = default;
|
||||
RecordStream(RecordStream &&other) = default;
|
||||
~RecordStream();
|
||||
|
||||
RecordStream &operator=(const RecordStream &other) = default;
|
||||
RecordStream &operator=(RecordStream &&other) = default;
|
||||
|
||||
void write(const VertexAccessor &vertex);
|
||||
void write(const EdgeAccessor &edge);
|
||||
void write(const VertexStoredProperty &prop);
|
||||
void write(const EdgeStoredProperty &prop);
|
||||
void write(const Null &v);
|
||||
void write(const Bool &prop);
|
||||
void write(const Float &prop);
|
||||
void write(const Double &prop);
|
||||
void write(const Int32 &prop);
|
||||
void write(const Int64 &prop);
|
||||
void write(const String &prop);
|
||||
void write(const ArrayBool &);
|
||||
void write(const ArrayInt32 &);
|
||||
void write(const ArrayInt64 &);
|
||||
void write(const ArrayFloat &);
|
||||
void write(const ArrayDouble &);
|
||||
void write(const ArrayString &);
|
||||
|
||||
void write_empty_fields();
|
||||
void write_success();
|
||||
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_list_header(size_t size);
|
||||
void write_record();
|
||||
void write_meta(const std::string &type);
|
||||
void write_failure(const std::map<std::string, std::string> &data);
|
||||
void send();
|
||||
void chunk();
|
||||
};
|
||||
|
||||
// ************ Here should be definitions of Unsized barrier classes
|
||||
// Original class can be Unsized barrier class if they are only used outside the
|
||||
// barrier through reference/pointer.
|
||||
// Usized barrier classes should:
|
||||
// --Have same name as original class or somethin more specific if it is
|
||||
// partialy specialized.
|
||||
// --Inherit Unsized class from common.hpp as protected. Blueprint:
|
||||
// class class_name: protected Unsized
|
||||
// --It should specify public methods which can be called on the original class.
|
||||
//
|
||||
// Blueprint:
|
||||
// class class_name : protected Unsized
|
||||
// {
|
||||
// public:
|
||||
//
|
||||
// };
|
||||
|
||||
class VertexPropertyFamily : protected Unsized
|
||||
{
|
||||
public:
|
||||
OptionPtr<VertexIndex<std::nullptr_t>> index();
|
||||
};
|
||||
|
||||
class EdgePropertyFamily : protected Unsized
|
||||
{
|
||||
public:
|
||||
OptionPtr<EdgeIndex<std::nullptr_t>> index();
|
||||
};
|
||||
|
||||
class Label : protected Unsized
|
||||
{
|
||||
public:
|
||||
VertexIndex<std::nullptr_t> &index() const;
|
||||
};
|
||||
|
||||
class EdgeType : protected Unsized
|
||||
{
|
||||
public:
|
||||
friend bool operator<(const EdgeType &lhs, const EdgeType &rhs);
|
||||
|
||||
friend bool operator==(const EdgeType &lhs, const EdgeType &rhs);
|
||||
|
||||
EdgeIndex<std::nullptr_t> &index() const;
|
||||
};
|
||||
|
||||
template <class K>
|
||||
class VertexIndex : protected Unsized
|
||||
{
|
||||
public:
|
||||
// TODO: This iterator sometimes has known type. It can be added to this
|
||||
// border to avoid dynamic dispatch
|
||||
VertexIterator for_range(DbAccessor &, Border<K> from = Border<K>(),
|
||||
Border<K> to = Border<K>());
|
||||
|
||||
IndexType type();
|
||||
};
|
||||
|
||||
template <class K>
|
||||
class EdgeIndex : protected Unsized
|
||||
{
|
||||
public:
|
||||
// TODO: This iterator has known type. It can be added to this border to
|
||||
// avoid dynamic dispatch
|
||||
EdgeIterator for_range(DbAccessor &, Border<K> from = Border<K>(),
|
||||
Border<K> to = Border<K>());
|
||||
|
||||
IndexType type();
|
||||
};
|
||||
|
||||
class Db : protected Unsized
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,142 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef BARRIER
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// This shoul be the only place to include code from memgraph other than
|
||||
// barrier.cpp
|
||||
#include "mvcc/id.hpp"
|
||||
#include "storage/indexes/index_definition.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/model/properties/property.hpp"
|
||||
#include "utils/border.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/option_ptr.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
|
||||
// Contains common classes and functions for barrier.hpp and barrier.cpp.
|
||||
namespace barrier
|
||||
{
|
||||
|
||||
// This define accepts other define which accepts property type to instantiate
|
||||
// template. Recieved define will be called for all property types.
|
||||
#define INSTANTIATE_FOR_PROPERTY(x) \
|
||||
x(Int32) x(Int64) x(Float) x(Double) x(Bool) x(String) x(ArrayInt32) \
|
||||
x(ArrayInt64) x(ArrayFloat) x(ArrayDouble) x(ArrayBool) x(ArrayString)
|
||||
|
||||
// **************************** HELPER FUNCTIONS **************************** //
|
||||
// CASTS FROM& -> TO&
|
||||
template <class TO, class FROM>
|
||||
TO &ref_as(FROM &ref)
|
||||
{
|
||||
return (*reinterpret_cast<TO *>(&ref));
|
||||
}
|
||||
|
||||
// CASTS FROM const& -> TO const&
|
||||
template <class TO, class FROM>
|
||||
TO const &ref_as(FROM const &ref)
|
||||
{
|
||||
return (*reinterpret_cast<TO const *>(&ref));
|
||||
}
|
||||
|
||||
// CASTS FROM* -> TO*
|
||||
template <class TO, class FROM>
|
||||
TO *ptr_as(FROM *ref)
|
||||
{
|
||||
return (reinterpret_cast<TO *>(ref));
|
||||
}
|
||||
|
||||
// CASTS FROM const* -> TO const*
|
||||
template <class TO, class FROM>
|
||||
TO const *ptr_as(FROM const *ref)
|
||||
{
|
||||
return (reinterpret_cast<TO const *>(ref));
|
||||
}
|
||||
|
||||
// CASTS FROM&& -> TO&&
|
||||
template <class TO, class FROM>
|
||||
TO &&value_as(FROM &&ref)
|
||||
{
|
||||
static_assert(sizeof(TO) == sizeof(FROM), "Border class size mismatch");
|
||||
static_assert(alignof(TO) == alignof(FROM),
|
||||
"Border class aligment mismatch");
|
||||
return (reinterpret_cast<TO &&>(std::move(ref)));
|
||||
}
|
||||
|
||||
// CASTS FROM const&& -> TO const&&
|
||||
template <class TO, class FROM>
|
||||
const TO &&value_as(const FROM &&ref)
|
||||
{
|
||||
static_assert(sizeof(TO) == sizeof(FROM), "Border class size mismatch");
|
||||
static_assert(alignof(TO) == alignof(FROM),
|
||||
"Border class aligment mismatch");
|
||||
return (reinterpret_cast<TO const &&>(std::move(ref)));
|
||||
}
|
||||
|
||||
// Barrier classes which will be used only through reference/pointer should
|
||||
// inherit this class. Outside of barrier derived classes will be used only
|
||||
// through reference/pointer.
|
||||
class Unsized
|
||||
{
|
||||
public:
|
||||
// Deleting following constructors/destroyers and opertators will assure
|
||||
// that this class/derived classes can't be created,copyed,deleted or moved.
|
||||
// This way the other side can't "accidentaly" create/copy/destroy or move
|
||||
// objects which inherit this class because that would be erroneous.
|
||||
Unsized() = delete;
|
||||
Unsized(const Unsized &other) = delete;
|
||||
Unsized(Unsized &&other) = delete;
|
||||
~Unsized() = delete;
|
||||
Unsized &operator=(const Unsized &other) = delete;
|
||||
Unsized &operator=(Unsized &&other) = delete;
|
||||
};
|
||||
|
||||
// Barrier classes which will be used as value should inherit this class.
|
||||
// Template accepts size_B in B of object of original class from memgraph.
|
||||
// Template accepts alignment_B in B of object of original class from memgraph.
|
||||
template <std::size_t size_B, std::size_t alignment_B>
|
||||
class Sized
|
||||
{
|
||||
protected:
|
||||
// This will ensure that this/derived class can't be instantiated.
|
||||
// Something outside the barrier can't "accidentaly" create this/derived
|
||||
// type because that would be erroneous.
|
||||
Sized() = delete;
|
||||
|
||||
// This constructor serves as a check for correctness of size_B and
|
||||
// alignment_B template parametars. Derived class MUST call this constructor
|
||||
// with T which it holds where T is original class from memgraph.
|
||||
template <class T>
|
||||
Sized(T &&d)
|
||||
{
|
||||
new (ptr_as<T>(&data)) T(std::move(d));
|
||||
static_assert(size_B == sizeof(T), "Border class size mismatch");
|
||||
static_assert(alignment_B == alignof(T),
|
||||
"Border class aligment mismatch");
|
||||
}
|
||||
|
||||
// This constructor serves as a check for correctness of size_B and
|
||||
// alignment_B template parametars. Derived class MUST call this constructor
|
||||
// with T which it holds where T is original class from memgraph.
|
||||
template <class T>
|
||||
Sized(const T &&d)
|
||||
{
|
||||
new (ptr_as<T>(&data)) T(std::move(d));
|
||||
static_assert(size_B == sizeof(T), "Border class size mismatch");
|
||||
static_assert(alignment_B == alignof(T),
|
||||
"Border class aligment mismatch");
|
||||
}
|
||||
|
||||
private:
|
||||
// Here is the aligned storage which imitates size and aligment of object of
|
||||
// original class from memgraph.
|
||||
typename std::aligned_storage<size_B, alignment_B>::type data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,269 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef BARRIER
|
||||
|
||||
#include "barrier/barrier.hpp"
|
||||
|
||||
// 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 "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.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_REF(x, y) \
|
||||
x &trans(y &l) { return ref_as<x>(l); } \
|
||||
x const &trans(y const &l) { return ref_as<x const>(l); } \
|
||||
y &trans(x &l) { return ref_as<y>(l); } \
|
||||
y const &trans(x const &l) { return ref_as<y const>(l); } \
|
||||
x *trans(y *l) { return ptr_as<x>(l); } \
|
||||
x const *trans(y const *l) { return ptr_as<x const>(l); } \
|
||||
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
|
||||
#define TRANSFORM_REF_TEMPLATED(x, y) \
|
||||
x &trans(y &l) { return ref_as<x>(l); } \
|
||||
template <class T> \
|
||||
x const &trans(y const &l) \
|
||||
{ \
|
||||
return ref_as<const x>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
y &trans(x &l) \
|
||||
{ \
|
||||
return ref_as<y>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
y const &trans(x const &l) \
|
||||
{ \
|
||||
return ref_as<const y>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
x *trans(y *l) \
|
||||
{ \
|
||||
return ptr_as<x>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
const x *trans(const y *l) \
|
||||
{ \
|
||||
return ptr_as<const x>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
y *trans(x *l) \
|
||||
{ \
|
||||
return ptr_as<y>(l); \
|
||||
} \
|
||||
template <class T> \
|
||||
const y *trans(const x *l) \
|
||||
{ \
|
||||
return ptr_as<const y>(l); \
|
||||
}
|
||||
|
||||
// For certain classes trans evaluates into ref which doesnt work for Sized
|
||||
// constructor. This Move forces type y.
|
||||
// DANGEROUS
|
||||
#define MOVE_CONSTRUCTOR_FORCED(x, y) \
|
||||
x::x(x &&other) : Sized(value_as<y>(std::move(other))) {}
|
||||
|
||||
// Creates constructor x(y) where x is border type and y shpuld be his original
|
||||
// type.
|
||||
// DANGEROUS
|
||||
#define VALID_CONSTRUCTION(x, y) \
|
||||
template <> \
|
||||
barrier::x::x(y &&d) : Sized(std::move(d)) \
|
||||
{ \
|
||||
}
|
||||
|
||||
// Creates const constructor x(y) where x is border type and y shpuld be his
|
||||
// original type.
|
||||
// DANGEROUS
|
||||
#define VALID_CONSTRUCTION_CONST(x, y) \
|
||||
template <> \
|
||||
barrier::x::x(y const &&d) : Sized(std::move(d)) \
|
||||
{ \
|
||||
}
|
||||
|
||||
// Creates value transformation function from original type y to border type x.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_VALUE_ONE_RAW(x, y) \
|
||||
x trans(y &&d) { return x(std::move(d)); }
|
||||
|
||||
// Creates value transformation function and constructor from original type y to
|
||||
// border type x.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_VALUE_ONE(x, y) \
|
||||
VALID_CONSTRUCTION(x, y) \
|
||||
x trans(y &&d) { return x(std::move(d)); }
|
||||
|
||||
// Creates value transformation functions and constructor between border type x
|
||||
// and original type y. Only mutable values.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_VALUE_MUT(x, y) \
|
||||
TRANSFORM_VALUE_ONE(x, y) \
|
||||
y trans(x &&d) { return value_as<y>(std::move(d)); }
|
||||
|
||||
// Creates value transformation functions and constructors between border type x
|
||||
// and original type y.
|
||||
// DANGEROUS
|
||||
#define TRANSFORM_VALUE(x, y) \
|
||||
TRANSFORM_VALUE_MUT(x, y) \
|
||||
VALID_CONSTRUCTION_CONST(x, y) \
|
||||
const x trans(const y &&d) { return x(std::move(d)); } \
|
||||
const y trans(const x &&d) { return value_as<const y>(std::move(d)); }
|
||||
|
||||
// Duplicates given x to call y with x and ::x
|
||||
#define DUP(x, y) y(x, ::x)
|
||||
|
||||
// ********************** TYPES OF AUTO
|
||||
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());
|
||||
|
||||
using in_edge_iterator_t =
|
||||
decltype(((::VertexAccessor *)(std::nullptr_t()))->in());
|
||||
|
||||
// ******************** OVERLOADED trans FUNCTIONS.
|
||||
// This enclosure is the only dangerous part of barrier except of Sized class in
|
||||
// common.hpp
|
||||
namespace barrier
|
||||
{
|
||||
// Blueprint for valid transformation of references:
|
||||
// TRANSFORM_REF(, ::);
|
||||
// template <class T> TRANSFORM_REF_TEMPLATED(<T>,::<T>);
|
||||
// TODO: Strongest assurance that evertyhing is correct is for all of following
|
||||
// transformation to use DUP for defining theres transformation. This would mean
|
||||
// that names of classes exported in barrier and names from real class in
|
||||
// database are equal.
|
||||
|
||||
// ***************** TRANSFORMS of reference and pointers
|
||||
DUP(Label, TRANSFORM_REF);
|
||||
DUP(EdgeType, TRANSFORM_REF);
|
||||
DUP(VertexPropertyFamily, TRANSFORM_REF);
|
||||
DUP(EdgePropertyFamily, TRANSFORM_REF);
|
||||
DUP(VertexAccessor, TRANSFORM_REF);
|
||||
DUP(EdgeAccessor, TRANSFORM_REF);
|
||||
DUP(Db, TRANSFORM_REF);
|
||||
DUP(DbAccessor, TRANSFORM_REF);
|
||||
TRANSFORM_REF(std::vector<label_ref_t>, std::vector<::label_ref_t>);
|
||||
TRANSFORM_REF(VertexPropertyKey,
|
||||
::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
TRANSFORM_REF(EdgePropertyKey,
|
||||
::EdgePropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
TRANSFORM_REF(VertexStoredProperty, ::StoredProperty<TypeGroupVertex>);
|
||||
TRANSFORM_REF(EdgeStoredProperty, ::StoredProperty<TypeGroupEdge>);
|
||||
|
||||
// ITERATORS
|
||||
TRANSFORM_REF(VertexIterator, ::iter::Virtual<const ::VertexAccessor>);
|
||||
TRANSFORM_REF(EdgeIterator, ::iter::Virtual<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);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(VertexIndex<T>, VertexIndexBase<T>);
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(EdgeIndex<T>, EdgeIndexBase<T>);
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(RecordStream<T>, ::bolt::RecordStream<T>);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(
|
||||
VertexPropertyType<T>,
|
||||
::VertexPropertyFamily::PropertyType::PropertyTypeKey<T>);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_REF_TEMPLATED(EdgePropertyType<T>,
|
||||
::EdgePropertyFamily::PropertyType::PropertyTypeKey<T>);
|
||||
|
||||
// ****************** TRANSFORMS of value
|
||||
// Blueprint for valid transformation of value:
|
||||
// TRANSFORM_VALUE(, ::);
|
||||
DUP(VertexAccessor, TRANSFORM_VALUE);
|
||||
DUP(EdgeAccessor, TRANSFORM_VALUE);
|
||||
TRANSFORM_VALUE(EdgePropertyKey,
|
||||
::EdgePropertyFamily::PropertyType::PropertyFamilyKey);
|
||||
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);
|
||||
MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
|
||||
TRANSFORM_VALUE_ONE(VertexIterator, ::iter::Virtual<const ::VertexAccessor>);
|
||||
MOVE_CONSTRUCTOR_FORCED(VertexIterator,
|
||||
::iter::Virtual<const ::VertexAccessor>);
|
||||
TRANSFORM_VALUE_ONE(EdgeIterator, ::iter::Virtual<const ::EdgeAccessor>);
|
||||
MOVE_CONSTRUCTOR_FORCED(EdgeIterator, ::iter::Virtual<const ::EdgeAccessor>);
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_VALUE_ONE_RAW(
|
||||
VertexPropertyType<T>,
|
||||
::VertexPropertyFamily::PropertyType::PropertyTypeKey<T>);
|
||||
template <class T>
|
||||
TRANSFORM_VALUE_ONE_RAW(EdgePropertyType<T>,
|
||||
::EdgePropertyFamily::PropertyType::PropertyTypeKey<T>)
|
||||
|
||||
template <class T>
|
||||
TRANSFORM_VALUE_ONE_RAW(RecordStream<T>, ::bolt::RecordStream<T>)
|
||||
|
||||
// ********************* SPECIAL CONSTRUCTORS
|
||||
#define VertexPropertyType_constructor(x) \
|
||||
template <> \
|
||||
template <> \
|
||||
VertexPropertyType<x>::VertexPropertyType( \
|
||||
::VertexPropertyFamily::PropertyType::PropertyTypeKey<x> &&d) \
|
||||
: Sized(std::move(d)) \
|
||||
{ \
|
||||
}
|
||||
INSTANTIATE_FOR_PROPERTY(VertexPropertyType_constructor);
|
||||
|
||||
#define EdgePropertyType_constructor(x) \
|
||||
template <> \
|
||||
template <> \
|
||||
EdgePropertyType<x>::EdgePropertyType( \
|
||||
::EdgePropertyFamily::PropertyType::PropertyTypeKey<x> &&d) \
|
||||
: Sized(std::move(d)) \
|
||||
{ \
|
||||
}
|
||||
INSTANTIATE_FOR_PROPERTY(EdgePropertyType_constructor);
|
||||
|
||||
DbAccessor::DbAccessor(Db &db) : Sized(::DbAccessor(trans(db))) {}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -105,10 +105,32 @@ public:
|
||||
serializer.write_failure(data);
|
||||
chunk();
|
||||
}
|
||||
// -- BOLT SPECIFIC METHODS -----------------------------------------------
|
||||
|
||||
void write_count(const size_t count)
|
||||
{
|
||||
write_record();
|
||||
write_list_header(1);
|
||||
write(Int64(count));
|
||||
chunk();
|
||||
}
|
||||
|
||||
void write(const VertexAccessor &vertex) { serializer.write(vertex); }
|
||||
void write_vertex_record(const VertexAccessor& va)
|
||||
{
|
||||
write_record();
|
||||
write_list_header(1);
|
||||
write(va);
|
||||
chunk();
|
||||
}
|
||||
|
||||
void write(const EdgeAccessor &edge) { serializer.write(edge); }
|
||||
void write_edge_record(const EdgeAccessor& ea)
|
||||
{
|
||||
write_record();
|
||||
write_list_header(1);
|
||||
write(ea);
|
||||
chunk();
|
||||
}
|
||||
|
||||
void write(const StoredProperty<TypeGroupEdge> &prop)
|
||||
{
|
||||
|
||||
@@ -20,8 +20,6 @@ public:
|
||||
// -- all possible Memgraph's keys --
|
||||
constexpr const char *COMPILE_CPU_PATH = "compile_cpu_path";
|
||||
constexpr const char *TEMPLATE_CPU_CPP_PATH = "template_cpu_cpp_path";
|
||||
constexpr const char *BARRIER_TEMPLATE_CPU_CPP_PATH =
|
||||
"barrier_template_cpu_cpp_path";
|
||||
constexpr const char *SNAPSHOTS_PATH = "snapshots_path";
|
||||
constexpr const char *CLEANING_CYCLE_SEC = "cleaning_cycle_sec";
|
||||
constexpr const char *SNAPSHOT_CYCLE_SEC = "snapshot_cycle_sec";
|
||||
|
||||
@@ -49,9 +49,11 @@ class DbAccessor
|
||||
|
||||
public:
|
||||
DbAccessor(Db &db);
|
||||
|
||||
DbAccessor(Db &db, tx::Transaction &t);
|
||||
|
||||
DbAccessor(const DbAccessor& other) = delete;
|
||||
DbAccessor(DbAccessor&& other) = delete;
|
||||
|
||||
//*******************VERTEX METHODS
|
||||
// Returns iterator of VertexAccessor for all vertices.
|
||||
// TODO: Implement class specaily for this return
|
||||
@@ -140,6 +142,7 @@ public:
|
||||
.template type_key<T>();
|
||||
}
|
||||
|
||||
bool update_indexes();
|
||||
// ******************** TRANSACTION METHODS
|
||||
|
||||
// True if commit was successful, or false if transaction was aborted.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "logging/loggable.hpp"
|
||||
#include "storage/indexes/index_update.hpp"
|
||||
#include "transactions/transaction.hpp"
|
||||
|
||||
@@ -13,13 +14,19 @@ using index_updates_t = std::vector<IndexUpdate>;
|
||||
// its methods.
|
||||
// Also serves as a barrier for calling methods defined public but meant for
|
||||
// internal use. That kind of method should request DbTransaction&.
|
||||
class DbTransaction
|
||||
class DbTransaction : public Loggable
|
||||
{
|
||||
friend DbAccessor;
|
||||
|
||||
public:
|
||||
DbTransaction(Db &db);
|
||||
DbTransaction(Db &db, tx::Transaction &trans) : db(db), trans(trans) {}
|
||||
DbTransaction(Db &db, tx::Transaction &trans)
|
||||
: Loggable("DbTransaction"), db(db), trans(trans)
|
||||
{
|
||||
}
|
||||
|
||||
DbTransaction(const DbTransaction& other) = delete;
|
||||
DbTransaction(DbTransaction&& other) = default;
|
||||
|
||||
// Global transactional algorithms,operations and general methods meant for
|
||||
// internal use should be here or should be routed through this object.
|
||||
@@ -48,14 +55,9 @@ public:
|
||||
// with call update_indexes
|
||||
template <class TG>
|
||||
void to_update_index(typename TG::vlist_t *vlist,
|
||||
typename TG::record_t *record)
|
||||
{
|
||||
index_updates.push_back(make_index_update(vlist, record));
|
||||
}
|
||||
typename TG::record_t *record);
|
||||
|
||||
index_updates_t index_updates;
|
||||
|
||||
tx::Transaction &trans;
|
||||
|
||||
Db &db;
|
||||
tx::Transaction &trans;
|
||||
};
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
class Loggable
|
||||
{
|
||||
public:
|
||||
Loggable(const std::string& name) : logger(logging::log->logger(name)) {}
|
||||
Loggable(std::string &&name)
|
||||
: logger(logging::log->logger(std::forward<std::string>(name)))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Loggable() {}
|
||||
|
||||
|
||||
@@ -76,8 +76,10 @@ public:
|
||||
template <class... Args>
|
||||
void debug(Args&&... args)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
#ifndef LOG_NO_DEBUG
|
||||
emit<Debug>(std::forward<Args>(args)...);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -14,13 +14,8 @@ class CypherBackend
|
||||
public:
|
||||
CypherBackend() : logger(logging::log->logger("CypherBackend"))
|
||||
{
|
||||
// load template file
|
||||
#ifdef BARRIER
|
||||
std::string template_path =
|
||||
CONFIG(config::BARRIER_TEMPLATE_CPU_CPP_PATH);
|
||||
#else
|
||||
// load template file
|
||||
std::string template_path = CONFIG(config::TEMPLATE_CPU_CPP_PATH);
|
||||
#endif
|
||||
template_text = utils::read_text(fs::path(template_path));
|
||||
}
|
||||
|
||||
@@ -46,11 +41,7 @@ public:
|
||||
template_text.str(), {{"class_name", "CodeCPU"},
|
||||
{"stripped_hash", std::to_string(stripped_hash)},
|
||||
{"query", query},
|
||||
#ifdef BARRIER
|
||||
{"stream", "RecordStream<::io::Socket>"},
|
||||
#else
|
||||
{"stream", type_name<Stream>().to_string()},
|
||||
#endif
|
||||
{"code", cpp_traverser.code}});
|
||||
|
||||
logger.trace("generated code: {}", generated);
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "includes.hpp"
|
||||
|
||||
namespace hardcode
|
||||
{
|
||||
|
||||
auto load_basic_functions(Db &db)
|
||||
{
|
||||
query_functions_t functions;
|
||||
|
||||
// CREATE (n {prop: 0}) RETURN n
|
||||
auto create_node = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto property_key = t.vertex_property_key("prop", args[0].key.flags());
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
return t.commit();
|
||||
};
|
||||
functions[11597417457737499503u] = create_node;
|
||||
|
||||
// CREATE (n:LABEL {name: "TEST"}) RETURN n;
|
||||
auto create_labeled_and_named_node = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto property_key = t.vertex_property_key("name", args[0].key.flags());
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
vertex_accessor.add_label(label);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// CREATE (n:OTHER {name: "TEST"}) RETURN n;
|
||||
auto create_labeled_and_named_node_v2 = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto property_key = t.vertex_property_key("name", args[0].key.flags());
|
||||
auto &label = t.label_find_or_create("OTHER");
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
vertex_accessor.add_label(label);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
auto create_account = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_id = t.vertex_property_key("id", args[0].key.flags());
|
||||
auto prop_name = t.vertex_property_key("name", args[1].key.flags());
|
||||
auto prop_country =
|
||||
t.vertex_property_key("country", args[2].key.flags());
|
||||
auto prop_created =
|
||||
t.vertex_property_key("created_at", args[3].key.flags());
|
||||
auto &label = t.label_find_or_create("ACCOUNT");
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(prop_id, std::move(args[0]));
|
||||
vertex_accessor.set(prop_name, std::move(args[1]));
|
||||
vertex_accessor.set(prop_country, std::move(args[2]));
|
||||
vertex_accessor.set(prop_created, std::move(args[3]));
|
||||
vertex_accessor.add_label(label);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
auto find_node_by_internal_id = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto maybe_va = t.vertex_find(Id(args[0].as<Int64>().value()));
|
||||
if (!option_fill(maybe_va)) {
|
||||
cout << "vertex doesn't exist" << endl;
|
||||
t.commit();
|
||||
return false;
|
||||
}
|
||||
auto vertex_accessor = maybe_va.get();
|
||||
// cout_properties(vertex_accessor.properties());
|
||||
cout << "LABELS:" << endl;
|
||||
for (auto label_ref : vertex_accessor.labels()) {
|
||||
// cout << label_ref.get() << endl;
|
||||
}
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
auto create_edge = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto &edge_type = t.type_find_or_create("IS");
|
||||
|
||||
auto v1 = t.vertex_find(args[0].as<Int64>().value());
|
||||
if (!option_fill(v1)) return t.commit(), false;
|
||||
|
||||
auto v2 = t.vertex_find(args[1].as<Int64>().value());
|
||||
if (!option_fill(v2)) return t.commit(), false;
|
||||
|
||||
auto edge_accessor = t.edge_insert(v1.get(), v2.get());
|
||||
|
||||
edge_accessor.edge_type(edge_type);
|
||||
|
||||
bool ret = t.commit();
|
||||
|
||||
// cout << edge_accessor.edge_type() << endl;
|
||||
|
||||
// cout_properties(edge_accessor.properties());
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
auto find_edge_by_internal_id = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto maybe_ea = t.edge_find(args[0].as<Int64>().value());
|
||||
if (!option_fill(maybe_ea)) return t.commit(), false;
|
||||
auto edge_accessor = maybe_ea.get();
|
||||
|
||||
// print edge type and properties
|
||||
// cout << "EDGE_TYPE: " << edge_accessor.edge_type() << endl;
|
||||
|
||||
auto from = edge_accessor.from();
|
||||
if (!from.fill()) return t.commit(), false;
|
||||
|
||||
cout << "FROM:" << endl;
|
||||
// cout_properties(from->data.props);
|
||||
|
||||
auto to = edge_accessor.to();
|
||||
if (!to.fill()) return t.commit(), false;
|
||||
|
||||
cout << "TO:" << endl;
|
||||
// cout_properties(to->data.props);
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
auto update_node = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
auto prop_name = t.vertex_property_key("name", args[1].key.flags());
|
||||
|
||||
auto maybe_v = t.vertex_find(args[0].as<Int64>().value());
|
||||
if (!option_fill(maybe_v)) return t.commit(), false;
|
||||
auto v = maybe_v.get();
|
||||
|
||||
v.set(prop_name, std::move(args[1]));
|
||||
// cout_properties(v.properties());
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// 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](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto prop_age = t.edge_property_key("age", args[2].key.flags());
|
||||
auto prop_weight = t.edge_property_key("weight", args[3].key.flags());
|
||||
|
||||
auto n1 = t.vertex_find(args[0].as<Int64>().value());
|
||||
if (!option_fill(n1)) return t.commit(), false;
|
||||
auto n2 = t.vertex_find(args[1].as<Int64>().value());
|
||||
if (!option_fill(n2)) return t.commit(), false;
|
||||
auto r = t.edge_insert(n2.get(), n1.get());
|
||||
r.set(prop_age, std::move(args[2]));
|
||||
r.set(prop_weight, std::move(args[3]));
|
||||
auto &IS = t.type_find_or_create("IS");
|
||||
r.edge_type(IS);
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n) RETURN n
|
||||
auto match_all_nodes = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
t.vertex_access().fill().for_all(
|
||||
[&](auto vertex) { cout << vertex.id() << endl; });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n:LABEL) RETURN n
|
||||
auto match_by_label = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
auto property_key = t.vertex_property_key("name", Flags::String);
|
||||
|
||||
cout << "VERTICES" << endl;
|
||||
label.index().for_range(t).for_all(
|
||||
[&](auto a) { cout << a.at(property_key) << endl; });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n) DELETE n
|
||||
auto match_all_delete = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
// DETACH DELETE
|
||||
// t.edge_access().fill().for_all(
|
||||
// [&](auto e) { e.remove(); }
|
||||
// );
|
||||
|
||||
t.vertex_access().fill().isolated().for_all(
|
||||
[&](auto a) { a.remove(); });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n:LABEL) DELETE n
|
||||
auto match_label_delete = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
|
||||
label.index().for_range(t).isolated().for_all(
|
||||
[&](auto a) { a.remove(); });
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n) WHERE ID(n) = id DELETE n
|
||||
auto match_id_delete = [&db](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();
|
||||
if (!v.isolated()) return t.commit(), false;
|
||||
v.remove();
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH ()-[r]-() WHERE ID(r) = id DELETE r
|
||||
auto match_edge_id_delete = [&db](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](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](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](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](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &type = t.type_find_or_create("TYPE");
|
||||
auto prop_name = t.vertex_property_key("name", args[0].key.flags());
|
||||
|
||||
Option<const EdgeAccessor> r;
|
||||
|
||||
auto it_type = type.index()
|
||||
.for_range(t)
|
||||
.clone_to(r) // Savepoint
|
||||
.from() // Backtracing
|
||||
.has_property(prop_name, args[0])
|
||||
.replace(r); // Load savepoint
|
||||
|
||||
auto it_vertex = t.vertex_access()
|
||||
.fill()
|
||||
.has_property(prop_name, args[0])
|
||||
.out()
|
||||
.type(type);
|
||||
|
||||
if (it_type.count() > it_vertex.count()) {
|
||||
// Going through vertices wiil probably be faster
|
||||
it_vertex.to().for_all([&](auto m) {
|
||||
// PRINT m
|
||||
});
|
||||
|
||||
} else {
|
||||
// Going through edges wiil probably be faster
|
||||
it_type.to().for_all([&](auto m) {
|
||||
// PRINT m
|
||||
});
|
||||
}
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN n,m
|
||||
auto match_name_type_return_cross = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
auto &type = t.type_find_or_create("TYPE");
|
||||
auto prop_name = t.vertex_property_key("name", args[0].key.flags());
|
||||
|
||||
Option<const VertexAccessor> n;
|
||||
Option<const EdgeAccessor> r;
|
||||
|
||||
// lazy load iterator
|
||||
auto it_type = type.index()
|
||||
.for_range(t)
|
||||
.clone_to(r) // Savepoint
|
||||
.from() // Backtracing
|
||||
.has_property(prop_name, args[0])
|
||||
.clone_to(n) // Savepoint
|
||||
.replace(r); // Load savepoint
|
||||
// Above statments + .to().for_all([&](auto m) {}) will unrool into:
|
||||
// for(auto edge:type.index.for_range(t)){
|
||||
// auto from_vertex=edge.from();
|
||||
// if(from_vertex.fill()){
|
||||
// auto &prop=from_vertex.at(prop_name);
|
||||
// if(prop==args[0]){
|
||||
// auto to_vertex=edge.to();
|
||||
// if(to_vertex.fill()){
|
||||
// // Here you have all data.
|
||||
// // n == from_vertex
|
||||
// // m == to_vertex
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
auto it_vertex = t.vertex_access()
|
||||
.fill()
|
||||
.has_property(prop_name, args[0])
|
||||
.clone_to(n) // Savepoint
|
||||
.out()
|
||||
.type(type);
|
||||
// Above statments + .to().for_all([&](auto m) {}) will unrool into:
|
||||
// for(auto from_vertex:t.vertex_access(t)){
|
||||
// if(from_vertex.fill()){
|
||||
// auto &prop=from_vertex.at(prop_name);
|
||||
// if(prop==args[0]){
|
||||
// for(auto edge:from_vertex.out()){
|
||||
// if(edge.edge_type() == type){
|
||||
// auto to_vertex=edge.to();
|
||||
// if(to_vertex.fill()){
|
||||
// // Here you have all data.
|
||||
// // n == from_vertex
|
||||
// // m == to_vertex
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (it_type.count() > it_vertex.count()) {
|
||||
// Going through vertices wiil probably be faster
|
||||
it_vertex.to().for_all([&](auto m) {
|
||||
// m is changing
|
||||
// n is n
|
||||
// PRINT n, m
|
||||
});
|
||||
|
||||
} else {
|
||||
// Going through edges wiil probably be faster
|
||||
it_type.to().for_all([&](auto m) {
|
||||
// m is r
|
||||
// n is changing
|
||||
// PRINT n, m
|
||||
});
|
||||
}
|
||||
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// MATCH (n:LABEL)-[:TYPE]->(m) RETURN n
|
||||
auto match_label_type_return = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
|
||||
try {
|
||||
auto &type = t.type_find_or_create("TYPE");
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
|
||||
Option<const VertexAccessor> bt;
|
||||
|
||||
auto it_type = type.index().for_range(t).from().label(label);
|
||||
|
||||
auto it_vertex = t.vertex_access()
|
||||
.fill()
|
||||
.label(label)
|
||||
.clone_to(bt) // Savepoint
|
||||
.out()
|
||||
.type(type)
|
||||
.replace(bt); // Load savepoint
|
||||
|
||||
if (it_type.count() > it_vertex.count()) {
|
||||
// Going through vertices wiil probably be faster
|
||||
it_vertex.for_all([&](auto n) {
|
||||
// PRINT n
|
||||
});
|
||||
|
||||
} else {
|
||||
// Going through edges wiil probably be faster
|
||||
it_type.for_all([&](auto n) {
|
||||
// PRINT n
|
||||
});
|
||||
}
|
||||
return t.commit();
|
||||
} catch (...) {
|
||||
// Catch all exceptions
|
||||
// Print something to logger
|
||||
t.abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// MATCH (n:LABEL {name: "TEST01"}) RETURN n;
|
||||
auto match_label_property = [&db](properties_t &&args) {
|
||||
std::map<std::string, int64_t> indices{{"name", 0}};
|
||||
auto properties = query_properties(indices, args);
|
||||
DbAccessor t(db);
|
||||
try {
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
label.index().for_range(t).properties_filter(t, properties).for_all(
|
||||
[&](auto vertex_accessor) -> void {
|
||||
std::cout << "MATCH" << std::endl;
|
||||
}
|
||||
);
|
||||
return t.commit();
|
||||
} catch (...) {
|
||||
t.abort();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
functions[17721584194272598838u] = match_label_property;
|
||||
|
||||
functions[15284086425088081497u] = match_all_nodes;
|
||||
functions[4857652843629217005u] = match_by_label;
|
||||
functions[15648836733456301916u] = create_edge_v2;
|
||||
functions[10597108978382323595u] = create_account;
|
||||
functions[5397556489557792025u] = create_labeled_and_named_node;
|
||||
|
||||
// TODO: query hasher reports two hash values
|
||||
functions[998725786176032607u] = create_labeled_and_named_node_v2;
|
||||
functions[16090682663946456821u] = create_labeled_and_named_node_v2;
|
||||
|
||||
functions[7939106225150551899u] = create_edge;
|
||||
functions[6579425155585886196u] = create_edge;
|
||||
functions[11198568396549106428u] = find_node_by_internal_id;
|
||||
functions[8320600413058284114u] = find_edge_by_internal_id;
|
||||
functions[6813335159006269041u] = update_node;
|
||||
functions[10506105811763742758u] = match_all_delete;
|
||||
functions[13742779491897528506u] = match_label_delete;
|
||||
functions[11349462498691305864u] = match_id_delete;
|
||||
functions[6963549500479100885u] = match_edge_id_delete;
|
||||
functions[14897166600223619735u] = match_edge_all_delete;
|
||||
functions[16888549834923624215u] = match_edge_type_delete;
|
||||
functions[11675960684124428508u] = match_id_type_return;
|
||||
functions[15698881472054193835u] = match_name_type_return;
|
||||
functions[12595102442911913761u] = match_name_type_return_cross;
|
||||
functions[8918221081398321263u] = match_label_type_return;
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "includes.hpp"
|
||||
|
||||
namespace hardcode
|
||||
{
|
||||
|
||||
// TODO: decouple hashes from the code because hashes could and should be
|
||||
// tested separately
|
||||
|
||||
auto load_dressipi_functions(Db &db)
|
||||
{
|
||||
query_functions_t functions;
|
||||
|
||||
// Query: CREATE (n {garment_id: 1234, garment_category_id: 1}) RETURN n
|
||||
// Hash: 12139093029838549530
|
||||
functions[12139093029838549530u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: CREATE (p:profile {profile_id: 111, partner_id: 55}) RETURN p
|
||||
// Hash: 17158428452166262783
|
||||
functions[17158428452166262783u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1234}) SET g:FF RETURN labels(g)
|
||||
// Hash: 11123780635391515946
|
||||
functions[11123780635391515946u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g:garment{garment_id: 1234}) SET s.score = 1550 RETURN s.score
|
||||
// Hash: 674581607834128909
|
||||
functions[674581607834128909u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 3456}) SET g.reveals = 50 RETURN g
|
||||
// Hash: 2839969099736071844
|
||||
functions[2839969099736071844u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MERGE (g1:garment {garment_id: 1234})-[r:default_outfit]-(g2:garment {garment_id: 2345}) RETURN r
|
||||
// Hash: 3782642357973971504
|
||||
functions[3782642357973971504u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MERGE (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) SET s.score=1500 RETURN s
|
||||
// Hash: 7871009397157280694
|
||||
functions[7871009397157280694u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) DELETE s
|
||||
// Hash: 9459600951073026137
|
||||
functions[9459600951073026137u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 113}) DELETE p
|
||||
// Hash: 6763665709953344106
|
||||
functions[6763665709953344106u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (n) DETACH DELETE n
|
||||
// Hash: 4798158026600988079
|
||||
functions[4798158026600988079u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile) RETURN p
|
||||
// Hash: 15599970964909894866
|
||||
functions[15599970964909894866u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment) RETURN COUNT(g)
|
||||
// Hash: 11458306387621940265
|
||||
functions[11458306387621940265u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1234}) RETURN g
|
||||
// Hash: 7756609649964321221
|
||||
functions[7756609649964321221u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {partner_id: 55}) RETURN p
|
||||
// Hash: 17506488413143988006
|
||||
functions[17506488413143988006u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (n) RETURN count(n)
|
||||
// Hash: 10510787599699014973
|
||||
functions[10510787599699014973u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
|
||||
#include "communication/bolt/v1/serialization/record_stream.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "io/network/socket.hpp"
|
||||
#include "mvcc/id.hpp"
|
||||
#include "query/util.hpp"
|
||||
#include "storage/edge_type/edge_type.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "storage/indexes/index_definition.hpp"
|
||||
#include "storage/label/label.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/model/properties/property.hpp"
|
||||
#include "utils/border.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/option_ptr.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace hardcode
|
||||
{
|
||||
using query_functions_t =
|
||||
std::map<uint64_t, std::function<bool(properties_t &&)>>;
|
||||
}
|
||||
@@ -1,25 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "query/strip/stripped.hpp"
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.hpp"
|
||||
#include "io/network/socket.hpp"
|
||||
#else
|
||||
#include "communication/communication.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#endif
|
||||
#include "query/strip/stripped.hpp"
|
||||
|
||||
template <typename Stream>
|
||||
class IPlanCPU
|
||||
{
|
||||
public:
|
||||
#ifdef BARRIER
|
||||
virtual bool run(barrier::Db &db, plan_args_t &args, Stream &stream) = 0;
|
||||
#else
|
||||
virtual bool run(Db &db, plan_args_t &args, Stream &stream) = 0;
|
||||
#endif
|
||||
virtual ~IPlanCPU() {}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
class Traverser : public ast::AstVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
using uptr = std::unique_ptr<Traverser>;
|
||||
using sptr = std::shared_ptr<Traverser>;
|
||||
|
||||
|
||||
@@ -12,14 +12,6 @@
|
||||
// execution
|
||||
// postprocess the results
|
||||
|
||||
// BARRIER!
|
||||
#ifdef BARRIER
|
||||
namespace barrier
|
||||
{
|
||||
Db &trans(::Db &ref);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Stream>
|
||||
class ProgramExecutor
|
||||
{
|
||||
@@ -29,13 +21,7 @@ public:
|
||||
auto execute(QueryProgram<Stream> &program, Db &db, Stream &stream)
|
||||
{
|
||||
try {
|
||||
// TODO: return result of query/code exection
|
||||
#ifdef BARRIER
|
||||
return program.plan->run(barrier::trans(db),
|
||||
program.stripped.arguments, stream);
|
||||
#else
|
||||
return program.plan->run(db, program.stripped.arguments, stream);
|
||||
#endif
|
||||
// TODO: catch more exceptions
|
||||
} catch (...) {
|
||||
throw PlanExecutionException("");
|
||||
|
||||
@@ -80,6 +80,7 @@ private:
|
||||
// TODO ifdef MEMGRAPH64 problem, how to use this kind
|
||||
// of ifdef functions?
|
||||
// uint64_t depends on fnv function
|
||||
// TODO: faster datastructure
|
||||
std::unordered_map<uint64_t, sptr_code_lib> code_libs;
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
@@ -9,32 +9,17 @@
|
||||
#include "logging/default.hpp"
|
||||
#include "storage/model/properties/properties.hpp"
|
||||
#include "storage/model/properties/property.hpp"
|
||||
#include "storage/model/properties/traversers/consolewriter.hpp"
|
||||
#include "storage/model/properties/traversers/jsonwriter.hpp"
|
||||
#include "storage/model/properties/json_writer.hpp"
|
||||
#include "utils/types/byte.hpp"
|
||||
#include "utils/exceptions/basic_exception.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
template <class T>
|
||||
void print_props(const Properties<T> &properties);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define PRINT_PROPS(_)
|
||||
#else
|
||||
#define PRINT_PROPS(_PROPS_) print_props(_PROPS_);
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
void cout_properties(const Properties<T> &properties);
|
||||
|
||||
template <class T>
|
||||
void cout_property(const StoredProperty<T> &property);
|
||||
|
||||
// this is a nice way how to avoid multiple definition problem with
|
||||
// headers because it will create a unique namespace for each compilation unit
|
||||
// http://stackoverflow.com/questions/2727582/multiple-definition-in-header-file
|
||||
// but sometimes that might be a problem
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -61,9 +46,9 @@ std::string code_line(const std::string &format_str, const Args &... args)
|
||||
}
|
||||
|
||||
using name_properties_t = std::vector<std::pair<std::string, Property>>;
|
||||
using indices_t = std::map<std::string, int>;
|
||||
|
||||
auto query_properties(const std::map<std::string, int64_t> &indices,
|
||||
properties_t &values)
|
||||
auto query_properties(indices_t &indices, properties_t &values)
|
||||
{
|
||||
name_properties_t properties;
|
||||
for (auto &property_index : indices) {
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
|
||||
#include "mvcc/record.hpp"
|
||||
#include "storage/model/edge_model.hpp"
|
||||
#include "utils/string_buffer.hpp"
|
||||
#include "storage/model/properties/json_writer.hpp"
|
||||
#include "utils/handle_write.hpp"
|
||||
|
||||
class Edge : public mvcc::Record<Edge>
|
||||
{
|
||||
using buffer_t = utils::StringBuffer;
|
||||
using props_writer_t = JsonWriter<buffer_t>;
|
||||
|
||||
public:
|
||||
class Accessor;
|
||||
|
||||
@@ -19,4 +25,14 @@ public:
|
||||
Edge &operator=(Edge &&) = delete;
|
||||
|
||||
EdgeModel data;
|
||||
|
||||
template <typename Stream>
|
||||
void stream_repr(Stream &stream) const
|
||||
{
|
||||
auto props = handle_write<buffer_t, props_writer_t>(data.props);
|
||||
|
||||
stream << "Edge(cre = " << tx.cre() << ", "
|
||||
<< "exp = " << tx.exp() << ", "
|
||||
<< "props = " << props.str() << ")";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,8 +19,9 @@ class EdgeAccessor : public RecordAccessor<TypeGroupEdge, EdgeAccessor>
|
||||
|
||||
public:
|
||||
using RecordAccessor::RecordAccessor;
|
||||
typedef Edge record_t;
|
||||
typedef EdgeRecord record_list_t;
|
||||
|
||||
using record_t = Edge;
|
||||
using record_list_t = EdgeRecord;
|
||||
|
||||
// Removes self and disconects vertices from it.
|
||||
void remove() const;
|
||||
@@ -34,4 +35,21 @@ public:
|
||||
|
||||
// EdgeAccessor doesnt need to be filled
|
||||
VertexAccessor to() const;
|
||||
|
||||
template <typename Stream>
|
||||
void stream_repr(Stream& stream) const
|
||||
{
|
||||
auto from_va = from();
|
||||
auto to_va = to();
|
||||
|
||||
from_va.fill();
|
||||
to_va.fill();
|
||||
|
||||
from_va.stream_repr(stream);
|
||||
stream << '-';
|
||||
this->record->stream_repr(stream);
|
||||
stream << "->";
|
||||
to_va.stream_repr(stream);
|
||||
stream << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
auto VertexAccessor::out() const
|
||||
{
|
||||
DbTransaction &t = this->db;
|
||||
std::cout << "VA OUT" << std::endl;
|
||||
std::cout << record->data.out.size() << std::endl;
|
||||
return iter::make_map(iter::make_iter_ref(record->data.out),
|
||||
[&](auto e) -> auto { return EdgeAccessor(*e, t); });
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "mvcc/id.hpp"
|
||||
|
||||
// #include "storage/indexes/index_record.hpp"
|
||||
#include "logging/loggable.hpp"
|
||||
#include "storage/garbage/delete_sensitive.hpp"
|
||||
#include "storage/indexes/index_definition.hpp"
|
||||
#include "utils/border.hpp"
|
||||
@@ -26,13 +27,14 @@ class Transaction;
|
||||
// TG type group
|
||||
// K type of key on which records are ordered
|
||||
template <class TG, class K>
|
||||
class IndexBase : public DeleteSensitive
|
||||
class IndexBase : public DeleteSensitive, public Loggable
|
||||
{
|
||||
public:
|
||||
// Created with the database
|
||||
IndexBase(IndexDefinition &&it);
|
||||
IndexBase(IndexDefinition &&it, std::string &&logger_name = "IndexBase");
|
||||
|
||||
IndexBase(IndexDefinition &&it, const tx::Transaction &t);
|
||||
IndexBase(IndexDefinition &&it, const tx::Transaction &t,
|
||||
std::string &&logger_name = "IndexBase");
|
||||
|
||||
virtual ~IndexBase(){};
|
||||
|
||||
@@ -70,6 +72,9 @@ public:
|
||||
|
||||
const IndexDefinition &definition() const { return it; }
|
||||
|
||||
protected:
|
||||
Logger logger;
|
||||
|
||||
private:
|
||||
const IndexDefinition it;
|
||||
// Id of transaction which created this index.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
// #include "storage/label/label.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
|
||||
class Label;
|
||||
@@ -11,13 +10,13 @@ using label_ref_t = ReferenceWrapper<const Label>;
|
||||
class LabelCollection
|
||||
{
|
||||
public:
|
||||
auto begin() { return _labels.begin(); }
|
||||
auto begin() const { return _labels.begin(); }
|
||||
auto cbegin() const { return _labels.begin(); }
|
||||
auto begin() { return labels_.begin(); }
|
||||
auto begin() const { return labels_.begin(); }
|
||||
auto cbegin() const { return labels_.begin(); }
|
||||
|
||||
auto end() { return _labels.end(); }
|
||||
auto end() const { return _labels.end(); }
|
||||
auto cend() const { return _labels.end(); }
|
||||
auto end() { return labels_.end(); }
|
||||
auto end() const { return labels_.end(); }
|
||||
auto cend() const { return labels_.end(); }
|
||||
|
||||
bool add(const Label &label);
|
||||
bool has(const Label &label) const;
|
||||
@@ -26,6 +25,13 @@ public:
|
||||
void clear();
|
||||
const std::vector<label_ref_t> &operator()() const;
|
||||
|
||||
template <class Handler>
|
||||
void handle(Handler &handler) const
|
||||
{
|
||||
for (auto &label : labels_)
|
||||
handler.handle(label.get());
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<label_ref_t> _labels;
|
||||
std::vector<label_ref_t> labels_;
|
||||
};
|
||||
|
||||
15
include/storage/label/labels_writer.hpp
Normal file
15
include/storage/label/labels_writer.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
class Label;
|
||||
|
||||
template <class Buffer>
|
||||
class LabelsWriter
|
||||
{
|
||||
public:
|
||||
LabelsWriter(Buffer &buffer) : buffer_(buffer) {}
|
||||
|
||||
void handle(const Label& label);
|
||||
|
||||
private:
|
||||
Buffer& buffer_;
|
||||
};
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
auto end() const { return edges.end(); }
|
||||
auto cend() const { return edges.end(); }
|
||||
|
||||
void add(EdgeRecord *edge) { edges.push_back(edge); }
|
||||
void add(EdgeRecord *edge) { edges.emplace_back(edge); }
|
||||
|
||||
size_t degree() const { return edges.size(); }
|
||||
|
||||
|
||||
@@ -70,30 +70,3 @@ private:
|
||||
bool first{true};
|
||||
Buffer &buffer;
|
||||
};
|
||||
|
||||
class StringBuffer
|
||||
{
|
||||
public:
|
||||
StringBuffer &operator<<(const std::string &str)
|
||||
{
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(const char *str)
|
||||
{
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(char c)
|
||||
{
|
||||
data += c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string &str() { return data; }
|
||||
|
||||
private:
|
||||
std::string data;
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "storage/model/properties/properties.hpp"
|
||||
#include "storage/type_group_edge.hpp"
|
||||
#include "storage/type_group_vertex.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
class ConsoleWriter
|
||||
{
|
||||
public:
|
||||
ConsoleWriter() {}
|
||||
|
||||
void handle(const StoredProperty<TypeGroupEdge> &value)
|
||||
{
|
||||
handle<TypeGroupEdge>(value);
|
||||
}
|
||||
|
||||
void handle(const StoredProperty<TypeGroupVertex> &value)
|
||||
{
|
||||
handle<TypeGroupVertex>(value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void handle(StoredProperty<T> const &value)
|
||||
{
|
||||
cout << "KEY: " << value.key.family_name() << "; VALUE: ";
|
||||
|
||||
value.accept(*this);
|
||||
|
||||
// value.accept(*this);
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void handle(const Null &v) { cout << "NULL"; }
|
||||
|
||||
void handle(const Bool &b) { cout << b; }
|
||||
|
||||
void handle(const String &s) { cout << s; }
|
||||
|
||||
void handle(const Int32 &int32) { cout << int32; }
|
||||
|
||||
void handle(const Int64 &int64) { cout << int64; }
|
||||
|
||||
void handle(const Float &f) { cout << f; }
|
||||
|
||||
void handle(const Double &d) { cout << d; }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayBool &) { assert(false); }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayInt32 &) { assert(false); }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayInt64 &) { assert(false); }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayFloat &) { assert(false); }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayDouble &) { assert(false); }
|
||||
|
||||
// Not yet implemented
|
||||
void handle(const ArrayString &) { assert(false); }
|
||||
|
||||
void finish() {}
|
||||
};
|
||||
@@ -1,11 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "mvcc/record.hpp"
|
||||
#include "storage/model/properties/traversers/jsonwriter.hpp"
|
||||
#include "storage/label/labels_writer.hpp"
|
||||
#include "storage/model/properties/json_writer.hpp"
|
||||
#include "storage/model/vertex_model.hpp"
|
||||
#include "utils/handle_write.hpp"
|
||||
#include "utils/string_buffer.hpp"
|
||||
|
||||
class Vertex : public mvcc::Record<Vertex>
|
||||
{
|
||||
using buffer_t = utils::StringBuffer;
|
||||
using props_writer_t = JsonWriter<buffer_t>;
|
||||
using labels_writer_t = LabelsWriter<buffer_t>;
|
||||
|
||||
public:
|
||||
class Accessor;
|
||||
|
||||
@@ -14,24 +21,22 @@ public:
|
||||
Vertex(VertexModel &&data) : data(std::move(data)) {}
|
||||
|
||||
Vertex(const Vertex &) = delete;
|
||||
Vertex(Vertex &&) = delete;
|
||||
Vertex(Vertex &&) = delete;
|
||||
|
||||
Vertex &operator=(const Vertex &) = delete;
|
||||
Vertex &operator=(Vertex &&) = delete;
|
||||
|
||||
VertexModel data;
|
||||
|
||||
template <typename Stream>
|
||||
void stream_repr(Stream &stream) const
|
||||
{
|
||||
auto props = handle_write<buffer_t, props_writer_t>(data.props);
|
||||
auto labels = handle_write<buffer_t, labels_writer_t>(data.labels);
|
||||
|
||||
stream << "Vertex(cre = " << tx.cre() << ", "
|
||||
<< "exp = " << tx.exp() << ", "
|
||||
<< "props = " << props.str() << ", "
|
||||
<< "labels = " << labels.str() << ")";
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const Vertex &record)
|
||||
{
|
||||
StringBuffer buffer;
|
||||
JsonWriter<StringBuffer> writer(buffer);
|
||||
|
||||
// dump properties in this buffer
|
||||
record.data.props.handle(writer);
|
||||
writer.finish();
|
||||
|
||||
return stream << "Vertex"
|
||||
<< "(cre = " << record.tx.cre()
|
||||
<< ", exp = " << record.tx.exp() << "): " << buffer.str();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "storage/label/label_collection.hpp"
|
||||
#include "storage/record_accessor.hpp"
|
||||
#include "storage/vertex.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
@@ -15,7 +16,7 @@ class VertexAccessor : public RecordAccessor<TypeGroupVertex, VertexAccessor>
|
||||
public:
|
||||
using RecordAccessor::RecordAccessor;
|
||||
|
||||
using record_t = Vertex;
|
||||
using record_t = Vertex;
|
||||
using record_list_t = VertexRecord;
|
||||
|
||||
// Removes self and all edges connected to it.
|
||||
@@ -51,4 +52,14 @@ public:
|
||||
|
||||
// True if there exists edge between other vertex and this vertex.
|
||||
bool in_contains(VertexAccessor const &other) const;
|
||||
|
||||
template <typename Stream>
|
||||
void stream_repr(Stream& stream) const
|
||||
{
|
||||
if (this->record != nullptr)
|
||||
this->record->stream_repr(stream);
|
||||
else
|
||||
std::cout << "TRACE: record is nullptr" << std::endl;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
16
include/utils/handle_write.hpp
Normal file
16
include/utils/handle_write.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* Source object is going to be traversed by Writer and Writer will
|
||||
* write that data into the Destination object.
|
||||
*
|
||||
* Writer object defines write format.
|
||||
*/
|
||||
template <typename Destination, typename Writer, typename Source>
|
||||
Destination handle_write(const Source& source)
|
||||
{
|
||||
Destination destination;
|
||||
Writer writter(destination);
|
||||
source.handle(writter);
|
||||
return destination;
|
||||
}
|
||||
@@ -6,7 +6,8 @@
|
||||
namespace iter
|
||||
{
|
||||
|
||||
// Class which Combined two iterators IT1 and IT2. Both return values T
|
||||
// Class which Combined two iterators IT1 and IT2.
|
||||
// Both return values T
|
||||
// T - type of return value
|
||||
// IT1 - first iterator type
|
||||
// IT2 - second iterator type
|
||||
|
||||
@@ -116,6 +116,12 @@ public:
|
||||
move(), [](auto vr) { return vr.out().fill(); });
|
||||
}
|
||||
|
||||
auto in()
|
||||
{
|
||||
return iter::make_flat_map<Derived>(
|
||||
move(), [](auto vr) { return vr.in().fill(); });
|
||||
}
|
||||
|
||||
// Filters with label on from vertex.
|
||||
template <class LABEL>
|
||||
auto from_label(LABEL const &label)
|
||||
@@ -153,6 +159,12 @@ public:
|
||||
move(), [&](auto &v) mutable { t = Option<const T>(v); });
|
||||
}
|
||||
|
||||
// auto clone_to(Option<T> &t)
|
||||
// {
|
||||
// return iter::make_inspect<Derived>(
|
||||
// move(), [&](auto &e) mutable { t = Option<T>(e); });
|
||||
// }
|
||||
|
||||
// Filters with call to method fill()
|
||||
auto fill()
|
||||
{
|
||||
|
||||
@@ -6,27 +6,31 @@
|
||||
namespace iter
|
||||
{
|
||||
|
||||
// Class which inspects values returned by I iterator before passing thenm as
|
||||
// result.
|
||||
// Class which inspects values returned by I iterator
|
||||
// before passing them as a result.
|
||||
// function.
|
||||
// T - type of return value
|
||||
// I - iterator type
|
||||
// OP - type of inspector function. OP: T&->void
|
||||
template <class T, class I, class OP>
|
||||
class Inspect : public IteratorBase<T>, public Composable<T, Inspect<T, I, OP>>
|
||||
class Inspect : public IteratorBase<T>,
|
||||
public Composable<T, Inspect<T, I, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
Inspect() = delete;
|
||||
|
||||
// Inspect operation is designed to be used in chained calls which operate
|
||||
// on a
|
||||
// iterator. Inspect will in that usecase receive other iterator by value
|
||||
// and
|
||||
// Inspect operation is designed to be used
|
||||
// in chained calls which operate on an
|
||||
// iterator. Inspect will in that usecase
|
||||
// receive other iterator by value and
|
||||
// std::move is a optimization for it.
|
||||
Inspect(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
|
||||
Inspect(I &&iter, OP &&op) :
|
||||
iter(std::move(iter)),
|
||||
op(std::move(op))
|
||||
{}
|
||||
|
||||
Inspect(Inspect &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
|
||||
Inspect(Inspect &&m) :
|
||||
iter(std::move(m.iter)), op(std::move(m.op)) {}
|
||||
|
||||
~Inspect() final {}
|
||||
|
||||
@@ -52,7 +56,7 @@ template <class I, class OP>
|
||||
auto make_inspect(I &&iter, OP &&op)
|
||||
{
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Inspect<decltype(iter.next().take()), I, OP>(std::move(iter),
|
||||
std::move(op));
|
||||
return Inspect<decltype(iter.next().take()), I, OP>
|
||||
(std::move(iter), std::move(op));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include "query_engine/exceptions/exceptions.hpp"
|
||||
|
||||
#include "utils/exceptions/out_of_memory.hpp"
|
||||
#include "utils/memory/block_allocator.hpp"
|
||||
|
||||
// http://en.cppreference.com/w/cpp/language/new
|
||||
@@ -24,7 +25,8 @@ public:
|
||||
// until it eats all the memory.
|
||||
static_assert(sizeof(T) <= page_size,
|
||||
"Cant allocate objects larger than page_size");
|
||||
do {
|
||||
do
|
||||
{
|
||||
// Mask which has log2(alignof(T)) lower bits setted to 0 and the
|
||||
// rest to 1.
|
||||
// example:
|
||||
@@ -56,7 +58,8 @@ public:
|
||||
|
||||
// If the new_head is greater than end that means that there isn't
|
||||
// enough space for object T in current block of memory.
|
||||
if (LIKELY(new_head <= end)) {
|
||||
if (LIKELY(new_head <= end))
|
||||
{
|
||||
|
||||
// All is fine, head can become new_head
|
||||
head = new_head;
|
||||
@@ -99,7 +102,8 @@ public:
|
||||
// Relases all memory.
|
||||
void free()
|
||||
{
|
||||
while (allocated_blocks.size() > 0) {
|
||||
while (allocated_blocks.size() > 0)
|
||||
{
|
||||
blocks.release(allocated_blocks.back());
|
||||
allocated_blocks.pop_back();
|
||||
}
|
||||
@@ -109,5 +113,5 @@ private:
|
||||
BlockAllocator<page_size> blocks;
|
||||
std::vector<void *> allocated_blocks;
|
||||
char *head = {nullptr};
|
||||
char *end = {nullptr};
|
||||
char *end = {nullptr};
|
||||
};
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
#include <ext/aligned_buffer.h>
|
||||
#include <utility>
|
||||
|
||||
// Optional object storage. It maybe has and maybe dosent have objet of type T.
|
||||
// Optional object storage. It maybe has and maybe
|
||||
// dosent have objet of type T.
|
||||
template <class T>
|
||||
class Option
|
||||
{
|
||||
@@ -33,12 +34,14 @@ public:
|
||||
std::memset(data._M_addr(), 0, sizeof(T));
|
||||
}
|
||||
}
|
||||
// Containers from std which have strong exception guarantees wont use move
|
||||
// constructors and operators wihtout noexcept. "Optimized C++,2016 , Kurt
|
||||
// Guntheroth, page: 142, title: Moving instances into std::vector"
|
||||
|
||||
// Containers from std which have strong exception
|
||||
// guarantees wont use move constructors and operators
|
||||
// wihtout noexcept. "Optimized C++,2016 , Kurt
|
||||
// Guntheroth, page: 142, title: Moving instances into
|
||||
// std::vector"
|
||||
Option(Option &&other) noexcept
|
||||
{
|
||||
|
||||
if (other.initialized) {
|
||||
new (data._M_addr()) T(std::move(other.get()));
|
||||
other.initialized = false;
|
||||
@@ -69,6 +72,7 @@ public:
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Option &operator=(Option &&other)
|
||||
{
|
||||
if (initialized) {
|
||||
@@ -180,8 +184,9 @@ public:
|
||||
explicit operator bool() const { return initialized; }
|
||||
|
||||
private:
|
||||
// Aligned buffer is here to ensure aligment for data of type T. It isn't
|
||||
// applicable to just put T field because the field has to be able to be
|
||||
// Aligned buffer is here to ensure aligment for
|
||||
// data of type T. It isn't applicable to just put T
|
||||
// field because the field has to be able to be
|
||||
// uninitialized to fulfill the semantics of Option class.
|
||||
__gnu_cxx::__aligned_buffer<T> data;
|
||||
bool initialized = false;
|
||||
|
||||
35
include/utils/string_buffer.hpp
Normal file
35
include/utils/string_buffer.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
class StringBuffer
|
||||
{
|
||||
public:
|
||||
StringBuffer &operator<<(const std::string &str)
|
||||
{
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(const char *str)
|
||||
{
|
||||
data += str;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringBuffer &operator<<(char c)
|
||||
{
|
||||
data += c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string &str() { return data; }
|
||||
|
||||
private:
|
||||
std::string data;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user