From b374ae1dbb7d2de2747c26dd4c9634fec6377da2 Mon Sep 17 00:00:00 2001 From: Florijan Stamenkovic <florijan.stamenkovic@memgraph.io> Date: Sat, 4 Feb 2017 09:01:15 +0100 Subject: [PATCH] storage and database major refactor in progress, also switching from properties to typed-value system. a lot of overdesigned functionalities cut down, new implementations just started. VERY UNSTABLE STATE --- CMakeLists.txt | 29 +- cmake/copy_includes.cmake | 52 +-- .../concurrent/concurrent_set.hpp | 94 +++--- include/database/creation_exception.hpp | 17 + include/database/db.hpp | 93 ------ include/database/db_accessor.hpp | 2 +- include/database/graph_db.hpp | 112 +++++++ include/database/graph_db_accessor.hpp | 24 ++ include/dbms/cleaner.hpp | 2 +- include/dbms/dbms.hpp | 2 +- include/mvcc/version_list.hpp | 4 +- include/query/engine.hpp | 2 +- include/query/i_plan_cpu.hpp | 2 +- include/query/plan/program_executor.hpp | 2 +- include/snapshot/snapshoter.hpp | 2 +- include/storage/common.hpp | 6 - include/storage/edge.hpp | 41 +-- include/storage/edge_accessor.hpp | 49 +-- include/storage/edge_record.hpp | 35 -- include/storage/edge_type/edge_type.hpp | 50 --- include/storage/edge_type/edge_type_store.hpp | 32 -- include/storage/edge_x_vertex.hpp | 20 -- include/storage/edges.hpp | 47 --- .../impl/nonunique_unordered_index.hpp | 42 --- .../indexes/impl/unique_ordered_index.hpp | 42 --- include/storage/indexes/index_base.hpp | 84 ----- include/storage/indexes/index_definition.hpp | 104 ------ include/storage/indexes/index_holder.hpp | 49 --- include/storage/indexes/index_record.hpp | 70 ---- include/storage/indexes/index_update.hpp | 45 --- include/storage/indexes/indexes.hpp | 308 ------------------ include/storage/indexes/keys/index_key.hpp | 20 -- .../storage/indexes/keys/non_unique_key.hpp | 18 - include/storage/indexes/keys/unique_key.hpp | 45 --- include/storage/iterator/graph_composable.hpp | 20 -- include/storage/iterator/graph_filter.hpp | 19 -- include/storage/label/label.hpp | 53 --- include/storage/label/label_collection.hpp | 37 --- include/storage/label/label_store.hpp | 25 -- include/storage/label/labels_writer.hpp | 23 -- include/storage/model/edge_list.hpp | 34 -- include/storage/model/edge_map.hpp | 34 -- include/storage/model/edge_model.hpp | 17 - include/storage/model/property_model.hpp | 10 - include/storage/model/vertex_model.hpp | 14 - include/storage/record_accessor.hpp | 226 ++++--------- include/storage/type_group_edge.hpp | 19 -- include/storage/type_group_vertex.hpp | 19 -- include/storage/{model => }/typed_value.hpp | 0 .../storage/{model => }/typed_value_store.hpp | 0 .../storage/{model => }/typed_value_utils.h | 2 +- include/storage/vertex.hpp | 46 +-- include/storage/vertex_accessor.hpp | 60 +--- include/storage/vertex_record.hpp | 12 - include/storage/vertices.hpp | 52 --- include/utils/pass_key.hpp | 22 ++ poc/add_double.cpp | 2 +- poc/astar.cpp | 2 +- poc/astar_query.cpp | 2 +- poc/csv_import.cpp | 2 +- poc/profile.cpp | 2 +- poc/size_aligment.cpp | 2 +- src/database/db.cpp | 21 -- src/database/db_accessor.cpp | 2 +- src/database/db_transaction.cpp | 2 +- src/database/graph_db.cpp | 77 +++++ src/memgraph_http.cpp | 2 +- src/storage/edge_accessor.cpp | 55 ++-- src/storage/edge_type/edge_type.cpp | 28 -- src/storage/edge_type/edge_type_store.cpp | 24 -- src/storage/edges.cpp | 60 ---- .../impl/nonunique_unordered_index.cpp | 93 ------ .../indexes/impl/unique_ordered_index.cpp | 115 ------- src/storage/indexes/index_base.cpp | 39 --- src/storage/indexes/index_holder.cpp | 71 ---- src/storage/indexes/index_record.cpp | 62 ---- src/storage/indexes/index_update.cpp | 14 - src/storage/indexes/indexes.cpp | 140 -------- src/storage/label/label.cpp | 39 --- src/storage/label/label_collection.cpp | 45 --- src/storage/label/label_store.cpp | 21 -- src/storage/label/labels_writer.cpp | 13 - src/storage/model/json/all.hpp | 11 - src/storage/model/json/array.hpp | 81 ----- src/storage/model/json/bool.hpp | 30 -- src/storage/model/json/integral.hpp | 30 -- src/storage/model/json/json.hpp | 44 --- src/storage/model/json/null.hpp | 27 -- src/storage/model/json/object.hpp | 103 ------ src/storage/model/json/primitive.hpp | 26 -- src/storage/model/json/real.hpp | 30 -- src/storage/model/json/string.hpp | 31 -- src/storage/record_accessor.cpp | 24 -- src/storage/{model => }/typed_value.cpp | 2 +- src/storage/{model => }/typed_value_store.cpp | 2 +- src/storage/vertex_accessor.cpp | 95 ++---- src/storage/vertices.cpp | 56 ---- .../integration/_hardcoded_query/includes.hpp | 4 +- tests/integration/queries.cpp | 2 +- 99 files changed, 491 insertions(+), 3332 deletions(-) create mode 100644 include/database/creation_exception.hpp delete mode 100644 include/database/db.hpp create mode 100644 include/database/graph_db.hpp create mode 100644 include/database/graph_db_accessor.hpp delete mode 100644 include/storage/common.hpp delete mode 100644 include/storage/edge_record.hpp delete mode 100644 include/storage/edge_type/edge_type.hpp delete mode 100644 include/storage/edge_type/edge_type_store.hpp delete mode 100644 include/storage/edge_x_vertex.hpp delete mode 100644 include/storage/edges.hpp delete mode 100644 include/storage/indexes/impl/nonunique_unordered_index.hpp delete mode 100644 include/storage/indexes/impl/unique_ordered_index.hpp delete mode 100644 include/storage/indexes/index_base.hpp delete mode 100644 include/storage/indexes/index_definition.hpp delete mode 100644 include/storage/indexes/index_holder.hpp delete mode 100644 include/storage/indexes/index_record.hpp delete mode 100644 include/storage/indexes/index_update.hpp delete mode 100644 include/storage/indexes/indexes.hpp delete mode 100644 include/storage/indexes/keys/index_key.hpp delete mode 100644 include/storage/indexes/keys/non_unique_key.hpp delete mode 100644 include/storage/indexes/keys/unique_key.hpp delete mode 100644 include/storage/iterator/graph_composable.hpp delete mode 100644 include/storage/iterator/graph_filter.hpp delete mode 100644 include/storage/label/label.hpp delete mode 100644 include/storage/label/label_collection.hpp delete mode 100644 include/storage/label/label_store.hpp delete mode 100644 include/storage/label/labels_writer.hpp delete mode 100644 include/storage/model/edge_list.hpp delete mode 100644 include/storage/model/edge_map.hpp delete mode 100644 include/storage/model/edge_model.hpp delete mode 100644 include/storage/model/property_model.hpp delete mode 100644 include/storage/model/vertex_model.hpp delete mode 100644 include/storage/type_group_edge.hpp delete mode 100644 include/storage/type_group_vertex.hpp rename include/storage/{model => }/typed_value.hpp (100%) rename include/storage/{model => }/typed_value_store.hpp (100%) rename include/storage/{model => }/typed_value_utils.h (96%) delete mode 100644 include/storage/vertex_record.hpp delete mode 100644 include/storage/vertices.hpp create mode 100644 include/utils/pass_key.hpp delete mode 100644 src/database/db.cpp create mode 100644 src/database/graph_db.cpp delete mode 100644 src/storage/edge_type/edge_type.cpp delete mode 100644 src/storage/edge_type/edge_type_store.cpp delete mode 100644 src/storage/edges.cpp delete mode 100644 src/storage/indexes/impl/nonunique_unordered_index.cpp delete mode 100644 src/storage/indexes/impl/unique_ordered_index.cpp delete mode 100644 src/storage/indexes/index_base.cpp delete mode 100644 src/storage/indexes/index_holder.cpp delete mode 100644 src/storage/indexes/index_record.cpp delete mode 100644 src/storage/indexes/index_update.cpp delete mode 100644 src/storage/indexes/indexes.cpp delete mode 100644 src/storage/label/label.cpp delete mode 100644 src/storage/label/label_collection.cpp delete mode 100644 src/storage/label/label_store.cpp delete mode 100644 src/storage/label/labels_writer.cpp delete mode 100644 src/storage/model/json/all.hpp delete mode 100644 src/storage/model/json/array.hpp delete mode 100644 src/storage/model/json/bool.hpp delete mode 100644 src/storage/model/json/integral.hpp delete mode 100644 src/storage/model/json/json.hpp delete mode 100644 src/storage/model/json/null.hpp delete mode 100644 src/storage/model/json/object.hpp delete mode 100644 src/storage/model/json/primitive.hpp delete mode 100644 src/storage/model/json/real.hpp delete mode 100644 src/storage/model/json/string.hpp delete mode 100644 src/storage/record_accessor.cpp rename src/storage/{model => }/typed_value.cpp (99%) rename src/storage/{model => }/typed_value_store.cpp (97%) delete mode 100644 src/storage/vertices.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 789f7b5df..8fbb08da1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -303,33 +303,8 @@ set(memgraph_src_files ${src_dir}/snapshot/snapshot_decoder.cpp ${src_dir}/storage/vertices.cpp ${src_dir}/storage/edges.cpp - ${src_dir}/storage/label/label.cpp - ${src_dir}/storage/label/label_collection.cpp - ${src_dir}/storage/label/label_store.cpp - ${src_dir}/storage/label/labels_writer.cpp - ${src_dir}/storage/edge_type/edge_type.cpp - ${src_dir}/storage/edge_type/edge_type_store.cpp - ${src_dir}/storage/model/typed_value.cpp - ${src_dir}/storage/model/typed_value_store.cpp - ${src_dir}/storage/model/properties/null.cpp - ${src_dir}/storage/model/properties/bool.cpp - ${src_dir}/storage/model/properties/int32.cpp - ${src_dir}/storage/model/properties/int64.cpp - ${src_dir}/storage/model/properties/float.cpp - ${src_dir}/storage/model/properties/double.cpp - ${src_dir}/storage/model/properties/string.cpp - ${src_dir}/storage/model/properties/array.cpp - ${src_dir}/storage/model/properties/property.cpp - ${src_dir}/storage/model/properties/properties.cpp - ${src_dir}/storage/model/properties/stored_property.cpp - ${src_dir}/storage/model/properties/property_family.cpp - ${src_dir}/storage/indexes/indexes.cpp - ${src_dir}/storage/indexes/index_base.cpp - ${src_dir}/storage/indexes/index_record.cpp - ${src_dir}/storage/indexes/index_update.cpp - ${src_dir}/storage/indexes/index_holder.cpp - ${src_dir}/storage/indexes/impl/unique_ordered_index.cpp - ${src_dir}/storage/indexes/impl/nonunique_unordered_index.cpp + ${src_dir}/storage/typed_value.cpp + ${src_dir}/storage/typed_value_store.cpp ${src_dir}/storage/locking/record_lock.cpp ${src_dir}/storage/garbage/garbage.cpp ${src_dir}/storage/vertex_accessor.cpp diff --git a/cmake/copy_includes.cmake b/cmake/copy_includes.cmake index 5508be6cd..d4564c21f 100644 --- a/cmake/copy_includes.cmake +++ b/cmake/copy_includes.cmake @@ -6,29 +6,16 @@ FILE(COPY ${include_dir}/database/db.hpp DESTINATION ${build_include_dir}/databa FILE(COPY ${include_dir}/database/db_transaction.hpp DESTINATION ${build_include_dir}/database) FILE(COPY ${include_dir}/database/db_accessor.hpp DESTINATION ${build_include_dir}/database) -FILE(COPY ${include_dir}/storage/common.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/graph.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/edge.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/edge_record.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/vertex_record.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/edge_accessor.hpp DESTINATION ${build_include_dir}/storage) -FILE(COPY ${include_dir}/storage/edges.hpp DESTINATION ${build_include_dir}/storage) -FILE(COPY ${include_dir}/storage/vertices.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/vertex.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/vertex_accessor.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/record_accessor.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/locking/record_lock.hpp DESTINATION ${build_include_dir}/storage/locking) FILE(COPY ${include_dir}/storage/locking/lock_status.hpp DESTINATION ${build_include_dir}/storage/locking) -FILE(COPY ${include_dir}/storage/edge_type/edge_type_store.hpp DESTINATION ${build_include_dir}/storage/edge_type) -FILE(COPY ${include_dir}/storage/edge_type/edge_type.hpp DESTINATION ${build_include_dir}/storage/edge_type) -FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_include_dir}/storage/label) -FILE(COPY ${include_dir}/storage/label/labels_writer.hpp DESTINATION ${build_include_dir}/storage/label) -FILE(COPY ${include_dir}/storage/model/edge_map.hpp DESTINATION ${build_include_dir}/storage/model) -FILE(COPY ${include_dir}/storage/model/properties/flags.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/stored_property.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/property_holder.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/type_group_edge.hpp DESTINATION ${build_include_dir}/storage) -FILE(COPY ${include_dir}/storage/type_group_vertex.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/edge_x_vertex.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/query/util.hpp DESTINATION ${build_include_dir}/query) @@ -71,42 +58,9 @@ FILE(COPY ${include_dir}/transactions/engine.hpp DESTINATION ${build_include_dir FILE(COPY ${include_dir}/transactions/transaction_store.hpp DESTINATION ${build_include_dir}/transactions) FILE(COPY ${include_dir}/transactions/transaction_read.hpp DESTINATION ${build_include_dir}/transactions) -FILE(COPY ${include_dir}/storage/model/properties/properties.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/property.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/json_writer.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/all.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/bool.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/null.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/float.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/double.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/int32.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/int64.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/string.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/array.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/floating.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/number.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/integral.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/property_family.hpp DESTINATION ${build_include_dir}/storage/model/properties) -FILE(COPY ${include_dir}/storage/model/properties/utils/math_operations.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils) -FILE(COPY ${include_dir}/storage/model/properties/utils/unary_negation.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils) -FILE(COPY ${include_dir}/storage/model/properties/utils/modulo.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils) - - -FILE(COPY ${include_dir}/storage/model/edge_model.hpp DESTINATION ${build_include_dir}/storage/model) -FILE(COPY ${include_dir}/storage/model/property_model.hpp DESTINATION ${build_include_dir}/storage/model) -FILE(COPY ${include_dir}/storage/model/vertex_model.hpp DESTINATION ${build_include_dir}/storage/model) -FILE(COPY ${include_dir}/storage/model/edge_list.hpp DESTINATION ${build_include_dir}/storage/model) - -FILE(COPY ${include_dir}/storage/label/label.hpp DESTINATION ${build_include_dir}/storage/label) -FILE(COPY ${include_dir}/storage/label/label_collection.hpp DESTINATION ${build_include_dir}/storage/label) -FILE(COPY ${include_dir}/storage/label/label_store.hpp DESTINATION ${build_include_dir}/storage/label) - -FILE(COPY ${include_dir}/storage/indexes/index_record.hpp DESTINATION ${build_include_dir}/storage/indexes) -FILE(COPY ${include_dir}/storage/indexes/index_base.hpp DESTINATION ${build_include_dir}/storage/indexes) -FILE(COPY ${include_dir}/storage/indexes/impl/nonunique_unordered_index.hpp DESTINATION ${build_include_dir}/storage/indexes/impl) -FILE(COPY ${include_dir}/storage/indexes/index_holder.hpp DESTINATION ${build_include_dir}/storage/indexes) -FILE(COPY ${include_dir}/storage/indexes/index_definition.hpp DESTINATION ${build_include_dir}/storage/indexes) -FILE(COPY ${include_dir}/storage/indexes/index_update.hpp DESTINATION ${build_include_dir}/storage/indexes) +FILE(COPY ${include_dir}/storage/typed_value.hpp DESTINATION ${build_include_dir}/storage/model) +FILE(COPY ${include_dir}/storage/typed_value_store.hpp DESTINATION ${build_include_dir}/storage/model) +FILE(COPY ${include_dir}/storage/typed_value_utils.hpp DESTINATION ${build_include_dir}/storage/model) FILE(COPY ${include_dir}/storage/garbage/delete_sensitive.hpp DESTINATION ${build_include_dir}/storage/garbage) FILE(COPY ${include_dir}/storage/garbage/garbage.hpp DESTINATION ${build_include_dir}/storage/garbage) diff --git a/include/data_structures/concurrent/concurrent_set.hpp b/include/data_structures/concurrent/concurrent_set.hpp index dc5bb69cc..b748eb4f9 100644 --- a/include/data_structures/concurrent/concurrent_set.hpp +++ b/include/data_structures/concurrent/concurrent_set.hpp @@ -5,73 +5,65 @@ // Multi thread safe set based on skiplist. // T - type of data. -template <class T> -class ConcurrentSet -{ - typedef SkipList<T> list; - typedef typename SkipList<T>::Iterator list_it; - typedef typename SkipList<T>::ConstIterator list_it_con; +template<class T> +class ConcurrentSet { + typedef SkipList<T> list; + typedef typename SkipList<T>::Iterator list_it; + typedef typename SkipList<T>::ConstIterator list_it_con; public: - ConcurrentSet() {} + ConcurrentSet() {} - class Accessor : public AccessorBase<T> - { - friend class ConcurrentSet; + class Accessor : public AccessorBase<T> { + friend class ConcurrentSet; - using AccessorBase<T>::AccessorBase; + using AccessorBase<T>::AccessorBase; - private: - using AccessorBase<T>::accessor; + private: + using AccessorBase<T>::accessor; - public: - std::pair<list_it, bool> insert(const T &item) - { - return accessor.insert(item); - } + public: + std::pair<list_it, bool> insert(const T &item) { + return accessor.insert(item); + } - std::pair<list_it, bool> insert(T &&item) - { - return accessor.insert(std::move(item)); - } + std::pair<list_it, bool> insert(T &&item) { + return accessor.insert(std::move(item)); + } - list_it_con find(const T &item) const { return accessor.find(item); } + list_it_con find(const T &item) const { return accessor.find(item); } - list_it find(const T &item) { return accessor.find(item); } + list_it find(const T &item) { return accessor.find(item); } - // Returns iterator to item or first larger if it doesn't exist. - template <class K> - list_it_con find_or_larger(const K &item) const - { - return accessor.find_or_larger(item); - } + // Returns iterator to item or first larger if it doesn't exist. + template<class K> + list_it_con find_or_larger(const K &item) const { + return accessor.find_or_larger(item); + } - // Returns iterator to item or first larger if it doesn't exist. - template <class K> - list_it find_or_larger(const K &item) - { - return accessor.find_or_larger(item); - } + // Returns iterator to item or first larger if it doesn't exist. + template<class K> + list_it find_or_larger(const K &item) { + return accessor.find_or_larger(item); + } - // Returns iterator to item or first larger if it doesn't exist. - template <class K> - list_it_con cfind_or_larger(const K &item) - { - return accessor.template find_or_larger<list_it_con, K>(item); - } + // Returns iterator to item or first larger if it doesn't exist. + template<class K> + list_it_con cfind_or_larger(const K &item) { + return accessor.template find_or_larger<list_it_con, K>(item); + } - bool contains(const T &item) const - { - return this->find(item) != this->end(); - } + bool contains(const T &item) const { + return this->find(item) != this->end(); + } - bool remove(const T &item) { return accessor.remove(item); } - }; + bool remove(const T &item) { return accessor.remove(item); } + }; - Accessor access() { return Accessor(&skiplist); } + Accessor access() { return Accessor(&skiplist); } - const Accessor access() const { return Accessor(&skiplist); } + const Accessor access() const { return Accessor(&skiplist); } private: - list skiplist; + list skiplist; }; diff --git a/include/database/creation_exception.hpp b/include/database/creation_exception.hpp new file mode 100644 index 000000000..d10a39627 --- /dev/null +++ b/include/database/creation_exception.hpp @@ -0,0 +1,17 @@ +// +// Copyright 2017 Memgraph +// Created by Florijan Stamenkovic on 03.02.17. +// + +#pragma once + +#include "utils/exceptions/basic_exception.hpp" + + +class CreationException : public BasicException { +public: + using BasicException::BasicException; +}; + + + diff --git a/include/database/db.hpp b/include/database/db.hpp deleted file mode 100644 index e5d46b3cc..000000000 --- a/include/database/db.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" - -#include "snapshot/snapshot_engine.hpp" -#include "storage/garbage/garbage.hpp" -#include "storage/graph.hpp" -#include "transactions/engine.hpp" - -class Indexes; - -// TODO: Maybe split this in another layer between Db and Dbms. Where the new -// layer would hold SnapshotEngine and his kind of concept objects. Some -// guidelines would be: retain objects which are necessary to implement querys -// in Db, the rest can be moved to the new layer. - -/** - * Main class which represents Database concept in code. - */ -class Db { -public: - using sptr = std::shared_ptr<Db>; - - /** - * This constructor will create a database with the name "default" - * - * NOTE: explicit is here to prevent compiler from evaluating const char * - * into a bool. - * - * @param import_snapshot will in constructor import latest snapshot - * into the db. - */ - explicit Db(bool import_snapshot = true); - - /** - * Construct database with a custom name. - * - * @param name database name - * @param import_snapshot will in constructor import latest snapshot - * into the db. - */ - Db(const char *name, bool import_snapshot = true); - - /** - * Construct database with a custom name. - * - * @param name database name - * @param import_snapshot will in constructor import latest snapshot - * into the db. - */ - Db(const std::string &name, bool import_snapshot = true); - - /** - * Database object can't be copied. - */ - Db(const Db &db) = delete; - -private: - /** database name */ - const std::string name_; - -public: - /** transaction engine related to this database */ - tx::Engine tx_engine; - - /** graph related to this database */ - Graph graph; - - /** garbage collector related to this database*/ - Garbage garbage = {tx_engine}; - - /** - * snapshot engine related to this database - * - * \b IMPORTANT: has to be initialized after name - * */ - SnapshotEngine snap_engine = {*this}; - - /** - * Creates Indexes for this database. - */ - Indexes indexes(); - // TODO: Indexes should be created only once somwhere Like Db or layer - // between Db and Dbms. - - /** - * Returns a name of the database. - * - * @return database name - */ - std::string const &name() const; -}; diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp index a8fc3c0df..77f38ea94 100644 --- a/include/database/db_accessor.hpp +++ b/include/database/db_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_transaction.hpp" #include "utils/border.hpp" #include "utils/iterator/iterator.hpp" diff --git a/include/database/graph_db.hpp b/include/database/graph_db.hpp new file mode 100644 index 000000000..f33e6c8be --- /dev/null +++ b/include/database/graph_db.hpp @@ -0,0 +1,112 @@ +#pragma once + +#include "data_structures/concurrent/skiplist.hpp" +#include "database/db_transaction.hpp" +#include "snapshot/snapshot_engine.hpp" +#include "storage/garbage/garbage.hpp" +#include "transactions/engine.hpp" +#include "mvcc/version_list.hpp" +#include "utils/pass_key.hpp" + +// forward declaring Edge and Vertex because they use +// GraphDb::Label etc., and therefore include this header +class Vertex; +class VertexAccessor; +class Edge; +class EdgeAccessor; + +// TODO: Maybe split this in another layer between Db and Dbms. Where the new +// layer would hold SnapshotEngine and his kind of concept objects. Some +// guidelines would be: retain objects which are necessary to implement querys +// in Db, the rest can be moved to the new layer. + +/** + * Main class which represents Database concept in code. + */ +class GraphDb { +public: + using sptr = std::shared_ptr<GraphDb>; + + // definitions for what data types are used for a Label, Property, EdgeType + using Label = uint32_t; + using EdgeType = uint32_t; + using Property = uint32_t; + + /** + * This constructor will create a database with the name "default" + * + * NOTE: explicit is here to prevent compiler from evaluating const char * + * into a bool. + * + * @param import_snapshot will in constructor import latest snapshot + * into the db. + */ + explicit GraphDb(bool import_snapshot = true); + + /** + * Construct database with a custom name. + * + * @param name database name + * @param import_snapshot will in constructor import latest snapshot + * into the db. + */ + GraphDb(const char *name, bool import_snapshot = true); + + /** + * Construct database with a custom name. + * + * @param name database name + * @param import_snapshot will in constructor import latest snapshot + * into the db. + */ + GraphDb(const std::string &name, bool import_snapshot = true); + + /** + * Database object can't be copied. + */ + GraphDb(const GraphDb &db) = delete; + + /** + * Creates a new Vertex and returns an accessor to it. + * + * @param db_trans The transaction that is creating a vertex. + * @return See above. + */ + VertexAccesor insert_vertex(DbTransaction& db_trans); + + /** + * Creates a new Edge and returns an accessor to it. + * + * @param db_trans The transaction that is creating an Edge. + * @param from The 'from' vertex. + * @param to The 'to' vertex' + * @param type Edge type. + * @return An accessor to the edge. + */ + EdgeAccessor insert_edge(DbTransaction& db_trans, VertexAccessor& from, + VertexAccessor& to, EdgeType type); + + + /** transaction engine related to this database */ + tx::Engine tx_engine; + + + /** garbage collector related to this database*/ +// TODO bring back garbage collection +// Garbage garbage = {tx_engine}; + +// TODO bring back shapshot engine +// SnapshotEngine snap_engine = {*this}; + + // database name + const std::string name_; + +private: + // main storage for the graph + SkipList<mvcc::VersionList<Edge>*> edges_; + SkipList<mvcc::VersionList<Vertex>*> vertices_; + + // utility stuff + const PassKey<GraphDb> pass_key; +}; + diff --git a/include/database/graph_db_accessor.hpp b/include/database/graph_db_accessor.hpp new file mode 100644 index 000000000..589f5d756 --- /dev/null +++ b/include/database/graph_db_accessor.hpp @@ -0,0 +1,24 @@ +// +// Copyright 2017 Memgraph +// Created by Florijan Stamenkovic on 03.02.17. +// + +#pragma + +#include "graph_db.hpp" +#include "transactions/transaction.hpp" + + +class GraphDbAccessor { + +public: + tx::Transaction transaction_; + +private: + + + +}; + + + diff --git a/include/dbms/cleaner.hpp b/include/dbms/cleaner.hpp index 47303339e..c5dd88f6f 100644 --- a/include/dbms/cleaner.hpp +++ b/include/dbms/cleaner.hpp @@ -1,6 +1,6 @@ #pragma once -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "threading/thread.hpp" class Thread; diff --git a/include/dbms/dbms.hpp b/include/dbms/dbms.hpp index 9612d1aad..af503c287 100644 --- a/include/dbms/dbms.hpp +++ b/include/dbms/dbms.hpp @@ -2,7 +2,7 @@ #include "config/config.hpp" #include "data_structures/concurrent/concurrent_map.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "dbms/cleaner.hpp" #include "snapshot/snapshoter.hpp" diff --git a/include/mvcc/version_list.hpp b/include/mvcc/version_list.hpp index 35b05ade7..da0c19b72 100644 --- a/include/mvcc/version_list.hpp +++ b/include/mvcc/version_list.hpp @@ -17,7 +17,7 @@ namespace mvcc { using uptr = std::unique_ptr<VersionList<T>>; using item_t = T; - VersionList(Id id) : id(id) {} + VersionList() = default; VersionList(const VersionList &) = delete; @@ -179,8 +179,6 @@ namespace mvcc { record->mark_deleted(t); } - const Id id; - private: void lock_and_validate(T *record, tx::Transaction &t) { assert(record != nullptr); diff --git a/include/query/engine.hpp b/include/query/engine.hpp index c506f4c7e..bdc6026c5 100644 --- a/include/query/engine.hpp +++ b/include/query/engine.hpp @@ -2,7 +2,7 @@ #include <experimental/filesystem> -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "logging/default.hpp" #include "query/exception/query_engine.hpp" #include "query/plan/program.hpp" diff --git a/include/query/i_plan_cpu.hpp b/include/query/i_plan_cpu.hpp index 0e2fbfa9e..a8790f730 100644 --- a/include/query/i_plan_cpu.hpp +++ b/include/query/i_plan_cpu.hpp @@ -1,7 +1,7 @@ #pragma once #include "communication/communication.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.hpp" #include "query/strip/stripped.hpp" diff --git a/include/query/plan/program_executor.hpp b/include/query/plan/program_executor.hpp index 38537afc4..0e85d3556 100644 --- a/include/query/plan/program_executor.hpp +++ b/include/query/plan/program_executor.hpp @@ -2,7 +2,7 @@ #include <string> -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "query/exception/query_engine.hpp" #include "query/exception/plan_execution.hpp" #include "query/plan/program.hpp" diff --git a/include/snapshot/snapshoter.hpp b/include/snapshot/snapshoter.hpp index 5c72980b4..7b110c381 100644 --- a/include/snapshot/snapshoter.hpp +++ b/include/snapshot/snapshoter.hpp @@ -2,7 +2,7 @@ #include <unordered_map> -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "logging/default.hpp" #include "threading/thread.hpp" diff --git a/include/storage/common.hpp b/include/storage/common.hpp deleted file mode 100644 index 8e29ab91e..000000000 --- a/include/storage/common.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "data_structures/concurrent/concurrent_map.hpp" -#include "mvcc/version_list.hpp" -#include "transactions/transaction.hpp" -#include "utils/counters/atomic_counter.hpp" diff --git a/include/storage/edge.hpp b/include/storage/edge.hpp index 5bff367d1..8525ee355 100644 --- a/include/storage/edge.hpp +++ b/include/storage/edge.hpp @@ -1,38 +1,17 @@ #pragma once +#include "database/graph_db.hpp" #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" +#include "mvcc/version_list.hpp" +#include "storage/typed_value_store.hpp" -class Edge : public mvcc::Record<Edge> -{ - using buffer_t = utils::StringBuffer; - using props_writer_t = JsonWriter<buffer_t>; +// forward declare Vertex because there is a circular usage Edge <-> Vertex +class Vertex; +class Edge : public mvcc::Record<Edge> { public: - class Accessor; - - Edge() = default; - Edge(const EdgeModel &data) : data(data) {} - Edge(EdgeModel &&data) : data(std::move(data)) {} - - Edge(const Edge &) = delete; - Edge(Edge &&) = delete; - - Edge &operator=(const Edge &) = delete; - 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() << ")"; - } + mvcc::VersionList<Vertex>* from_; + mvcc::VersionList<Vertex>* to_; + GraphDb::EdgeType edge_type_; + TypedValueStore properties_; }; diff --git a/include/storage/edge_accessor.hpp b/include/storage/edge_accessor.hpp index 40e0eee24..3eb54ba4f 100644 --- a/include/storage/edge_accessor.hpp +++ b/include/storage/edge_accessor.hpp @@ -1,55 +1,24 @@ #pragma once #include "storage/edge.hpp" -#include "storage/edge_record.hpp" #include "storage/record_accessor.hpp" -#include "storage/vertex_accessor.hpp" #include "utils/assert.hpp" #include "utils/reference_wrapper.hpp" +#include "database/graph_db.hpp" -class EdgeType; -using edge_type_ref_t = ReferenceWrapper<const EdgeType>; - -class Edges; - -// There exists circular dependecy with VertexAccessor. -class EdgeAccessor : public RecordAccessor<TypeGroupEdge, EdgeAccessor> -{ - friend VertexAccessor; +class VertexAccessor; +class EdgeAccessor : public RecordAccessor<Edge, EdgeAccessor> { public: - using RecordAccessor::RecordAccessor; + using RecordAccessor::RecordAccessor; - using record_t = Edge; - using record_list_t = EdgeRecord; + void set_edge_type(GraphDb::EdgeType edge_type); - // Removes self and disconects vertices from it. - void remove() const; + EdgeType edge_type() const; - void edge_type(EdgeType const &edge_type); + VertexAccessor from() const; - const EdgeType &edge_type() const; + VertexAccessor to() const; - // EdgeAccessor doesnt need to be filled - VertexAccessor from() const; - - // 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'; - } + void remove() const; }; diff --git a/include/storage/edge_record.hpp b/include/storage/edge_record.hpp deleted file mode 100644 index 50ce0a42d..000000000 --- a/include/storage/edge_record.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "mvcc/version_list.hpp" -#include "storage/edge.hpp" - -class VertexRecord; - -class EdgeRecord : public mvcc::VersionList<Edge> -{ -public: - EdgeRecord(Id id, VertexRecord *from, VertexRecord *to) - : from_v(from), to_v(to), VersionList(id) - { - } - EdgeRecord(const VersionList &) = delete; - - /* @brief Move constructs the version list - * Note: use only at the beginning of the "other's" lifecycle since this - * constructor doesn't move the RecordLock, but only the head pointer - */ - EdgeRecord(EdgeRecord &&other) - : from_v(other.from_v), to_v(other.to_v), VersionList(std::move(other)) - { - } - - VertexRecord *&get_key() { return this->from_v; } - - auto from() const { return this->from_v; } - - auto to() const { return this->to_v; } - -protected: - VertexRecord *from_v; - VertexRecord *to_v; -}; diff --git a/include/storage/edge_type/edge_type.hpp b/include/storage/edge_type/edge_type.hpp deleted file mode 100644 index 8838c42d8..000000000 --- a/include/storage/edge_type/edge_type.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include <ostream> -#include <stdint.h> - -#include "storage/edge.hpp" -#include "storage/edge_accessor.hpp" -#include "storage/indexes/impl/nonunique_unordered_index.hpp" -#include "storage/type_group_edge.hpp" -#include "utils/char_str.hpp" -#include "utils/reference_wrapper.hpp" -#include "utils/total_ordering.hpp" - -using EdgeTypeIndexRecord = IndexRecord<TypeGroupEdge, std::nullptr_t>; - -class EdgeType : public TotalOrdering<EdgeType> -{ -public: - using type_index_t = NonUniqueUnorderedIndex<TypeGroupEdge, std::nullptr_t>; - - EdgeType() = delete; - - EdgeType(const std::string &id); - EdgeType(const char *id); - EdgeType(std::string &&id); - - EdgeType(const EdgeType &) = delete; - EdgeType(EdgeType &&other) = default; - - friend bool operator<(const EdgeType &lhs, const EdgeType &rhs); - - friend bool operator==(const EdgeType &lhs, const EdgeType &rhs); - - friend std::ostream &operator<<(std::ostream &stream, const EdgeType &type); - - operator const std::string &() const; - - std::string const &str() const { return id; } - - CharStr char_str() { return CharStr(&id[0]); } - - // Index of esges which have this type. - type_index_t &index() const; - -private: - std::string id; - std::unique_ptr<type_index_t> index_v; -}; - -using edge_type_ref_t = ReferenceWrapper<const EdgeType>; diff --git a/include/storage/edge_type/edge_type_store.hpp b/include/storage/edge_type/edge_type_store.hpp deleted file mode 100644 index ac30176b0..000000000 --- a/include/storage/edge_type/edge_type_store.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <stdexcept> - -#include "data_structures/concurrent/concurrent_map.hpp" -#include "storage/edge_type/edge_type.hpp" -#include "utils/char_str.hpp" - -class EdgeTypeStore -{ -public: - using store_t = ConcurrentMap<CharStr, std::unique_ptr<EdgeType>>; - - store_t::Accessor access(); - - const EdgeType &find_or_create(const char *name); - - bool contains(const char *name); // TODO: const - - // TODO: implement find method - // return { EdgeType, is_found } - - // TODO: find by reference if it is possible (should be faster) - // figure out the fastest way to store and find types - // do the same for labels - - // TODO: EdgeTypeStore and LabelStore are almost the same - // templetize the two of them - -private: - store_t edge_types; -}; diff --git a/include/storage/edge_x_vertex.hpp b/include/storage/edge_x_vertex.hpp deleted file mode 100644 index 382fe4a0c..000000000 --- a/include/storage/edge_x_vertex.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// There exists circular dependecy with EdgeAccessor. This file serves to break -// that circularity. -#include "storage/edge_accessor.hpp" -#include "storage/vertex_accessor.hpp" - -auto VertexAccessor::out() const -{ - DbTransaction &t = this->db; - return iter::make_map(iter::make_iter_ref(record->data.out), - [&](auto e) -> auto { return EdgeAccessor(*e, t); }); -} - -auto VertexAccessor::in() const -{ - DbTransaction &t = this->db; - return iter::make_map(iter::make_iter_ref(record->data.in), - [&](auto e) -> auto { return EdgeAccessor(e, t); }); -} diff --git a/include/storage/edges.hpp b/include/storage/edges.hpp deleted file mode 100644 index de6b6ef99..000000000 --- a/include/storage/edges.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include <string> - -#include "data_structures/concurrent/concurrent_map.hpp" -#include "utils/counters/atomic_counter.hpp" -#include "utils/option.hpp" - -#include "storage/edge_record.hpp" -#include "storage/model/properties/property_family.hpp" - -class EdgeAccessor; -class DbTransaction; - -using EdgePropertyFamily = PropertyFamily<TypeGroupEdge>; -template <class K> -using EdgeIndexBase = IndexBase<TypeGroupEdge, K>; - -class Edges -{ - using prop_familys_t = ConcurrentMap<std::string, EdgePropertyFamily *>; - using store_t = ConcurrentMap<uint64_t, EdgeRecord>; - -public: - store_t::Accessor access(); - - Option<const EdgeAccessor> find(DbTransaction &t, const Id &id); - - // Creates new Edge and returns filled EdgeAccessor. - EdgeAccessor insert(DbTransaction &t, VertexRecord *from, VertexRecord *to); - - prop_familys_t::Accessor property_family_access(); - - EdgePropertyFamily &property_family_find_or_create(const std::string &name); - -private: - // TODO: Because familys wont be removed this could be done with more - // efficent - // data structure. - prop_familys_t prop_familys; - - // NOTE: this must be before prop_familys field to be destroyed before them. - // Because there are property_family references in vertices. - store_t edges; - - AtomicCounter<uint64_t> counter; -}; diff --git a/include/storage/indexes/impl/nonunique_unordered_index.hpp b/include/storage/indexes/impl/nonunique_unordered_index.hpp deleted file mode 100644 index 8a551c081..000000000 --- a/include/storage/indexes/impl/nonunique_unordered_index.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "storage/indexes/index_base.hpp" -// #include "storage/indexes/index_record.hpp" - -#include "data_structures/concurrent/concurrent_list.hpp" - -template <class TG, class K> -class NonUniqueUnorderedIndex : public IndexBase<TG, K> -{ -public: - using store_t = ConcurrentList<IndexRecord<TG, K>>; - // typedef T value_type; - // typedef K key_type; - - // Created with the database - NonUniqueUnorderedIndex(IndexLocation &&loc); - - NonUniqueUnorderedIndex(IndexLocation &&loc, tx::Transaction const &t); - - // Insert's value. - // nonunique => always succeds. - bool insert(IndexRecord<TG, K> &&value) final; - - // Returns iterator which returns valid records in range. - // ordered==None => doesn't guarantee any order of submitting records. - iter::Virtual<const typename TG::accessor_t> - for_range(DbAccessor &t, Border<K> from = Border<K>(), - Border<K> to = Border<K>()) final; - - // Same as for_range just whit known returned iterator. - auto for_range_exact(DbAccessor &t, Border<K> from = Border<K>(), - Border<K> to = Border<K>()); - - // Removes for all transactions obsolete Records. - // Cleaner has to call this method when he decideds that it is time for - // cleaning. Id must be id of oldest active transaction. - void clean(const Id &id) final; - -private: - store_t list; -}; diff --git a/include/storage/indexes/impl/unique_ordered_index.hpp b/include/storage/indexes/impl/unique_ordered_index.hpp deleted file mode 100644 index 09a9b22bf..000000000 --- a/include/storage/indexes/impl/unique_ordered_index.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "storage/indexes/index_base.hpp" - -#include "data_structures/concurrent/concurrent_set.hpp" - -// TODO: T shoud be TG (TypeGroup) -template <class T, class K> -class UniqueOrderedIndex : public IndexBase<T, K> -{ -public: - // typedef T value_type; - // typedef K key_type; - - // Created with the database - UniqueOrderedIndex(IndexLocation loc, Order order); - - UniqueOrderedIndex(IndexLocation loc, Order order, - tx::Transaction const &t); - - // Insert's value. - // nonunique => always succeds. - bool insert(IndexRecord<T, K> &&value) final; - - // Returns iterator which returns valid records in range. - // ordered==None => doesn't guarantee any order of submitting records. - iter::Virtual<const typename T::accessor_t> - for_range(DbAccessor &t, Border<K> from = Border<K>(), - Border<K> to = Border<K>()) final; - - // Same as for_range just whith known returned iterator. - auto for_range_exact(DbAccessor &t, Border<K> from = Border<K>(), - Border<K> to = Border<K>()); - - // Removes for all transactions obsolete Records. - // Cleaner has to call this method when he decideds that it is time for - // cleaning. Id must be id of oldest active transaction. - void clean(const Id &id) final; - -private: - ConcurrentSet<IndexRecord<T, K>> set; -}; diff --git a/include/storage/indexes/index_base.hpp b/include/storage/indexes/index_base.hpp deleted file mode 100644 index 9ce62918b..000000000 --- a/include/storage/indexes/index_base.hpp +++ /dev/null @@ -1,84 +0,0 @@ - -#pragma once - -#include <atomic> -#include <functional> -#include <memory> -#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" -#include "utils/iterator/virtual_iter.hpp" - -template <class TG, class K> -class IndexRecord; - -class DbTransaction; -class DbAccessor; -namespace tx -{ -class Transaction; -} - -// Interface for all indexes. -// TG type group -// K type of key on which records are ordered -template <class TG, class K> -class IndexBase : public DeleteSensitive, public Loggable -{ -public: - // Created with the database - IndexBase(IndexDefinition &&it, std::string &&logger_name = "IndexBase"); - - IndexBase(IndexDefinition &&it, const tx::Transaction &t, - std::string &&logger_name = "IndexBase"); - - virtual ~IndexBase(){}; - - // Insert's value. - // unique => returns false if there is already valid equal value. - // nonunique => always succeds. - virtual bool insert(IndexRecord<TG, K> &&value) = 0; - - // Returns iterator which returns valid filled records in range. - // order==noe => doesn't guarantee any order of returned records. - // order==Ascending => guarantees order of returnd records will be from - // smallest to largest. - // order==Descending => guarantees order of returned records will be from - // largest to smallest. - // Range must be from<=to - virtual iter::Virtual<const typename TG::accessor_t> - for_range(DbAccessor &, Border<K> from = Border<K>(), - Border<K> to = Border<K>()) = 0; - - // Removes for all transactions obsolete Records. - // Cleaner has to call this method when he decideds that it is time for - // cleaning. Id must be id of oldest active transaction. - virtual void clean(const Id &id) = 0; - - // Activates index for readers. - void activate(); - - // True if index is ready for reading. - bool can_read(); - - // True if transaction is obliged to insert T into index. - bool is_obliged_to_insert(const tx::Transaction &t); - - IndexType type() const { return it.type; } - - const IndexDefinition &definition() const { return it; } - -protected: - Logger logger; - -private: - const IndexDefinition it; - // Id of transaction which created this index. - const Id created; - // Active state - std::atomic_bool active = {false}; -}; diff --git a/include/storage/indexes/index_definition.hpp b/include/storage/indexes/index_definition.hpp deleted file mode 100644 index e99705d1b..000000000 --- a/include/storage/indexes/index_definition.hpp +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include "utils/option.hpp" -#include "utils/order.hpp" -#include "utils/underlying_cast.hpp" - -enum DbSide : uint8_t -{ - EdgeSide = 0, - VertexSide = 1, -}; - -struct IndexType -{ -public: - // Are the records unique - const bool unique; - // Ordering of the records. - const Order order; -}; - -// Defines location of index in a sense of what is necessary to be present in -// Edge/Vertex for it to be in index. -struct IndexLocation -{ -public: - // Returns code for location. - size_t location_code() const - { - return (property_name.is_present() ? 1 : 0) | - (label_name.is_present() ? 2 : 0) | - (edge_type_name.is_present() ? 4 : 0); - } - - IndexLocation clone() const - { - return IndexLocation{side, property_name, label_name, edge_type_name}; - } - - const DbSide side; - const Option<std::string> property_name; - const Option<std::string> label_name; - const Option<std::string> edge_type_name; -}; - -// Fully answers: -// Index on what? -// What kind of index? -struct IndexDefinition -{ -public: - // Serializes self which can be deserialized. - template <class E> - void serialize(E &encoder) const - { - std::string empty; - encoder.write_integer(underlying_cast(loc.side)); - encoder.write_string(loc.property_name.get_or(empty)); - encoder.write_string(loc.label_name.get_or(empty)); - encoder.write_string(loc.edge_type_name.get_or(empty)); - encoder.write_bool(type.unique); - encoder.write_integer(underlying_cast(type.order)); - } - - // Deserializes self. - template <class D> - static IndexDefinition deserialize(D &decoder) - { - auto side = decoder.integer() == 0 ? EdgeSide : VertexSide; - - std::string property_name_s; - decoder.string(property_name_s); - auto property_name = - property_name_s.empty() - ? Option<std::string>() - : Option<std::string>(std::move(property_name_s)); - - std::string label_name_s; - decoder.string(label_name_s); - auto label_name = label_name_s.empty() - ? Option<std::string>() - : Option<std::string>(std::move(label_name_s)); - - std::string edge_type_name_s; - decoder.string(edge_type_name_s); - auto edge_type_name = - edge_type_name_s.empty() - ? Option<std::string>() - : Option<std::string>(std::move(edge_type_name_s)); - - bool unique = decoder.read_bool(); - - auto order_v = decoder.integer(); - auto order = - order_v == 0 ? None : (order_v == 1 ? Ascending : Descending); - - return IndexDefinition{ - IndexLocation{side, property_name, label_name, edge_type_name}, - IndexType{unique, order}}; - } - - const IndexLocation loc; - const IndexType type; -}; diff --git a/include/storage/indexes/index_holder.hpp b/include/storage/indexes/index_holder.hpp deleted file mode 100644 index 28626b489..000000000 --- a/include/storage/indexes/index_holder.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include <atomic> - -#include "storage/indexes/index_base.hpp" -#include "utils/option.hpp" -#include "utils/option_ptr.hpp" - -namespace tx -{ -class Transaction; -} - -// Holds one index which can be changed. Convinient class. -// TG - type group -// K - key of index_records -template <class TG, class K> -class IndexHolder -{ - -public: - IndexHolder() = default; - - IndexHolder(IndexHolder const &) = delete; - - IndexHolder(IndexHolder &&) = default; - - // Sets index for this property family. returns false if index is already - // present. - bool set_index(std::unique_ptr<IndexBase<TG, K>> inx); - - // Returns index for read only if it is present and it's valid for read. - OptionPtr<IndexBase<TG, K>> get_read() const; - - // Returns index for write only if it's present and transaction is - // responsibly for updating it. - OptionPtr<IndexBase<TG, K>> get_write(const tx::Transaction &t) const; - - // Removes index if it is given index. Caller is now responsable of - // disposing index in a safe way. - Option<std::unique_ptr<IndexBase<TG, K>>> - remove_index(IndexBase<TG, K> *index); - - // Caller is now responsable of disposing index in a safe way. - Option<std::unique_ptr<IndexBase<TG, K>>> remove_index(); - -private: - std::atomic<IndexBase<TG, K> *> index = {nullptr}; -}; diff --git a/include/storage/indexes/index_record.hpp b/include/storage/indexes/index_record.hpp deleted file mode 100644 index 4c54c376a..000000000 --- a/include/storage/indexes/index_record.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "mvcc/id.hpp" -#include "utils/border.hpp" -#include "utils/total_ordering.hpp" - -namespace tx -{ -class Transaction; -} -class DbTransaction; - -// TG type group -// K key on which record is ordered. -template <class TG, class K> -class IndexRecord : public TotalOrdering<IndexRecord<TG, K>>, - public TotalOrdering<Border<K>, IndexRecord<TG, K>> -{ -public: - IndexRecord() = default; - - IndexRecord(K key, typename TG::record_t *record, - typename TG::vlist_t *vlist); - - friend bool operator<(const IndexRecord &lhs, const IndexRecord &rhs) - { - return (lhs.key < rhs.key || - (lhs.key == rhs.key && lhs.vlist == rhs.vlist && - lhs.record < rhs.record)) ^ - lhs.descending; - } - - friend bool operator==(const IndexRecord &lhs, const IndexRecord &rhs) - { - return lhs.key == rhs.key && - (lhs.vlist != rhs.vlist || lhs.record == rhs.record); - } - - friend bool operator<(const Border<K> &lhs, const IndexRecord &rhs) - { - return lhs < rhs.key; - } - - friend bool operator==(const Border<K> &lhs, const IndexRecord &rhs) - { - return lhs == rhs.key; - } - - // Will change ordering of record to descending. - void set_descending(); - - // true if record is nullptr. - bool empty() const; - - // True if this index record i valid for given Transaction. - bool is_valid(tx::Transaction &t) const; - - // True if it can be removed. - bool to_clean(const Id &oldest_active) const; - - // This method is valid only if is_valid is true. - const auto access(DbTransaction &db) const; - - const K key; - -private: - bool descending = false; // TODO: this can be passed as template argument. - typename TG::record_t *const record{nullptr}; - typename TG::vlist_t *const vlist{nullptr}; -}; diff --git a/include/storage/indexes/index_update.hpp b/include/storage/indexes/index_update.hpp deleted file mode 100644 index 899eff11f..000000000 --- a/include/storage/indexes/index_update.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "storage/indexes/index_record.hpp" -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" - -// Record for updating indexes of edge -struct IndexUpdateEdge -{ - EdgeRecord *vlist; - Edge *record; -}; - -// Record for updatin indexes of vertex -struct IndexUpdateVertex -{ - VertexRecord *vlist; - Vertex *record; -}; - -// based of IndexUpdate objects IndexRecords are created -// at the end of transaction (inside commit called on DbAccessor) -struct IndexUpdate -{ - enum - { - EDGE, - VERTEX - } tag; - - union - { - IndexUpdateEdge e; - IndexUpdateVertex v; - }; -}; - -template <class T, class V> -IndexUpdate make_index_update(V *vlist, T *record); - -template <> -IndexUpdate make_index_update(EdgeRecord *vlist, Edge *record); - -template <> -IndexUpdate make_index_update(VertexRecord *vlist, Vertex *record); diff --git a/include/storage/indexes/indexes.hpp b/include/storage/indexes/indexes.hpp deleted file mode 100644 index 677d21fea..000000000 --- a/include/storage/indexes/indexes.hpp +++ /dev/null @@ -1,308 +0,0 @@ -#pragma once - -#include "database/db.hpp" -#include "storage/garbage/garbage.hpp" -#include "storage/graph.hpp" -#include "storage/indexes/impl/nonunique_unordered_index.hpp" -#include "storage/indexes/impl/unique_ordered_index.hpp" -#include "storage/indexes/index_definition.hpp" -#include "transactions/engine.hpp" -#include "utils/exceptions/non_exaustive_switch.hpp" -#include "utils/exceptions/not_yet_implemented.hpp" - -// Operation on indexes in the This should be the only place which knows how -// to get all indexes in database. -// TODO: This class should be updated accordingly when adding new place for -// index. -class Indexes -{ -public: - Indexes(Db &d) : db(d) {} - - // Adds index defined in given definition. Returns true if successfull. - bool add_index(IndexDefinition id); - - // currently caller has to get index through object that contains - // the index - - // TODO: redesign - // - // this was a nice try - // // Returns index from location. - // template <class TG, class K> - // Option<IndexHolder<TG, K>> get_index(IndexLocation loc) - // { - // size_t code = loc.location_code(); - // - // switch (code) { - // case 0: // Illegal location - // return Option<IndexHolder<TG, K>>(); - // - // case 1: - // switch (loc.side) { - // case EdgeSide: { - // return make_option( - // db.graph.edges - // .property_family_find_or_create(loc.property_name.get()) - // .index); - // } - // case VertexSide: { - // return make_option( - // db.graph.vertices - // .property_family_find_or_create(loc.property_name.get()) - // .index); - // } - // default: - // throw new NonExhaustiveSwitch("Unkown side: " + - // std::to_string(loc.side)); - // }; - // - // case 2: // Can't be removed - // return Option<IndexHolder<TG, K>>(); - // - // case 3: // Not yet implemented - // throw new NotYetImplemented("Getting index over label and " - // "property isn't yet implemented"); - // case 4: // Can't be removed - // return Option<IndexHolder<TG, K>>(); - // - // case 5: // Not yet implemented - // throw new NotYetImplemented("Getting index over edge_type and " - // "property isn't yet implemented"); - // case 6: // Not yet implemented - // throw new NotYetImplemented("Getting index over edge_type and " - // "label isn't yet implemented"); - // case 7: // Not yet implemented - // throw new NotYetImplemented("Getting index over label, edge_type - // " - // "and property isn't yet - // implemented"); - // default: - // throw new NonExhaustiveSwitch("Unkown index location code: " + - // std::to_string(code)); - // } - // } - - // Removes index from given location. Returns true if successfull or if no - // index was present. False if index location is illegal. - bool remove_index(IndexLocation loc) - { - size_t code = loc.location_code(); - - switch (code) { - case 0: // Illegal location - return false; - - case 1: - switch (loc.side) { - case EdgeSide: { - return remove_index( - db.graph.edges - .property_family_find_or_create(loc.property_name.get()) - .index); - } - case VertexSide: { - return remove_index( - db.graph.vertices - .property_family_find_or_create(loc.property_name.get()) - .index); - } - default: - throw new NonExhaustiveSwitch("Unkown side: " + - std::to_string(loc.side)); - }; - - case 2: // Can't be removed - return false; - - case 3: // Not yet implemented - throw new NotYetImplemented("Remove of index over label and " - "property isn't yet implemented"); - case 4: // Can't be removed - return false; - - case 5: // Not yet implemented - throw new NotYetImplemented("Remove of index over edge_type and " - "property isn't yet implemented"); - case 6: // Not yet implemented - throw new NotYetImplemented("Remove of index over edge_type and " - "label isn't yet implemented"); - case 7: // Not yet implemented - throw new NotYetImplemented("Remove of index over label, edge_type " - "and property isn't yet implemented"); - default: - throw new NonExhaustiveSwitch("Unkown index location code: " + - std::to_string(code)); - } - } - - // Calls F over all vertex indexes in the database which are readable. - template <class F> - void vertex_indexes(F &&f) - { - for (auto &l : db.graph.label_store.access()) { - f(l.second.get()->index()); - } - - for_all_property_indexes_read( - db.graph.vertices.property_family_access(), f); - } - - // Calls F over all edge indexes in the database which are readable. - template <class F> - void edge_indexes(F &&f) - { - for (auto &l : db.graph.edge_type_store.access()) { - f(l.second.get()->index()); - } - - for_all_property_indexes_read(db.graph.edges.property_family_access(), - f); - } - - // Updates property indexes for given TypeGroup TG and IU index_update - template <class TG, class IU> - bool update_property_indexes(IU &iu, const tx::Transaction &t) - { - for (auto kp : iu.record->data.props) { - - // FamilyProperty index - auto opi = kp.key.get_family().index.get_write(t); - if (opi.is_present()) { - if (!opi.get()->insert(IndexRecord<TG, std::nullptr_t>( - std::nullptr_t(), iu.record, iu.vlist))) { - return false; - } - } - - // TODO: other property indexes - } - - return true; - } - -private: - // Calls F for all * property indexes which are readable. - template <class A, class F> - void for_all_property_indexes_read(A &&acc, F &f) - { - for (auto &family : acc) { - auto oi = family.second->index.get_read(); - if (oi.is_present()) { - f(*oi.get()); - } - } - - // TODO: Code for reaching other property indexes which are not yet - // coded into the database. - } - - // Creates type of index specified ind index definition. - // TG - type group vertex/edge - // K - key of index - template <class TG, class K> - std::unique_ptr<IndexBase<TG, K>> create_index(IndexDefinition id, - tx::Transaction const &t) - { - // Determine which index is needed - if (id.type.unique) { - switch (id.type.order) { - case None: { - // TODO: Implement this version of index. - throw NotYetImplemented( - "Missing implementation for Unique Unordered Index"); - } - case Ascending: - case Descending: { - return std::make_unique<UniqueOrderedIndex<TG, K>>( - id.loc.clone(), id.type.order, t); - } - default: - throw new NonExhaustiveSwitch("Unknown order: " + - std::to_string(id.type.order)); - }; - - } else { - switch (id.type.order) { - case None: { - return std::make_unique<NonUniqueUnorderedIndex<TG, K>>( - id.loc.clone(), t); - } - case Ascending: - case Descending: { - // TODO: Implement this version of index. - throw NotYetImplemented( - "Missing implementation for Nonunique Ordered Index"); - } - default: - throw new NonExhaustiveSwitch("Unknown order: " + - std::to_string(id.type.order)); - }; - } - } - - // Fills index with returned elements. Return true if successfully filled. - // Iterator must return std::pair<TG::accessor_t, K> - template <class TG, class K, class I> - bool fill_index(DbTransaction &t, IndexHolder<TG, K> &holder, I &&iter) - { - // Wait for all other active transactions to finish so that this - // transaction can see there changes so that they can be added into - // index. - t.trans.wait_for_active(); - - auto oindex = holder.get_write(t.trans); - if (oindex.is_present()) { - // Inexed to which whe must insert is present. This wouldn't be the - // case if someone removed it. - auto index = oindex.get(); - - // Iterate over all elements and add them into index. Fail if - // some insert failed. - bool res = iter.all([&](auto elem) { - // Try to insert record. - if (!index->insert(elem.first.create_index_record( - std::move(elem.second)))) { - // Index is probably unique. - - // Index wasn't successfully filled so whe should remove it - // an safely dispose of it. - auto owned_maybe = holder.remove_index(index); - if (owned_maybe.is_present()) { - db.garbage.dispose(db.tx_engine.snapshot(), - owned_maybe.get().release()); - } - - return false; - } - return true; - }); - if (res) { - // Index has been updated accordingly and whe can activate it - // for read. - index->activate(); - return true; - } - } - - return false; - } - - // Removes index from index holder - template <class TG, class K> - bool remove_index(IndexHolder<TG, K> &ih) - { - auto owned_maybe = ih.remove_index(); - if (owned_maybe.is_present()) { - // Index was successfully removed so whe are responsible for - // dispoising it safely. - db.garbage.dispose(db.tx_engine.snapshot(), - owned_maybe.get().release()); - return true; - } - - return false; - } - - Db &db; -}; diff --git a/include/storage/indexes/keys/index_key.hpp b/include/storage/indexes/keys/index_key.hpp deleted file mode 100644 index 0dd847153..000000000 --- a/include/storage/indexes/keys/index_key.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -// TODO: DEPRICATED - -#include "utils/total_ordering.hpp" - -#include "storage/model/properties/properties.hpp" -#include "storage/model/properties/property.hpp" - -template <class Ordering> -class UniqueIndexKey -{ -public: -}; - -template <class Ordering> -class IndexKey -{ -public: -}; diff --git a/include/storage/indexes/keys/non_unique_key.hpp b/include/storage/indexes/keys/non_unique_key.hpp deleted file mode 100644 index d64227258..000000000 --- a/include/storage/indexes/keys/non_unique_key.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -// TODO: DEPRICATED - -#include "unique_key.hpp" - -template <class K, class T, class SortOrder> -class NonUniqueKey -{ -public: - NonUniqueKey(const K& key, const T&) - { - - } - -private: - intptr_t x; -}; diff --git a/include/storage/indexes/keys/unique_key.hpp b/include/storage/indexes/keys/unique_key.hpp deleted file mode 100644 index 6c415795c..000000000 --- a/include/storage/indexes/keys/unique_key.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -// TODO: DEPRICATED - -#include "utils/total_ordering.hpp" - -#include "storage/indexes/sort_order.hpp" -#include "storage/model/properties/properties.hpp" -#include "storage/model/properties/property.hpp" - -template <class K, class SortOrder> -class UniqueKey : public TotalOrdering<UniqueKey<K, SortOrder>> -{ -public: - using type = UniqueKey<K, SortOrder>; - using key_t = K; - - UniqueKey(const K& key) : key(key) {} - - friend constexpr bool operator<(const type& lhs, const type& rhs) - { - return sort_order(lhs.key, rhs.key); - } - - friend constexpr bool operator==(const type& lhs, const type& rhs) - { - return lhs.key == rhs.key; - } - - operator const K&() const { return key; } - -private: - static constexpr SortOrder sort_order = SortOrder(); - const K& key; -}; - -template <class K, class SortOrder> -constexpr SortOrder UniqueKey<K, SortOrder>::sort_order; - -template <class K> -using UniqueKeyAsc = UniqueKey<K, Ascending<K>>; - -template <class K> -using UniqueKeyDesc = UniqueKey<K, Descending<K>>; - diff --git a/include/storage/iterator/graph_composable.hpp b/include/storage/iterator/graph_composable.hpp deleted file mode 100644 index 37093d967..000000000 --- a/include/storage/iterator/graph_composable.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "utils/iterator/composable.hpp" - -// Class for creating easy composable iterators for querying. -// -// This class contains graph specific methods. -// -// Derived - type of derived class -// T - return type -template <class T, Derived> -class GraphComposable : public Composable<T, GraphComposable<T, Derived>> -{ - // TODO: various filters - // from filter - // to filter - // match filter -}; - - diff --git a/include/storage/iterator/graph_filter.hpp b/include/storage/iterator/graph_filter.hpp deleted file mode 100644 index 6a26f2acf..000000000 --- a/include/storage/iterator/graph_filter.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "utils/iterator/filter.hpp" -#include "storage/iterator/graph_composable.hpp" - -template <class T, class I, class OP> -class GraphFilter : public Filter<T, I, OP>, - public GraphComposable<T, GraphFilter<T, I, OP> -{ - using Filter::Filter; -}; - -template <class I, class OP> -auto make_graph_filter(I &&iter, OP &&op) -{ - // Compiler cant deduce type T. decltype is here to help with it. - return GraphFilter<decltype(iter.next().take()), I, OP>(std::move(iter), - std::move(op)); -} diff --git a/include/storage/label/label.hpp b/include/storage/label/label.hpp deleted file mode 100644 index f3bdfb63f..000000000 --- a/include/storage/label/label.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include <ostream> -#include <stdint.h> - -#include "storage/indexes/impl/nonunique_unordered_index.hpp" -#include "storage/type_group_vertex.hpp" -#include "storage/vertex.hpp" -#include "storage/vertex_accessor.hpp" -#include "utils/char_str.hpp" -#include "utils/reference_wrapper.hpp" -#include "utils/total_ordering.hpp" - -using LabelIndexRecord = IndexRecord<TypeGroupVertex, std::nullptr_t>; - -class Label : public TotalOrdering<Label>, TotalOrdering<CharStr, Label> -{ -public: - using label_index_t = - NonUniqueUnorderedIndex<TypeGroupVertex, std::nullptr_t>; - - Label() = delete; - - Label(const char *name); - - Label(const Label &) = delete; - Label(Label &&other) = default; - - friend bool operator<(const Label &lhs, const Label &rhs); - - friend bool operator==(const Label &lhs, const Label &rhs); - - friend bool operator<(const CharStr &lhs, const Label &rhs); - - friend bool operator==(const CharStr &lhs, const Label &rhs); - - friend std::ostream &operator<<(std::ostream &stream, const Label &label); - - operator const std::string &() const; - - std::string const &str() const { return name; } - - CharStr char_str() const { return CharStr(name.c_str()); } - - // Index of vertices with current label. - label_index_t &index() const; - -private: - std::unique_ptr<label_index_t> index_v; - std::string name; -}; - -using label_ref_t = ReferenceWrapper<const Label>; diff --git a/include/storage/label/label_collection.hpp b/include/storage/label/label_collection.hpp deleted file mode 100644 index 564c29392..000000000 --- a/include/storage/label/label_collection.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <vector> - -#include "utils/reference_wrapper.hpp" - -class Label; -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 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; - size_t count() const; - bool remove(const Label &label); - 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_; -}; diff --git a/include/storage/label/label_store.hpp b/include/storage/label/label_store.hpp deleted file mode 100644 index 35ce3166a..000000000 --- a/include/storage/label/label_store.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <stdexcept> - -#include "data_structures/concurrent/concurrent_set.hpp" -#include "storage/label/label.hpp" -#include "utils/char_str.hpp" - -class LabelStore -{ -public: - using store_t = ConcurrentMap<CharStr, std::unique_ptr<Label>>; - - store_t::Accessor access(); - - const Label &find_or_create(const char *name); - - bool contains(const char *name); // TODO: const - - // TODO: implement find method - // return { Label, is_found } - -private: - store_t labels; -}; diff --git a/include/storage/label/labels_writer.hpp b/include/storage/label/labels_writer.hpp deleted file mode 100644 index a075766b1..000000000 --- a/include/storage/label/labels_writer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -class Label; - -template <class Buffer> -class LabelsWriter -{ -public: - LabelsWriter(Buffer &buffer) : buffer_(buffer) {} - - ~LabelsWriter() = default; - - LabelsWriter(const LabelsWriter &) = delete; - LabelsWriter(LabelsWriter &&) = delete; - - LabelsWriter &operator=(const LabelsWriter &) = delete; - LabelsWriter &operator=(LabelsWriter &&) = delete; - - void handle(const Label& label); - -private: - Buffer& buffer_; -}; diff --git a/include/storage/model/edge_list.hpp b/include/storage/model/edge_list.hpp deleted file mode 100644 index 15703beef..000000000 --- a/include/storage/model/edge_list.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include <vector> - -#include "mvcc/version_list.hpp" -#include "storage/edge_record.hpp" - -class EdgeList -{ -public: - auto begin() { return edges.begin(); } - auto begin() const { return edges.begin(); } - auto cbegin() const { return edges.begin(); } - - auto end() { return edges.end(); } - auto end() const { return edges.end(); } - auto cend() const { return edges.end(); } - - void add(EdgeRecord *edge) { edges.emplace_back(edge); } - - size_t degree() const { return edges.size(); } - - void remove(EdgeRecord *edge) - { - edges.erase(std::remove(edges.begin(), edges.end(), edge), edges.end()); - } - - void clear() { edges.clear(); } - - std::size_t size() { return edges.size(); } - -private: - std::vector<EdgeRecord *> edges; -}; diff --git a/include/storage/model/edge_map.hpp b/include/storage/model/edge_map.hpp deleted file mode 100644 index 521e13e8b..000000000 --- a/include/storage/model/edge_map.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "data_structures/map/rh_hashmultimap.hpp" -#include "storage/edge_record.hpp" - -class EdgeMap -{ -public: - auto begin() { return edges.begin(); } - auto begin() const { return edges.begin(); } - auto cbegin() const { return edges.begin(); } - - auto end() { return edges.end(); } - auto end() const { return edges.end(); } - auto cend() const { return edges.end(); } - - size_t degree() const { return edges.size(); } - - void add(EdgeRecord *edge) { edges.add(edge); } - - void remove(EdgeRecord *edge) - { - edges.remove(edge); // Currently the return is ignored - } - - bool contains(VertexRecord *vr) const { return edges.contains(vr); } - - void clear() { edges.clear(); } - - std::size_t size() { return edges.size(); } - -private: - RhHashMultiMap<VertexRecord *, EdgeRecord> edges; -}; diff --git a/include/storage/model/edge_model.hpp b/include/storage/model/edge_model.hpp deleted file mode 100644 index 2d3be107e..000000000 --- a/include/storage/model/edge_model.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// #include "mvcc/version_list.hpp" -// #include "storage/edge_type/edge_type.hpp" -#include "storage/model/property_model.hpp" -#include "storage/type_group_edge.hpp" - -class EdgeType; - -class EdgeModel : public PropertyModel<TypeGroupEdge> -{ -public: - // TODO: here should be the reference - // but something that is copyable - // because this model is copied all the time (mvcc) - const EdgeType *edge_type{nullptr}; -}; diff --git a/include/storage/model/property_model.hpp b/include/storage/model/property_model.hpp deleted file mode 100644 index 466446723..000000000 --- a/include/storage/model/property_model.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "storage/model/properties/properties.hpp" - -template <class TG> -class PropertyModel -{ -public: - Properties<TG> props; -}; diff --git a/include/storage/model/vertex_model.hpp b/include/storage/model/vertex_model.hpp deleted file mode 100644 index 088fbd549..000000000 --- a/include/storage/model/vertex_model.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "storage/label/label_collection.hpp" -#include "storage/model/edge_list.hpp" -#include "storage/model/edge_map.hpp" -#include "storage/model/property_model.hpp" - -class VertexModel : public PropertyModel<TypeGroupVertex> -{ -public: - EdgeList out; - EdgeMap in; - LabelCollection labels; -}; diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp index 466ae97a6..360b501f8 100644 --- a/include/storage/record_accessor.hpp +++ b/include/storage/record_accessor.hpp @@ -2,175 +2,89 @@ #include "database/db_transaction.hpp" #include "mvcc/version_list.hpp" -#include "storage/indexes/index_record.hpp" -#include "storage/indexes/index_update.hpp" -#include "storage/model/properties/properties.hpp" -#include "storage/model/properties/property.hpp" -#include "storage/model/properties/property_family.hpp" -#include "storage/model/properties/stored_property.hpp" #include "transactions/transaction.hpp" +#include "storage/typed_value.hpp" +#include "database/graph_db.hpp" +#include "utils/pass_key.hpp" -template <class TG, class Derived> -class RecordAccessor -{ - friend DbAccessor; - using vlist_t = typename TG::vlist_t; - using T = typename TG::record_t; +template <typename TRecord, typename TDerived> +class RecordAccessor { public: - RecordAccessor(vlist_t *vlist, DbTransaction &db) : vlist(vlist), db(db) - { - assert(vlist != nullptr); + + RecordAccessor(mvcc::VersionList<TRecord>* vlist, DbTransaction &db_trans) + : vlist_(vlist), db_trans_(db_trans) { + assert(vlist_ != nullptr); + } + + RecordAccessor(TRecord *t, mvcc::VersionList<TRecord> *vlist, DbTransaction &db_trans) + : record_(t), vlist_(vlist), db_trans_(db_trans) { + assert(record_ != nullptr); + assert(vlist_ != nullptr); + } + + // TODO: Test this + TDerived update() const { + assert(!empty()); + + if (record_->is_visible_write(db_trans_.trans)) { + // TODO: VALIDATE THIS BRANCH. THEN ONLY THIS TRANSACTION CAN SEE + // THIS DATA WHICH MEANS THAT IT CAN CHANGE IT. + return TDerived(record_, vlist_, db_trans_); + + } else { + auto new_record_ = vlist_->update(db_trans_.trans); + + // TODO: Validate that update of record in this accessor is correct. + const_cast<RecordAccessor *>(this)->record_ = new_record; + return TDerived(new_record, vlist_, db_trans_); } + } - RecordAccessor(T *t, vlist_t *vlist, DbTransaction &db) - : record(t), vlist(vlist), db(db) - { - assert(record != nullptr); - assert(vlist != nullptr); - } + TypedValue at(GraphDb::Property key) const { + return record_->props_.at(key); + } - RecordAccessor(RecordAccessor const &other) - : record(other.record), vlist(other.vlist), db(other.db) - { - } - RecordAccessor(RecordAccessor &&other) - : record(other.record), vlist(other.vlist), db(other.db) - { - } + template <typename TValue> + void set(GraphDb::Property key, TValue value) { + // TODO should update be called here?!?! + record_->props_.set(key, value); + } - bool empty() const { return record == nullptr; } + size_t erase(GraphDb::Property key) const { + return record_->props_.erase(key); + } - // Fills accessor and returns true if there is valid data for current - // transaction false otherwise. - bool fill() const - { - const_cast<RecordAccessor *>(this)->record = vlist->find(db.trans); - return record != nullptr; - } + void Accept(std::function<void(const GraphDb::Property key, const TypedValue& prop)> handler, + std::function<void()> finish = {}) const { + record_->props_.Accept(handler, finish); + } - const Id &id() const { return vlist->id; } + // Assumes same transaction + friend bool operator==(const RecordAccessor &a, const RecordAccessor &b) { + // TODO consider the legitimacy of this comparison + return a.vlist_ == b.vlist_; + } - // True if record visible for current transaction is visible to given - // transaction id. - bool is_visble_to(tx::TransactionRead const &id) - { - return record->visible(id); - } + // Assumes same transaction + friend bool operator!=(const RecordAccessor &a, const RecordAccessor &b) { + // TODO consider the legitimacy of this comparison + return !(a == b); + } - // Returns new IndexRecord with given key. - template <class K> - IndexRecord<TG, K> create_index_record(K &&key) - { - return IndexRecord<TG, K>(std::move(key), record, vlist); - } + /** + * Exposes the version list only to the GraphDb. + * + * @param pass_key Ignored. + * @return The version list of this accessor. + */ + mvcc::VersionList<TRecord>* vlist(Passkey<GraphDb> pass_key) { + return vlist_; + } - // TODO: Test this - Derived update() const - { - assert(!empty()); - - if (record->is_visible_write(db.trans)) { - // TODO: VALIDATE THIS BRANCH. THEN ONLY THIS TRANSACTION CAN SEE - // THIS DATA WHICH MEANS THAT IT CAN CHANGE IT. - return Derived(record, vlist, db); - - } else { - auto new_record = vlist->update(db.trans); - - // TODO: Validate that update of record in this accessor is correct. - const_cast<RecordAccessor *>(this)->record = new_record; - - // Add record to update index. - db.to_update_index<TG>(vlist, new_record); - - return Derived(new_record, vlist, db); - } - } - - bool contains(property_key<TG> &key) const - { - return properties().contains(key); - } - - const StoredProperty<TG> &at(PropertyFamily<TG> &key) const - { - return properties().at(key); - } - - const StoredProperty<TG> &at(property_key<TG> &key) const - { - return properties().at(key); - } - - template <class V> - OptionPtr<const V> at(type_key_t<TG, V> &key) const - { - return properties().template at<V>(key); - } - - void set(property_key<TG> &key, Property value) - { - properties().set(StoredProperty<TG>(std::move(value), key)); - } - - void set(StoredProperty<TG> value) { properties().set(std::move(value)); } - - void clear(property_key<TG> &key) { properties().clear(key); } - - void clear(PropertyFamily<TG> &key) { properties().clear(key); } - - template <class Handler> - void accept(Handler &handler) const - { - properties().template accept<Handler>(handler); - } - - template <class Handler> - void handle(Handler &handler) const - { - properties().template handle<Handler>(handler); - } - - Properties<TG> &properties() const { return record->data.props; } - - explicit operator bool() const { return record != nullptr; } - - T const *operator->() const { return record; } - T *operator->() { return record; } - - RecordAccessor &operator=(const RecordAccessor &other) - { - record = other.record; - vlist_t *&vl = const_cast<vlist_t *&>(vlist); - vl = other.vlist; - return *this; - } - - RecordAccessor &operator=(RecordAccessor &&other) - { - record = other.record; - vlist_t *&vl = const_cast<vlist_t *&>(vlist); - vl = other.vlist; - return *this; - } - - // Assumes same transaction - friend bool operator==(const RecordAccessor &a, const RecordAccessor &b) - { - return a.vlist == b.vlist; - } - - // Assumes same transaction - friend bool operator!=(const RecordAccessor &a, const RecordAccessor &b) - { - return !(a == b); - } protected: - void remove() const; - - T *record{nullptr}; - vlist_t *const vlist; - DbTransaction &db; + TRecord* record_{nullptr}; + mvcc::VersionList<TRecord>* vlist_; + DbTransaction& db_trans_; }; diff --git a/include/storage/type_group_edge.hpp b/include/storage/type_group_edge.hpp deleted file mode 100644 index f0871f865..000000000 --- a/include/storage/type_group_edge.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -class Edge; -class EdgeRecord; -class EdgeAccessor; - -// Types for Edge side of database. Firstly there exists need for knowing the -// type of object to be able to efficently use it. Dependant classes can -// templetaze over such type, but this is anoying and error prone if there are -// multiple such types over which it is necessary to templetaze. The idea is to -// unify groups of logicaly tyed types into one type. That way depending classes -// can template over that one type. -class TypeGroupEdge -{ -public: - using record_t = Edge; - using vlist_t = EdgeRecord; - using accessor_t = EdgeAccessor; -}; diff --git a/include/storage/type_group_vertex.hpp b/include/storage/type_group_vertex.hpp deleted file mode 100644 index 2c103ee78..000000000 --- a/include/storage/type_group_vertex.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -class Vertex; -class VertexRecord; -class VertexAccessor; - -// Types for Vertex side of database. Firstly there exists need for knowing the -// type of object to be able to efficently use it. Dependant classes can -// templetaze over such type, but this is anoying and error prone if there are -// multiple such types over which it is necessary to templetaze. The idea is to -// unify groups of logicaly tyed types into one type. That way depending classes -// can template over that one type. -class TypeGroupVertex -{ -public: - using record_t = Vertex; - using vlist_t = VertexRecord; - using accessor_t = VertexAccessor; -}; diff --git a/include/storage/model/typed_value.hpp b/include/storage/typed_value.hpp similarity index 100% rename from include/storage/model/typed_value.hpp rename to include/storage/typed_value.hpp diff --git a/include/storage/model/typed_value_store.hpp b/include/storage/typed_value_store.hpp similarity index 100% rename from include/storage/model/typed_value_store.hpp rename to include/storage/typed_value_store.hpp diff --git a/include/storage/model/typed_value_utils.h b/include/storage/typed_value_utils.h similarity index 96% rename from include/storage/model/typed_value_utils.h rename to include/storage/typed_value_utils.h index 5b5af377f..493c10229 100644 --- a/include/storage/model/typed_value_utils.h +++ b/include/storage/typed_value_utils.h @@ -6,7 +6,7 @@ #pragma once #include <ostream> -#include "storage/model/typed_value_store.hpp" +#include "storage/typed_value_store.hpp" /** diff --git a/include/storage/vertex.hpp b/include/storage/vertex.hpp index 309cd5af9..095dd7e8c 100644 --- a/include/storage/vertex.hpp +++ b/include/storage/vertex.hpp @@ -1,42 +1,18 @@ #pragma once +#include "database/graph_db.hpp" #include "mvcc/record.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" +#include "mvcc/version_list.hpp" +#include "storage/typed_value_store.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>; +// forward declare Edge because there is a circular usage Edge <-> Vertex +class Edge; + +class Vertex : public mvcc::Record<Vertex> { public: - class Accessor; - - Vertex() = default; - Vertex(const VertexModel &data) : data(data) {} - Vertex(VertexModel &&data) : data(std::move(data)) {} - - Vertex(const 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() << ")"; - } + std::vector<mvcc::VersionList<Edge> *> out_; + std::vector<mvcc::VersionList<Edge> *> in_; + std::set<GraphDb::Label> labels_; + TypedValueStore properties_; }; diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp index 4d661b0cc..b6939c8d2 100644 --- a/include/storage/vertex_accessor.hpp +++ b/include/storage/vertex_accessor.hpp @@ -1,64 +1,34 @@ #pragma once -#include "storage/label/label_collection.hpp" +#include <set> + #include "storage/record_accessor.hpp" #include "storage/vertex.hpp" #include "utils/iterator/iterator.hpp" +#include "database/graph_db.hpp" -class Vertices; class EdgeAccessor; -// There exists circular dependecy with EdgeAccessor. -class VertexAccessor : public RecordAccessor<TypeGroupVertex, VertexAccessor> -{ - friend EdgeAccessor; - +class VertexAccessor : public RecordAccessor<Vertex, VertexAccessor> { public: - using RecordAccessor::RecordAccessor; + using RecordAccessor::RecordAccessor; - using record_t = Vertex; - using record_list_t = VertexRecord; + size_t out_degree() const; - // Removes self and all edges connected to it. - void remove() const; + size_t in_degree() const; - // Returns number of out edges. - size_t out_degree() const; + bool add_label(GraphDb::Label label); - // Returns number of in edges. - size_t in_degree() const; + size_t remove_label(GraphDb::Label label); - // Returns number of all edges. - size_t degree() const; + bool has_label(GraphDb::Label label) const; - // True if vertex isn't connected to any other vertex. - bool isolated() const; + const std::set<GraphDb::Label>& labels() const; - // False if it already has the label. - bool add_label(const Label &label); + // TODO add in/out functions that return (collection|iterator) over EdgeAccessor - // False if it doesn't have the label. - bool remove_label(const Label &label); + // returns if remove was possible due to connections + bool remove() const; - // Checks if it has the label. - bool has_label(const Label &label) const; - - // Returns container with all labels. - const std::vector<label_ref_t> &labels() const; - - auto out() const; - - auto in() const; - - // 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) - return; - - this->record->stream_repr(stream); - } + void detach_remove() const; }; diff --git a/include/storage/vertex_record.hpp b/include/storage/vertex_record.hpp deleted file mode 100644 index 72051795b..000000000 --- a/include/storage/vertex_record.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "mvcc/version_list.hpp" -#include "storage/vertex.hpp" - -class VertexRecord : public mvcc::VersionList<Vertex> -{ -public: - VertexRecord(Id id) : VersionList(id) {} - VertexRecord(const VersionList &) = delete; - VertexRecord(VersionList &&other) : VersionList(std::move(other)) {} -}; diff --git a/include/storage/vertices.hpp b/include/storage/vertices.hpp deleted file mode 100644 index 5ca2a7289..000000000 --- a/include/storage/vertices.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include <string> - -#include "data_structures/concurrent/concurrent_map.hpp" -#include "utils/counters/atomic_counter.hpp" -#include "utils/option.hpp" - -#include "storage/model/properties/property_family.hpp" -#include "storage/vertex_record.hpp" - -class DbTransaction; -class VertexAccessor; - -using VertexPropertyFamily = PropertyFamily<TypeGroupVertex>; -template <class K> -using VertexIndexBase = IndexBase<TypeGroupVertex, K>; - -class Vertices -{ -public: - using vertices_t = ConcurrentMap<uint64_t, VertexRecord>; - using prop_familys_t = - ConcurrentMap<std::string, std::unique_ptr<VertexPropertyFamily>>; - - vertices_t::Accessor access(); - - Option<const VertexAccessor> find(DbTransaction &t, const Id &id); - - // Creates new Vertex and returns filled VertexAccessor. - VertexAccessor insert(DbTransaction &t); - - // TODO: how can I know how many elements exist - // without iterating through all of them? MVCC? - - VertexPropertyFamily & - property_family_find_or_create(const std::string &name); - - prop_familys_t::Accessor property_family_access(); - -private: - // TODO: Because families wont be removed this could be done with more - // efficent - // data structure. - prop_familys_t prop_familys; - - // NOTE: this must be before prop_familys field to be destroyed before them. - // Because there are property_family references in vertices. - vertices_t vertices; - - AtomicCounter<uint64_t> counter; -}; diff --git a/include/utils/pass_key.hpp b/include/utils/pass_key.hpp new file mode 100644 index 000000000..b82d6b203 --- /dev/null +++ b/include/utils/pass_key.hpp @@ -0,0 +1,22 @@ +// +// Copyright 2017 Memgraph +// Created by Marko Budiselic +// +// SOURCES: +// http://arne-mertz.de/2016/10/passkey-idiom/ +// http://stackoverflow.com/questions/3217390/clean-c-granular-friend-equivalent-answer-attorney-client-idiom + + +#pragma once + +template<typename T> +class PassKey { + friend T; + +private: + // default constructor has to be manually defined otherwise = default + // would allow aggregate initialization to bypass default constructor + // both, default and copy constructors have to be user-defined + // otherwise are public by default + PassKey() {} +}; diff --git a/poc/add_double.cpp b/poc/add_double.cpp index 5c0dd003b..57cd3062e 100644 --- a/poc/add_double.cpp +++ b/poc/add_double.cpp @@ -1,7 +1,7 @@ #include <cstring> #include <ctime> -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "import/csv_import.hpp" #include "logging/default.hpp" #include "logging/streams/stdout.hpp" diff --git a/poc/astar.cpp b/poc/astar.cpp index 477b9a00d..9c93e8a69 100644 --- a/poc/astar.cpp +++ b/poc/astar.cpp @@ -11,7 +11,7 @@ #include "communication/bolt/v1/serialization/bolt_serializer.hpp" #include "data_structures/map/rh_hashmap.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.cpp" #include "database/db_accessor.hpp" #include "import/csv_import.hpp" diff --git a/poc/astar_query.cpp b/poc/astar_query.cpp index 925848a95..93714479b 100644 --- a/poc/astar_query.cpp +++ b/poc/astar_query.cpp @@ -11,7 +11,7 @@ #include "communication/bolt/v1/serialization/bolt_serializer.hpp" #include "data_structures/map/rh_hashmap.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.cpp" #include "database/db_accessor.hpp" #include "import/csv_import.hpp" diff --git a/poc/csv_import.cpp b/poc/csv_import.cpp index b40f6a7a3..8584f9980 100644 --- a/poc/csv_import.cpp +++ b/poc/csv_import.cpp @@ -1,4 +1,4 @@ -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "import/csv_import.hpp" #include "logging/default.hpp" #include "logging/streams/stdout.hpp" diff --git a/poc/profile.cpp b/poc/profile.cpp index 11bc4f447..19d7cf9d4 100644 --- a/poc/profile.cpp +++ b/poc/profile.cpp @@ -4,7 +4,7 @@ #include <unistd.h> #include <unordered_map> -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.hpp" #include "communication/bolt/v1/serialization/bolt_serializer.hpp" #include "import/csv_import.hpp" diff --git a/poc/size_aligment.cpp b/poc/size_aligment.cpp index eee45fc23..d3a8304ae 100644 --- a/poc/size_aligment.cpp +++ b/poc/size_aligment.cpp @@ -1,4 +1,4 @@ -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.hpp" #include <chrono> diff --git a/src/database/db.cpp b/src/database/db.cpp deleted file mode 100644 index 16086a23e..000000000 --- a/src/database/db.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "database/db.hpp" - -#include "snapshot/snapshoter.hpp" -#include "storage/indexes/indexes.hpp" -#include "storage/model/properties/property_family.hpp" - -Db::Db(bool import_snapshot) : Db("default", import_snapshot) {} - -Db::Db(const std::string &name, bool import_snapshot) - : Db(name.c_str(), import_snapshot) -{ -} - -Db::Db(const char *name, bool import_snapshot) : name_(name) -{ - if (import_snapshot) snap_engine.import(); -} - -Indexes Db::indexes() { return Indexes(*this); } - -std::string const &Db::name() const { return name_; } diff --git a/src/database/db_accessor.cpp b/src/database/db_accessor.cpp index 23b86e0a8..ca758714f 100644 --- a/src/database/db_accessor.cpp +++ b/src/database/db_accessor.cpp @@ -1,4 +1,4 @@ -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.hpp" DbAccessor::DbAccessor(Db &db) diff --git a/src/database/db_transaction.cpp b/src/database/db_transaction.cpp index 9b1104e03..0099395f7 100644 --- a/src/database/db_transaction.cpp +++ b/src/database/db_transaction.cpp @@ -1,6 +1,6 @@ #include "database/db_transaction.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "serialization/serialization.hpp" #include "storage/edge.hpp" #include "storage/edge_type/edge_type.hpp" diff --git a/src/database/graph_db.cpp b/src/database/graph_db.cpp new file mode 100644 index 000000000..0e5ef74f6 --- /dev/null +++ b/src/database/graph_db.cpp @@ -0,0 +1,77 @@ + +#include <storage/edge.hpp> +#include "database/creation_exception.hpp" +#include "database/graph_db.hpp" +#include "snapshot/snapshoter.hpp" + +#include "storage/vertex.hpp" +#include "storage/vertex_accessor.hpp" +#include "storage/edge.hpp" +#include "storage/edge_accessor.hpp" + +GraphDb::GraphDb(bool import_snapshot) : GraphDb("default", import_snapshot) {} + +GraphDb::GraphDb(const std::string &name, bool import_snapshot) + : GraphDb(name.c_str(), import_snapshot) { +} + +//GraphDb::GraphDb(const char *name, bool import_snapshot) : name_(name) { +// if (import_snapshot) snap_engine.import(); +//} + +VertexAccessor GraphDb::insert_vertex(DbTransaction &db_trans) { + auto vertex_vlist = new mvcc::VersionList<Vertex>(); + vertex_vlist->insert(db_trans.trans); + + // TODO make this configurable + for (int i = 0; i < 5; ++i) { + bool success = vertices_.access().insert(vertex_vlist).second; + if (success) + return VertexAccessor(vertex_vlist, db_trans); + // TODO sleep for some amount of time + } + + throw CreationException("Unable to create a Vertex after 5 attempts"); +} + +EdgeAccessor GraphDb::insert_edge( + DbTransaction& db_trans, VertexAccessor& from, + VertexAccessor& to, EdgeType type) { + + auto edge_vlist = new mvcc::VersionList<Edge>(); + Edge* edge = edge_vlist->insert(db_trans.trans); + + // set the given values of the new edge + edge->edge_type_ = type; + // connect the edge to vertices + edge->from_ = from.vlist(pass_key); + edge->to_ = to.vlist(pass_key); + // connect the vertices to edge + from.vlist(pass_key).out_.emplace(edge_vlist); + to.vlist(pass_key).in_.emplace(edge_vlist); + + // TODO make this configurable + for (int i = 0; i < 5; ++i) { + bool success = edges_.access().insert(edge_vlist).second; + if (success) + return EdgeAccessor(edge_vlist, db_trans); + // TODO sleep for some amount of time + } + + throw CreationException("Unable to create an Edge after 5 attempts"); + + EdgeRecord edge_record(next, from, to); + auto edge = edge_record.insert(t.trans); + + // insert the new vertex record into the vertex store + auto edges_accessor = edges.access(); + auto result = edges_accessor.insert(next, std::move(edge_record)); + + // create new vertex + auto inserted_edge_record = result.first; + + t.to_update_index<TypeGroupEdge>(&inserted_edge_record->second, edge); + + return EdgeAccessor(edge, &inserted_edge_record->second, t); +} +` diff --git a/src/memgraph_http.cpp b/src/memgraph_http.cpp index 92b8a2548..709e7e616 100644 --- a/src/memgraph_http.cpp +++ b/src/memgraph_http.cpp @@ -4,7 +4,7 @@ #include "debug/log.hpp" #include "utils/ioc/container.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "api/resources/include.hpp" #include "speedy/speedy.hpp" diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp index 3dbded0f7..868879e56 100644 --- a/src/storage/edge_accessor.cpp +++ b/src/storage/edge_accessor.cpp @@ -1,45 +1,32 @@ #include "storage/edge_accessor.hpp" +#include "storage/vertex_accessor.hpp" -#include <cassert> - -#include "utils/assert.hpp" -#include "storage/vertex_record.hpp" -#include "storage/edge_type/edge_type.hpp" - -void EdgeAccessor::remove() const -{ - RecordAccessor::remove(); - - auto from_va = from(); - auto from_va_is_full = from_va.fill(); - runtime_assert(from_va_is_full, "From Vertex Accessor is empty"); - - auto to_va = to(); - auto to_va_is_full = to_va.fill(); - permanent_assert(to_va_is_full, "To Vertex Accessor is empty"); - - from_va.update().record->data.out.remove(vlist); - to_va.update().record->data.in.remove(vlist); +void EdgeAccessor::set_edge_type(GraphDb::EdgeType edge_type) { + this->record_->edge_type_ = edge_type; } -void EdgeAccessor::edge_type(const EdgeType &edge_type) -{ - this->record->data.edge_type = &edge_type; +GraphDb::EdgeType EdgeAccessor::edge_type() const { + return this->record_->edge_type_; } -const EdgeType &EdgeAccessor::edge_type() const -{ - assert(this->record->data.edge_type != nullptr); - runtime_assert(this->record->data.edge_type != nullptr, "EdgeType is null"); - return *this->record->data.edge_type; +VertexAccessor EdgeAccessor::from() const { + return VertexAccessor(this->record_->from_, this->db_trans_); } -VertexAccessor EdgeAccessor::from() const -{ - return VertexAccessor(this->vlist->from(), this->db); +VertexAccessor EdgeAccessor::to() const { + return VertexAccessor(this->record_->to_, this->db_trans_); } -VertexAccessor EdgeAccessor::to() const -{ - return VertexAccessor(this->vlist->to(), this->db); +void EdgeAccessor::remove() const { + // remove this edge's reference from the "from" vertex + auto& vertex_from_out = from().update().record_->out_; + std::remove(vertex_from_out.begin(), vertex_from_out.end(), record_->from_); + + // remove this edge's reference from the "to" vertex + auto& vertex_to_in = to().update().record_->in_; + std::remove(vertex_to_in.begin(), vertex_to_in.end(), record_->to_); + + // remove this record from the database via MVCC + vlist_->remove(record_, db_trans_.trans); } + diff --git a/src/storage/edge_type/edge_type.cpp b/src/storage/edge_type/edge_type.cpp deleted file mode 100644 index ce8b56386..000000000 --- a/src/storage/edge_type/edge_type.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "storage/edge_type/edge_type.hpp" - -EdgeType::EdgeType(const std::string &id) : EdgeType(std::string(id)) {} -EdgeType::EdgeType(const char *id) : EdgeType(std::string(id)) {} -EdgeType::EdgeType(std::string &&id) - : id(id), index_v(std::make_unique<type_index_t>(IndexLocation{ - EdgeSide, Option<std::string>(), Option<std::string>(id)})) -{ -} - -bool operator<(const EdgeType &lhs, const EdgeType &rhs) -{ - return lhs.id < rhs.id; -} - -bool operator==(const EdgeType &lhs, const EdgeType &rhs) -{ - return lhs.id == rhs.id; -} - -std::ostream &operator<<(std::ostream &stream, const EdgeType &type) -{ - return stream << type.id; -} - -EdgeType::operator const std::string &() const { return id; } - -EdgeType::type_index_t &EdgeType::index() const { return *index_v.get(); } diff --git a/src/storage/edge_type/edge_type_store.cpp b/src/storage/edge_type/edge_type_store.cpp deleted file mode 100644 index 3062eee1d..000000000 --- a/src/storage/edge_type/edge_type_store.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "storage/edge_type/edge_type_store.hpp" - -EdgeTypeStore::store_t::Accessor EdgeTypeStore::access() -{ - return edge_types.access(); -} - -const EdgeType &EdgeTypeStore::find_or_create(const char *name) -{ - auto accessor = edge_types.access(); - auto it = accessor.find(CharStr(name)); - if (it == accessor.end()) { - auto l = std::make_unique<EdgeType>(name); - auto k = l->char_str(); - it = accessor.insert(k, std::move(l)).first; - } - return *(it->second); -} - -bool EdgeTypeStore::contains(const char *name) // const -{ - auto accessor = edge_types.access(); - return accessor.find(CharStr(name)) != accessor.end(); -} diff --git a/src/storage/edges.cpp b/src/storage/edges.cpp deleted file mode 100644 index 58f3d8376..000000000 --- a/src/storage/edges.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "storage/edges.hpp" - -#include "storage/edge_accessor.hpp" -#include "utils/iterator/iterator.hpp" - -Edges::store_t::Accessor Edges::access() { return edges.access(); } - -Option<const EdgeAccessor> Edges::find(DbTransaction &t, const Id &id) -{ - auto edges_accessor = edges.access(); - auto edges_iterator = edges_accessor.find(id); - - if (edges_iterator == edges_accessor.end()) - return make_option<const EdgeAccessor>(); - - return make_option_const(EdgeAccessor(&edges_iterator->second, t)); -} - -EdgeAccessor Edges::insert(DbTransaction &t, VertexRecord *from, - VertexRecord *to) -{ - // get next vertex id - auto next = counter.next(std::memory_order_acquire); - - // create new vertex record - EdgeRecord edge_record(next, from, to); - auto edge = edge_record.insert(t.trans); - - // insert the new vertex record into the vertex store - auto edges_accessor = edges.access(); - auto result = edges_accessor.insert(next, std::move(edge_record)); - - // create new vertex - auto inserted_edge_record = result.first; - - t.to_update_index<TypeGroupEdge>(&inserted_edge_record->second, edge); - - return EdgeAccessor(edge, &inserted_edge_record->second, t); -} - -Edges::prop_familys_t::Accessor Edges::property_family_access() -{ - return prop_familys.access(); -} - -EdgePropertyFamily & -Edges::property_family_find_or_create(const std::string &name) -{ - auto acc = prop_familys.access(); - auto it = acc.find(name); - if (it == acc.end()) { - EdgePropertyFamily *family = new EdgePropertyFamily(name); - auto res = acc.insert(name, family); - if (!res.second) { - delete family; - } - it = res.first; - } - return *(it->second); -} diff --git a/src/storage/indexes/impl/nonunique_unordered_index.cpp b/src/storage/indexes/impl/nonunique_unordered_index.cpp deleted file mode 100644 index b4652131a..000000000 --- a/src/storage/indexes/impl/nonunique_unordered_index.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "storage/indexes/impl/nonunique_unordered_index.hpp" - -#include "database/db_accessor.hpp" -#include "database/db_transaction.hpp" -#include "storage/edge_accessor.hpp" -#include "storage/edge_record.hpp" -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" -#include "storage/vertex_accessor.hpp" -#include "storage/vertex_record.hpp" -#include "utils/iterator/iterator.hpp" - -#include "storage/indexes/index_record.cpp" - -template <class T, class K> -NonUniqueUnorderedIndex<T, K>::NonUniqueUnorderedIndex(IndexLocation &&loc) - : IndexBase<T, K>(IndexDefinition{loc, IndexType{false, None}}, - "NonUniqueUnorderedIndex") -{ -} - -template <class T, class K> -NonUniqueUnorderedIndex<T, K>::NonUniqueUnorderedIndex(IndexLocation &&loc, - tx::Transaction const &t) - : IndexBase<T, K>(IndexDefinition{loc, IndexType{false, None}}, t, - "NonUniqueUnorderedIndex") -{ -} - -template <class T, class K> -bool NonUniqueUnorderedIndex<T, K>::insert(IndexRecord<T, K> &&value) -{ - list.begin().push(std::move(value)); - return true; -} - -template <class T, class K> -iter::Virtual<const typename T::accessor_t> -NonUniqueUnorderedIndex<T, K>::for_range(DbAccessor &t, Border<K> from, - Border<K> to) -{ - return iter::make_virtual( - for_range_exact(t, std::move(from), std::move(to))); -} - -template <class T, class K> -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_v is passed by reference because otherwise - // DbAccessor would be copied that means that t_v.db_transaction would - // also be copied and that wouldn't be good because - // db_transaction contains index_updates - t = &t_v - ]() mutable -> auto { - // NonUniqueUnorderedIndex is stupid so it must iterate through all - // index records to determine which are iniside borders. - while (it != end) { - const IndexRecord<T, K> &r = *it; - if (from < r.key && to > r.key && - r.is_valid(t->db_transaction.trans)) { - // record r is inside borders and is valid for current - // transaction. - const typename T::accessor_t acc = - r.access(t->db_transaction); - it++; - return make_option(std::move(acc)); - } - it++; - } - - return Option<const typename T::accessor_t>(); - }, - list.size()); -} - -template <class T, class K> -void NonUniqueUnorderedIndex<T, K>::clean(const Id &id) -{ - auto end = list.end(); - for (auto it = list.begin(); it != end; it++) { - if (it->to_clean(id)) { - it.remove(); - } - } -} - -template class NonUniqueUnorderedIndex<TypeGroupEdge, std::nullptr_t>; -template class NonUniqueUnorderedIndex<TypeGroupVertex, std::nullptr_t>; diff --git a/src/storage/indexes/impl/unique_ordered_index.cpp b/src/storage/indexes/impl/unique_ordered_index.cpp deleted file mode 100644 index 9b6481801..000000000 --- a/src/storage/indexes/impl/unique_ordered_index.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "storage/indexes/impl/unique_ordered_index.hpp" - -#include "database/db.hpp" - -#include "database/db_accessor.hpp" -#include "database/db_transaction.hpp" -#include "storage/edge_accessor.hpp" -#include "storage/edge_record.hpp" -#include "storage/edge_type/edge_type.hpp" -#include "storage/label/label.hpp" -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" -#include "storage/vertex_accessor.hpp" -#include "storage/vertex_record.hpp" -#include "utils/iterator/iterator.hpp" - -#include "storage/indexes/index_record.cpp" - -template <class T, class K> -UniqueOrderedIndex<T, K>::UniqueOrderedIndex(IndexLocation loc, Order order) - : IndexBase<T, K>(IndexDefinition{loc, IndexType{true, order}}, - "UniqueOrderedIndex") -{ -} - -template <class T, class K> -UniqueOrderedIndex<T, K>::UniqueOrderedIndex(IndexLocation loc, Order order, - tx::Transaction const &t) - : IndexBase<T, K>(IndexDefinition{loc, IndexType{true, order}}, - t, "UniqueOrderedIndex") -{ -} - -template <class T, class K> -bool UniqueOrderedIndex<T, K>::insert(IndexRecord<T, K> &&value) -{ - if (this->type().order == Descending) { - value.set_descending(); - } - return set.access().insert(std::move(value)).second; -} - -template <class T, class K> -iter::Virtual<const typename T::accessor_t> -UniqueOrderedIndex<T, K>::for_range(DbAccessor &t, Border<K> from, Border<K> to) -{ - return iter::make_virtual( - for_range_exact(t, std::move(from), std::move(to))); -} - -template <class T, class K> -auto UniqueOrderedIndex<T, K>::for_range_exact(DbAccessor &t_v, - Border<K> from_v, Border<K> to_v) -{ - auto acc = set.access(); - auto begin = acc.cbegin(); - auto end = to_v; - - // Sorted order must be checked - if (this->type().order == Ascending && from_v.key.is_present()) { - begin = acc.cfind_or_larger(from_v); - - } else if (this->type().order == Descending && to_v.key.is_present()) { - // Order is descending so whe have to start from the end border and - // iterate to the from border. - begin = acc.cfind_or_larger(to_v); - end = from_v; - - } else { - assert(this->type().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 { - // UniqueOrderedIndex is smart so he has to iterate only through - // records which are inside borders. He knows that he will start - // with items larger than from_v but he needs to check if it has - // reached end border. - while (b_end >= it->key) { - const IndexRecord<T, K> &r = *it; - if (r.is_valid(t->db_transaction.trans)) { - // record r is inside borders and is valid for current - // transaction. - const typename T::accessor_t acc = - r.access(t->db_transaction); - it++; - return make_option(std::move(acc)); - } - it++; - } - - return Option<const typename T::accessor_t>(); - }, - size); -} - -template <class T, class K> -void UniqueOrderedIndex<T, K>::clean(const Id &id) -{ - auto acc = set.access(); - for (auto ir : acc) { - if (ir.to_clean(id)) { - // TODO: Optimization, iterator with remove method. - acc.remove(ir); - } - } -} - -template class UniqueOrderedIndex<TypeGroupEdge, std::nullptr_t>; -template class UniqueOrderedIndex<TypeGroupVertex, std::nullptr_t>; diff --git a/src/storage/indexes/index_base.cpp b/src/storage/indexes/index_base.cpp deleted file mode 100644 index 226befd22..000000000 --- a/src/storage/indexes/index_base.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "storage/indexes/index_base.hpp" - -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" -#include "transactions/transaction.hpp" - -template <class TG, class K> -IndexBase<TG, K>::IndexBase(IndexDefinition &&it, std::string&& logger_name) - : Loggable(std::forward<std::string>(logger_name)), it(it), created(Id(0)), active(true) -{ -} - -template <class TG, class K> -IndexBase<TG, K>::IndexBase(IndexDefinition &&it, const tx::Transaction &t, std::string&& logger_name) - : Loggable(std::forward<std::string>(logger_name)), it(it), created(t.id) -{ -} - -template <class TG, class K> -void IndexBase<TG, K>::activate() -{ - assert(!can_read()); - active.store(true); -} - -template <class TG, class K> -bool IndexBase<TG, K>::can_read() -{ - return active.load(std::memory_order_acquire); -} - -template <class TG, class K> -bool IndexBase<TG, K>::is_obliged_to_insert(const tx::Transaction &t) -{ - return t.id >= created; -} - -template class IndexBase<TypeGroupEdge, std::nullptr_t>; -template class IndexBase<TypeGroupVertex, std::nullptr_t>; diff --git a/src/storage/indexes/index_holder.cpp b/src/storage/indexes/index_holder.cpp deleted file mode 100644 index aa8a74fd3..000000000 --- a/src/storage/indexes/index_holder.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "storage/indexes/index_holder.hpp" - -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" - -template <class TG, class K> -IndexBase<TG, K> *npr = (IndexBase<TG, K> *)nullptr; - -template <class TG, class K> -bool IndexHolder<TG, K>::set_index(std::unique_ptr<IndexBase<TG, K>> inx) -{ - if (index.compare_exchange_strong(npr<TG, K>, inx.get())) { - inx.release(); - return true; - - } else { - return false; - } -} - -template <class TG, class K> -OptionPtr<IndexBase<TG, K>> IndexHolder<TG, K>::get_read() const -{ - auto loaded = index.load(std::memory_order_acquire); - if (loaded == nullptr || !loaded->can_read()) { - return OptionPtr<IndexBase<TG, K>>(); - - } else { - return make_option_ptr(loaded); - } -} - -template <class TG, class K> -OptionPtr<IndexBase<TG, K>> -IndexHolder<TG, K>::get_write(const tx::Transaction &t) const -{ - auto loaded = index.load(std::memory_order_acquire); - if (loaded == nullptr || !loaded->is_obliged_to_insert(t)) { - return OptionPtr<IndexBase<TG, K>>(); - - } else { - return make_option_ptr(loaded); - } -} - -template <class TG, class K> -Option<std::unique_ptr<IndexBase<TG, K>>> -IndexHolder<TG, K>::remove_index(IndexBase<TG, K> *expected) -{ - if (index.compare_exchange_strong(expected, nullptr)) { - return make_option(std::unique_ptr<IndexBase<TG, K>>(expected)); - - } else { - return make_option(std::unique_ptr<IndexBase<TG, K>>()); - } -} - -template <class TG, class K> -Option<std::unique_ptr<IndexBase<TG, K>>> IndexHolder<TG, K>::remove_index() -{ - auto removed = index.exchange(nullptr); - if (removed == nullptr) { - return make_option<std::unique_ptr<IndexBase<TG, K>>>(); - - } else { - return make_option(std::unique_ptr<IndexBase<TG, K>>(removed)); - } -} - -template class IndexHolder<TypeGroupEdge, std::nullptr_t>; -template class IndexHolder<TypeGroupVertex, std::nullptr_t>; diff --git a/src/storage/indexes/index_record.cpp b/src/storage/indexes/index_record.cpp deleted file mode 100644 index 9632b5349..000000000 --- a/src/storage/indexes/index_record.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "storage/indexes/index_record.hpp" - -#include "storage/type_group_edge.hpp" -#include "storage/type_group_vertex.hpp" -#include "transactions/transaction.hpp" - -template <class TG, class K> -IndexRecord<TG, K>::IndexRecord(K key, typename TG::record_t *record, - typename TG::vlist_t *vlist) - : key(std::move(key)), record(record), vlist(vlist) -{ - assert(record != nullptr); - assert(vlist != nullptr); -} - -template <class TG, class K> -void IndexRecord<TG, K>::set_descending() -{ - descending = true; -} - -template <class TG, class K> -bool IndexRecord<TG, K>::empty() const -{ - return record == nullptr; -} - -template <class TG, class K> -bool IndexRecord<TG, K>::is_valid(tx::Transaction &t) const -{ - assert(!empty()); - // TODO: this has to be tested extensively - // before here was only (record == newest_record) - // but it doesn't work if single transaction updates something from - // this index and then tries to access to the same element again through - // the same index - auto newest_record = vlist->find(t); - if (!newest_record) - return false; - return (record == newest_record) || (newest_record->tx.cre() == t.id); -} - -template <class TG, class K> -bool IndexRecord<TG, K>::to_clean(const Id &oldest_active) const -{ - assert(!empty()); - return record->is_deleted_before(oldest_active); -} - -template <class TG, class K> -const auto IndexRecord<TG, K>::access(DbTransaction &db) const -{ - return typename TG::accessor_t(record, vlist, db); -} - -#include "storage/edge_accessor.hpp" -#include "storage/edge_record.hpp" -#include "storage/vertex_accessor.hpp" -#include "storage/vertex_record.hpp" - -template class IndexRecord<TypeGroupVertex, std::nullptr_t>; -template class IndexRecord<TypeGroupEdge, std::nullptr_t>; diff --git a/src/storage/indexes/index_update.cpp b/src/storage/indexes/index_update.cpp deleted file mode 100644 index ca7fe1028..000000000 --- a/src/storage/indexes/index_update.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "storage/indexes/index_update.hpp" - -template <> -IndexUpdate make_index_update(EdgeRecord *vlist, Edge *record) -{ - return IndexUpdate{IndexUpdate::EDGE, .e = IndexUpdateEdge{vlist, record}}; -} - -template <> -IndexUpdate make_index_update(VertexRecord *vlist, Vertex *record) -{ - return IndexUpdate{IndexUpdate::VERTEX, - .v = IndexUpdateVertex{vlist, record}}; -} diff --git a/src/storage/indexes/indexes.cpp b/src/storage/indexes/indexes.cpp deleted file mode 100644 index 64a0ef7f6..000000000 --- a/src/storage/indexes/indexes.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "storage/indexes/indexes.hpp" - -#include "database/db_accessor.hpp" - -bool Indexes::add_index(IndexDefinition id) -{ - auto logger = logging::log->logger("Add index"); - logger.info("Starting"); - - // Closure which needs to be runned to finish creating index. - std::function<bool(DbTransaction &)> finish = [](auto &t) { return false; }; - - // Creates transaction and during it's creation adds index into it's - // place. Also creates finish closure which will add necessary elements - // into index. - DbTransaction t(db, db.tx_engine.begin([&](auto &t) mutable { - size_t code = id.loc.location_code(); - - switch (code) { - - // Index over nothing - case 0: // Illegal location - break; - - // Index over property - case 1: { - switch (id.loc.side) { - case EdgeSide: { - auto &holder = db.graph.edges - .property_family_find_or_create( - id.loc.property_name.get()) - .index; - if (holder.set_index( - create_index<TypeGroupEdge, std::nullptr_t>(id, t))) { - // Set closure which will fill index. - finish = [&](auto &t) mutable { - DbAccessor acc(t.db, t.trans); - auto &key = acc.edge_property_family_get( - id.loc.property_name.get()); - - return fill_index( - t, holder, - acc.edge_access().fill().has_property(key).map( - [&](auto ra) { - return std::make_pair(std::move(ra), - std::nullptr_t()); - })); - }; - } - break; - } - case VertexSide: { // TODO: Duplicate code as above, only difference - // is vertices/vertex - auto &holder = db.graph.vertices - .property_family_find_or_create( - id.loc.property_name.get()) - .index; - if (holder.set_index( - create_index<TypeGroupVertex, std::nullptr_t>(id, t))) { - // Set closure which will fill index. - finish = [&](auto &t) mutable { - DbAccessor acc(t.db, t.trans); - auto &key = acc.vertex_property_family_get( - id.loc.property_name.get()); - - return fill_index( - t, holder, - acc.vertex_access().fill().has_property(key).map( - [&](auto ra) { - return std::make_pair(std::move(ra), - std::nullptr_t()); - })); - }; - } - break; - } - default: - logger.error("Unkown side: " + std::to_string(id.loc.side)); - }; - break; - } - - // Index over label - case 2: { // Always added - finish = [](auto &t) { return true; }; - return; - } - - // Index over property and label - case 3: { // Not yet implemented - logger.error("Remove of index over label and " - "property isn't yet implemented"); - break; - } - - // Index over edge_type - case 4: { // Always added - finish = [](auto &t) { return true; }; - break; - } - - // Index over property and edge_type - case 5: { // Not yet implemented - logger.error("Remove of index over edge_type and " - "property isn't yet implemented"); - break; - } - - // Index over edge_type and label - case 6: { // Not yet implemented - logger.error("Remove of index over edge_type and " - "label isn't yet implemented"); - break; - } - - // Index over property, edge_type and label - case 7: { // Not yet implemented - logger.error("Remove of index over label, edge_type " - "and property isn't yet implemented"); - break; - } - - default: - logger.error("Unkown index location code: " + std::to_string(code)); - } - })); - - if (finish(t)) { - t.trans.commit(); - - logger.info("Success"); - return true; - - } else { - t.trans.abort(); - - logger.info("Failed"); - return false; - } -} diff --git a/src/storage/label/label.cpp b/src/storage/label/label.cpp deleted file mode 100644 index e4e70c0d7..000000000 --- a/src/storage/label/label.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// #include "storage/indexes/impl/nonunique_unordered_index.hpp" -#include "storage/label/label.hpp" - -Label::Label(const char *name) - : name(std::string(name)), - index_v(std::make_unique<label_index_t>( - IndexLocation{VertexSide, Option<std::string>(), - Option<std::string>(std::string(name))})) -{ -} - -bool operator<(const Label &lhs, const Label &rhs) -{ - return lhs.name < rhs.name; -} - -bool operator==(const Label &lhs, const Label &rhs) -{ - return lhs.name == rhs.name; -} - -bool operator<(const CharStr &lhs, const Label &rhs) -{ - return lhs < rhs.char_str(); -} - -bool operator==(const CharStr &lhs, const Label &rhs) -{ - return lhs == rhs.char_str(); -} - -std::ostream &operator<<(std::ostream &stream, const Label &label) -{ - return stream << label.name; -} - -Label::operator const std::string &() const { return name; } - -Label::label_index_t &Label::index() const { return *index_v.get(); } diff --git a/src/storage/label/label_collection.cpp b/src/storage/label/label_collection.cpp deleted file mode 100644 index 48f0890c8..000000000 --- a/src/storage/label/label_collection.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "storage/label/label_collection.hpp" - -#include "storage/label/label.hpp" - -bool LabelCollection::add(const Label &label) -{ - if (has(label)) { - return false; - } else { - labels_.push_back(label_ref_t(label)); - return true; - } -} - -bool LabelCollection::has(const Label &label) const -{ - for (auto l : labels_) { - if (l == label) { - return true; - } - } - return false; -} - -size_t LabelCollection::count() const { return labels_.size(); } - -bool LabelCollection::remove(const Label &label) -{ - auto end = labels_.end(); - for (auto it = labels_.begin(); it != end; it++) { - if (*it == label) { - labels_.erase(it); - return true; - } - } - - return false; -} - -void LabelCollection::clear() { labels_.clear(); } - -const std::vector<label_ref_t> &LabelCollection::operator()() const -{ - return labels_; -} diff --git a/src/storage/label/label_store.cpp b/src/storage/label/label_store.cpp deleted file mode 100644 index db9fdad7e..000000000 --- a/src/storage/label/label_store.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "storage/label/label_store.hpp" - -LabelStore::store_t::Accessor LabelStore::access() { return labels.access(); } - -const Label &LabelStore::find_or_create(const char *name) -{ - auto accessor = labels.access(); - auto it = accessor.find(CharStr(name)); - if (it == accessor.end()) { - auto l = std::make_unique<Label>(name); - auto k = l->char_str(); - it = accessor.insert(k, std::move(l)).first; - } - return *(it->second); -} - -bool LabelStore::contains(const char *name) // const -{ - auto accessor = labels.access(); - return accessor.find(CharStr(name)) != accessor.end(); -} diff --git a/src/storage/label/labels_writer.cpp b/src/storage/label/labels_writer.cpp deleted file mode 100644 index 7eb5342c8..000000000 --- a/src/storage/label/labels_writer.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "storage/label/labels_writer.hpp" - -#include "storage/label/label.hpp" -#include "utils/string_buffer.hpp" - -template <typename Buffer> -void LabelsWriter<Buffer>::handle(const Label& label) -{ - buffer_ << ':' << label.str(); -} - -// NOTE! template instantiations -template class LabelsWriter<utils::StringBuffer>; diff --git a/src/storage/model/json/all.hpp b/src/storage/model/json/all.hpp deleted file mode 100644 index 17e46e942..000000000 --- a/src/storage/model/json/all.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "array.hpp" -#include "bool.hpp" -#include "integral.hpp" -#include "json.hpp" -#include "null.hpp" -#include "object.hpp" -#include "primitive.hpp" -#include "real.hpp" -#include "string.hpp" diff --git a/src/storage/model/json/array.hpp b/src/storage/model/json/array.hpp deleted file mode 100644 index 23eff2ec5..000000000 --- a/src/storage/model/json/array.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include <cassert> -#include <memory> -#include <vector> - -#include "utilities/string/intercalate.hpp" - -#include "json.hpp" - -namespace json -{ - -class Array final : public Json -{ -public: - Array() {} - - template <typename It> - Array(It first, It last) - : elements(first, last) {} - - Array(std::initializer_list<spJson> elements) - : elements(elements) {} - - virtual bool is_array() const; - - size_t size() const; - - Array& push(const std::shared_ptr<Json>& element); - - const spJson& operator[](size_t i) const; - spJson operator[](size_t i); - - virtual operator std::string() const; - -private: - std::vector<spJson> elements; -}; - -bool Array::is_array() const -{ - return true; -} - -size_t Array::size() const -{ - return elements.size(); -} - -Array& Array::push(const spJson& element) -{ - assert(element); - - elements.push_back(element); - return *this; -} - -const spJson& Array::operator[](size_t i) const -{ - return elements[i]; -} - -spJson Array::operator[](size_t i) -{ - return elements[i]; -} - -Array::operator std::string() const -{ - std::vector<std::string> xs; - - std::transform(elements.begin(), elements.end(), std::back_inserter(xs), - [](const spJson& element) { - return static_cast<std::string>(*element); - }); - - return "[" + utils::intercalate(xs.begin(), xs.end(), ",") + "]"; -} - -} diff --git a/src/storage/model/json/bool.hpp b/src/storage/model/json/bool.hpp deleted file mode 100644 index 683541bea..000000000 --- a/src/storage/model/json/bool.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "primitive.hpp" - -namespace json { - -class Bool final : public Primitive<bool> -{ -public: - Bool() {} - - Bool(bool value) - : Primitive<bool>(value) {} - - virtual bool is_boolean() const; - - virtual operator std::string() const; -}; - -bool Bool::is_boolean() const -{ - return true; -} - -Bool::operator std::string() const -{ - return value == true ? "true" : "false"; -} - -} diff --git a/src/storage/model/json/integral.hpp b/src/storage/model/json/integral.hpp deleted file mode 100644 index 905ff1038..000000000 --- a/src/storage/model/json/integral.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "primitive.hpp" - -namespace json { - -class Integral final : public Primitive<int64_t> -{ -public: - Integral() {} - - Integral(int64_t value) - : Primitive<int64_t>(value) {} - - virtual bool is_integral() const; - - virtual operator std::string() const; -}; - -bool Integral::is_integral() const -{ - return true; -} - -Integral::operator std::string() const -{ - return std::to_string(value); -} - -} diff --git a/src/storage/model/json/json.hpp b/src/storage/model/json/json.hpp deleted file mode 100644 index 29396c16b..000000000 --- a/src/storage/model/json/json.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include <initializer_list> -#include <string> -#include <memory> - -namespace json { - -class Json; - -typedef std::shared_ptr<Json> spJson; - -class Json -{ -public: - Json() {} - virtual ~Json() {} - - virtual bool is_object() const { return false; } - virtual bool is_array() const { return false; } - virtual bool is_real() const { return false; } - virtual bool is_integral() const { return false; } - virtual bool is_boolean() const { return false; } - virtual bool is_null() const { return false; } - - template <typename T> T& as(); - template <typename T> const T& as() const; - - virtual operator std::string() const = 0; -}; - -template <typename T> -T& Json::as() -{ - return *dynamic_cast<T*>(this); -} - -template <typename T> -const T& Json::as() const -{ - return *dynamic_cast<T*>(this); -} - -} diff --git a/src/storage/model/json/null.hpp b/src/storage/model/json/null.hpp deleted file mode 100644 index aab486603..000000000 --- a/src/storage/model/json/null.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "json.hpp" - -namespace json { - -class Null final : public Json -{ -public: - Null() {} - - virtual bool is_null() const; - - virtual operator std::string() const; -}; - -bool Null::is_null() const -{ - return true; -} - -Null::operator std::string() const -{ - return "null"; -} - -} diff --git a/src/storage/model/json/object.hpp b/src/storage/model/json/object.hpp deleted file mode 100644 index 73260d3df..000000000 --- a/src/storage/model/json/object.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include <iostream> - -#include <functional> -#include <sstream> -#include <cassert> -#include <vector> -#include <map> - -#include "utilities/string/intercalate.hpp" - -#include "json.hpp" - -namespace json { - -typedef std::pair<const std::string, spJson> const_kv_pair_t; -typedef std::pair<std::string, spJson> kv_pair_t; - -class Object; - -typedef std::shared_ptr<Object> spObject; - -class Object : public Json -{ -public: - Object() {} - - Object(std::initializer_list<const_kv_pair_t> elements) - : props(elements) {} - - virtual bool is_object() const; - - const spJson& at(const std::string& key) const; - spJson at(const std::string& key); - - const spJson& operator[](const std::string& key) const; - spJson operator[](const std::string& key); - - Object& put(const std::string& key, spJson value); - - Object& operator<<(const kv_pair_t& kv_pair); - - virtual operator std::string() const; - -protected: - std::map<std::string, spJson> props; -}; - -bool Object::is_object() const -{ - return true; -} - -const spJson& Object::at(const std::string& key) const -{ - return props.at(key); -} - -spJson Object::at(const std::string& key) -{ - return props.at(key); -} - -const spJson& Object::operator[](const std::string& key) const -{ - return this->at(key); -} - -spJson Object::operator[](const std::string& key) -{ - return this->at(key); -} - -Object& Object::put(const std::string& key, spJson value) -{ - assert(value); - - props[key] = value; - return *this; -} - -Object& Object::operator<<(const kv_pair_t& kv_pair) -{ - return this->put(std::get<0>(kv_pair), std::get<1>(kv_pair)); -} - -Object::operator std::string() const -{ - if(props.empty()) - return "{}"; - - std::vector<std::string> xs; - - std::transform(props.begin(), props.end(), std::back_inserter(xs), - [](const kv_pair_t& kvp) { - return "\"" + kvp.first + "\":" + static_cast<std::string>(*kvp.second); - }); - - return "{" + utils::intercalate(xs.begin(), xs.end(), ",") + "}"; -} - -} diff --git a/src/storage/model/json/primitive.hpp b/src/storage/model/json/primitive.hpp deleted file mode 100644 index d9cc5b67c..000000000 --- a/src/storage/model/json/primitive.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "json.hpp" - -namespace json { - -template <class T> -class Primitive : public Json -{ -public: - Primitive() {} - - Primitive(const T& value) - : value(value) {} - - T get() const { return value; } - void set(T value) { this->value = value; } - - operator T() const { return this->get(); } - -protected: - T value; -}; - - -} diff --git a/src/storage/model/json/real.hpp b/src/storage/model/json/real.hpp deleted file mode 100644 index 83a05bf95..000000000 --- a/src/storage/model/json/real.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "primitive.hpp" - -namespace json { - -class Real final : public Primitive<float> -{ -public: - Real() {} - - Real(float value) - : Primitive<float>(value) {} - - virtual bool is_real() const; - - virtual operator std::string() const; -}; - -bool Real::is_real() const -{ - return true; -} - -Real::operator std::string() const -{ - return std::to_string(value); -} - -} diff --git a/src/storage/model/json/string.hpp b/src/storage/model/json/string.hpp deleted file mode 100644 index 0922088ea..000000000 --- a/src/storage/model/json/string.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "primitive.hpp" - -namespace json -{ - -class String final : public Primitive<std::string> -{ -public: - String() {} - - String(const std::string& value) - : Primitive<std::string>(value) {} - - virtual bool is_string() const; - - virtual operator std::string() const; -}; - -bool String::is_string() const -{ - return true; -} - -String::operator std::string() const -{ - return "\"" + value + "\""; -} - -} diff --git a/src/storage/record_accessor.cpp b/src/storage/record_accessor.cpp deleted file mode 100644 index 3f62e8ad4..000000000 --- a/src/storage/record_accessor.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "storage/record_accessor.hpp" - -#include "storage/edge_accessor.hpp" -#include "storage/edge_record.hpp" -#include "storage/vertex_accessor.hpp" -#include "storage/vertex_record.hpp" - -// template <class T, class Derived> -// template <class V> -// auto RecordAccessor<T, Derived>::at(type_key_t<T, V> &key) const -// { -// return properties().template at<V>(key); -// } - -template <class T, class Derived> -void RecordAccessor<T, Derived>::remove() const -{ - assert(!empty()); - - vlist->remove(record, db.trans); -} - -template class RecordAccessor<TypeGroupEdge, EdgeAccessor>; -template class RecordAccessor<TypeGroupVertex, VertexAccessor>; diff --git a/src/storage/model/typed_value.cpp b/src/storage/typed_value.cpp similarity index 99% rename from src/storage/model/typed_value.cpp rename to src/storage/typed_value.cpp index eeb4a39fe..43be7e04e 100644 --- a/src/storage/model/typed_value.cpp +++ b/src/storage/typed_value.cpp @@ -3,7 +3,7 @@ #include <cmath> #include <fmt/format.h> -#include "storage/model/typed_value.hpp" +#include "storage/typed_value.hpp" #include "utils/assert.hpp" // Value extraction template instantiations diff --git a/src/storage/model/typed_value_store.cpp b/src/storage/typed_value_store.cpp similarity index 97% rename from src/storage/model/typed_value_store.cpp rename to src/storage/typed_value_store.cpp index 145c92f68..e3daa0283 100644 --- a/src/storage/model/typed_value_store.cpp +++ b/src/storage/typed_value_store.cpp @@ -1,6 +1,6 @@ #include <algorithm> -#include "storage/model/typed_value_store.hpp" +#include "storage/typed_value_store.hpp" const TypedValue& TypedValueStore::at(const TKey &key) const { for (const auto& kv : props_) diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp index 016bca2b4..db0817ab7 100644 --- a/src/storage/vertex_accessor.cpp +++ b/src/storage/vertex_accessor.cpp @@ -1,81 +1,50 @@ +#include "storage/edge_accessor.hpp" #include "storage/vertex_accessor.hpp" -#include "database/db.hpp" -#include "storage/vertex_record.hpp" -#include "storage/vertices.hpp" -#include "utils/iterator/iterator.hpp" - -bool VertexAccessor::isolated() const -{ - return out_degree() == 0 && in_degree() == 0; +size_t VertexAccessor::out_degree() const { + return this->record_->out_.size(); } -size_t VertexAccessor::out_degree() const -{ - return this->record->data.out.degree(); +size_t VertexAccessor::in_degree() const { + return this->record_->in_.size(); } -size_t VertexAccessor::in_degree() const -{ - return this->record->data.in.degree(); +bool VertexAccessor::add_label(GraphDb::Label label) { + return this->record_->labels_.emplace(label).second; } -size_t VertexAccessor::degree() const { return in_degree() + out_degree(); } - -bool VertexAccessor::add_label(const Label &label) -{ - // update vertex - return this->record->data.labels.add(label); +size_t VertexAccessor::remove_label(GraphDb::Label label) { + return this->record_->labels_.erase(label); } -bool VertexAccessor::remove_label(const Label &label) -{ - // update vertex - return this->record->data.labels.remove(label); +bool VertexAccessor::has_label(GraphDb::Label label) const { + auto &label_set = this->record_->labels_; + return label_set.find(label) != label_set.end(); } -bool VertexAccessor::has_label(const Label &label) const -{ - return this->record->data.labels.has(label); +const std::set<GraphDb::Label> &VertexAccessor::labels() const { + return this->record_->labels_; } -const std::vector<label_ref_t> &VertexAccessor::labels() const -{ - return this->record->data.labels(); +bool VertexAccessor::remove() const { + // TODO consider if this works well with MVCC + if (out_degree() > 0 || in_degree() > 0) + return false; + + vlist_->remove(record_, db_trans_.trans); + return true; } -bool VertexAccessor::in_contains(VertexAccessor const &other) const -{ - return record->data.in.contains(other.vlist); +void VertexAccessor::detach_remove() const { + // removing edges via accessors is both safe + // and it should remove all the pointers in the relevant + // vertices (including this one) + for (auto edge_vlist : record_->out_) + EdgeAccessor(edge_vlist, db_trans_).remove(); + + for (auto edge_vlist : record_->in_) + EdgeAccessor(edge_vlist, db_trans_).remove(); + + vlist_->remove(record_, db_trans_.trans); } -void VertexAccessor::remove() const -{ - RecordAccessor::remove(); - - // Detach all out edges. - for (auto evr : record->data.out) { - auto ea = EdgeAccessor(evr, db); - - // Delete edge - ea.vlist->remove(db.trans); - - // Remove edge from it's to vertex. - auto to_v = ea.to(); - to_v.fill(); - to_v.update().record->data.in.remove(ea.vlist); - } - - // Detach all in edges. - for (auto evr : record->data.in) { - auto ea = EdgeAccessor(evr, db); - - // Delete edge - ea.vlist->remove(db.trans); - - // Remove edge from it's from vertex. - auto from_v = ea.from(); - from_v.fill(); - from_v.update().record->data.out.remove(ea.vlist); - } -} diff --git a/src/storage/vertices.cpp b/src/storage/vertices.cpp deleted file mode 100644 index 18ab6de2d..000000000 --- a/src/storage/vertices.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "storage/vertices.hpp" - -#include "storage/vertex_accessor.hpp" -#include "utils/iterator/iterator.hpp" - -Vertices::vertices_t::Accessor Vertices::access() { return vertices.access(); } - -Option<const VertexAccessor> Vertices::find(DbTransaction &t, const Id &id) -{ - auto vertices_accessor = vertices.access(); - auto vertices_iterator = vertices_accessor.find(id); - - if (vertices_iterator == vertices_accessor.end()) - return make_option<const VertexAccessor>(); - - return make_option_const(VertexAccessor(&vertices_iterator->second, t)); -} - -VertexAccessor Vertices::insert(DbTransaction &t) -{ - // get next vertex id - auto next = counter.next(); - - // create new vertex record - VertexRecord vertex_record(next); - auto vertex = vertex_record.insert(t.trans); - - // insert the new vertex record into the vertex store - auto vertices_accessor = vertices.access(); - auto result = vertices_accessor.insert(next, std::move(vertex_record)); - - // create new vertex - auto inserted_vertex_record = result.first; - t.to_update_index<TypeGroupVertex>(&inserted_vertex_record->second, vertex); - - return VertexAccessor(vertex, &inserted_vertex_record->second, t); -} - -Vertices::prop_familys_t::Accessor Vertices::property_family_access() -{ - return prop_familys.access(); -} - -VertexPropertyFamily & -Vertices::property_family_find_or_create(const std::string &name) -{ - auto acc = prop_familys.access(); - auto it = acc.find(name); - if (it == acc.end()) { - auto family = std::unique_ptr<VertexPropertyFamily>( - new VertexPropertyFamily(name)); - auto res = acc.insert(name, std::move(family)); - it = res.first; - } - return *(it->second); -} diff --git a/tests/integration/_hardcoded_query/includes.hpp b/tests/integration/_hardcoded_query/includes.hpp index 810a9ce23..87f00092e 100644 --- a/tests/integration/_hardcoded_query/includes.hpp +++ b/tests/integration/_hardcoded_query/includes.hpp @@ -10,8 +10,8 @@ #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/graph_db.hpp" +#include "database/graph_db.hpp" #include "database/db_accessor.hpp" #include "database/db_accessor.hpp" #include "io/network/socket.hpp" diff --git a/tests/integration/queries.cpp b/tests/integration/queries.cpp index 3b30a7515..36c1f9aad 100644 --- a/tests/integration/queries.cpp +++ b/tests/integration/queries.cpp @@ -1,5 +1,5 @@ #include "communication/bolt/v1/serialization/bolt_serializer.hpp" -#include "database/db.hpp" +#include "database/graph_db.hpp" #include "logging/default.hpp" #include "logging/streams/stdout.hpp" #include "_hardcoded_query/basic.hpp"