From 027dce0d9a26a3fe971136be711c689c04969fc5 Mon Sep 17 00:00:00 2001
From: Kruno Tomola Fabro <krunotf@memgraph.io>
Date: Tue, 30 Aug 2016 06:16:04 +0100
Subject: [PATCH] Commint which extracts iterator_base methods to hpp.

---
 CMakeLists.txt                            |  1 -
 include/barrier/barrier.hpp               |  4 ++
 include/query_engine/hardcode/queries.hpp | 13 +++---
 include/storage/edge_accessor.hpp         |  3 ++
 include/storage/record_accessor.hpp       |  9 +---
 include/storage/vertex_accessor.hpp       |  9 ++++
 include/utils/iterator/iterator_base.hpp  | 50 ++++++++++++++++++++---
 src/barrier/barrier.cpp                   |  2 +
 src/storage/edge_accessor.cpp             | 22 ++++++++++
 src/storage/record_accessor.cpp           | 16 ++++++++
 src/storage/vertex_accessor.cpp           |  5 +++
 src/utils/iterator/iterator_base.cpp      | 43 -------------------
 12 files changed, 114 insertions(+), 63 deletions(-)
 delete mode 100644 src/utils/iterator/iterator_base.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e41ecc27f..a1086b0df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -407,7 +407,6 @@ set(memgraph_src_files
     ${src_dir}/utils/string/transform.cpp
     ${src_dir}/utils/string/join.cpp
     ${src_dir}/utils/string/file.cpp
-    ${src_dir}/utils/iterator/iterator_base.cpp
     ${src_dir}/query_engine/util.cpp
     ${src_dir}/communication/bolt/v1/bolt.cpp
     ${src_dir}/communication/bolt/v1/states.cpp
diff --git a/include/barrier/barrier.hpp b/include/barrier/barrier.hpp
index 7c03e49c9..6520c0cf7 100644
--- a/include/barrier/barrier.hpp
+++ b/include/barrier/barrier.hpp
@@ -115,6 +115,8 @@ public:
     VertexAccessor &operator=(const VertexAccessor &other);
     VertexAccessor &operator=(VertexAccessor &&other);
 
+    bool isolated() const;
+
     size_t out_degree() const;
 
     size_t in_degree() const;
@@ -388,6 +390,8 @@ public:
     Option<const EdgeAccessor> next() final;
 
     Count count() final;
+
+    EdgeIterator &operator->() { return *this; }
 };
 
 class VertexPropertyKey : private Sized<8, 8>
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index 191cca8de..303b664d2 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -4,7 +4,6 @@
 #include <map>
 
 #include "barrier/barrier.hpp"
-#include "utils/iterator/iterator_base.cpp"
 
 using namespace std;
 
@@ -182,7 +181,8 @@ auto load_queries(Db &db)
     auto match_all_delete = [&db](const properties_t &args) {
         DbAccessor t(db);
 
-        t.vertex_access().fill().for_all([&](auto a) { a.remove(); });
+        t.vertex_access().fill().isolated().for_all(
+            [&](auto a) { a.remove(); });
 
         return t.commit();
     };
@@ -193,7 +193,8 @@ auto load_queries(Db &db)
 
         auto &label = t.label_find_or_create("LABEL");
 
-        label.index().for_range(t).for_all([&](auto a) { a.remove(); });
+        label.index().for_range(t).isolated().for_all(
+            [&](auto a) { a.remove(); });
 
         return t.commit();
     };
@@ -204,8 +205,8 @@ auto load_queries(Db &db)
 
         auto ov = t.vertex_find(args[0]->as<Int64>().value);
         if (!option_fill(ov)) return t.commit(), false;
-
         auto v = ov.take();
+        if (!v.isolated()) return t.commit(), false;
         v.remove();
 
         return t.commit();
@@ -274,8 +275,8 @@ auto load_queries(Db &db)
         auto it_type = type.index().for_range(t);
         auto it_vertex = t.vertex_access();
 
-        // if(it_type.count().max>it_vertex.count().max){
-        //
+        // TODO
+        // if (it_type.count().max > it_vertex.count().max) {
         // }
 
         return t.commit();
diff --git a/include/storage/edge_accessor.hpp b/include/storage/edge_accessor.hpp
index 9fc06765a..05d266290 100644
--- a/include/storage/edge_accessor.hpp
+++ b/include/storage/edge_accessor.hpp
@@ -20,6 +20,9 @@ public:
     typedef Edge record_t;
     typedef EdgeRecord record_list_t;
 
+    // Removes self and disconects vertices from it.
+    bool remove() const;
+
     void edge_type(EdgeType const &edge_type);
 
     const EdgeType &edge_type() const;
diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp
index 6678cf8ba..9a8e80fb8 100644
--- a/include/storage/record_accessor.hpp
+++ b/include/storage/record_accessor.hpp
@@ -73,13 +73,6 @@ public:
         }
     }
 
-    bool remove() const
-    {
-        assert(!empty());
-
-        return vlist->remove(record, db.trans);
-    }
-
     const Property &at(PropertyFamily<TG> &key) const
     {
         return properties().at(key);
@@ -153,6 +146,8 @@ public:
     }
 
 protected:
+    bool remove() const;
+
     T *record{nullptr};
     vlist_t *const vlist;
     DbTransaction &db;
diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp
index 4927117e3..7b73e8cb3 100644
--- a/include/storage/vertex_accessor.hpp
+++ b/include/storage/vertex_accessor.hpp
@@ -5,21 +5,30 @@
 #include "utils/iterator/iterator.hpp"
 
 class Vertices;
+class EdgeAccessor;
 
 // There exists circular dependecy with EdgeAccessor.
 class VertexAccessor : public RecordAccessor<TypeGroupVertex, VertexAccessor>
 {
+    friend EdgeAccessor;
+
 public:
     using RecordAccessor::RecordAccessor;
     typedef Vertex record_t;
     typedef VertexRecord record_list_t;
 
+    // Removes only self.
+    bool remove() const { return RecordAccessor::remove(); }
+
     size_t out_degree() const;
 
     size_t in_degree() const;
 
     size_t degree() const;
 
+    // True if vertex isn't connected to any other vertex.
+    bool isolated() const;
+
     // False if it's label with it already.
     bool add_label(const Label &label);
 
diff --git a/include/utils/iterator/iterator_base.hpp b/include/utils/iterator/iterator_base.hpp
index d6feb5813..b11906673 100644
--- a/include/utils/iterator/iterator_base.hpp
+++ b/include/utils/iterator/iterator_base.hpp
@@ -5,6 +5,18 @@
 
 class EdgeType;
 
+namespace iter
+{
+template <class I, class OP>
+auto make_map(I &&iter, OP &&op);
+
+template <class I, class OP>
+auto make_filter(I &&iter, OP &&op);
+
+template <class I, class C>
+void for_all(I &&iter, C &&consumer);
+}
+
 // Base iterator for next() kind iterator.
 // T - type of return value
 template <class T>
@@ -18,22 +30,48 @@ public:
     virtual Count count() { return Count(0, ~((size_t)0)); }
 
     template <class OP>
-    auto map(OP &&op);
+    auto map(OP &&op)
+    {
+        return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
+                                                              std::move(op));
+    }
 
     template <class OP>
-    auto filter(OP &&op);
+    auto filter(OP &&op)
+    {
+        return iter::make_filter<decltype(std::move(*this)), OP>(
+            std::move(*this), std::move(op));
+    }
 
     // Maps with call to method to() and filters with call to fill.
-    auto to();
+    auto to()
+    {
+        return map([](auto er) { return er.to(); }).fill();
+    }
 
     // Filters with call to method fill()
-    auto fill();
+    auto fill()
+    {
+        return filter([](auto &ra) { return ra.fill(); });
+    }
 
     // Filters with type
     template <class TYPE>
-    auto type(TYPE const &type);
+    auto type(TYPE const &type)
+    {
+        return filter([&](auto &ra) { return ra.edge_type() == type; });
+    }
+
+    // Filters out vertices which are connected.
+    auto isolated()
+    {
+        return filter([&](auto &ra) { return ra.isolated(); });
+    }
 
     // For all items calls OP.
     template <class OP>
-    void for_all(OP &&op);
+    void for_all(OP &&op)
+    {
+        iter::for_all(std::move(*this), std::move(op));
+    }
 };
diff --git a/src/barrier/barrier.cpp b/src/barrier/barrier.cpp
index 717e1fedf..3c1702dac 100644
--- a/src/barrier/barrier.cpp
+++ b/src/barrier/barrier.cpp
@@ -237,6 +237,8 @@ DESTRUCTOR(VertexAccessor, VertexAccessor);
 COPY_OPERATOR(VertexAccessor);
 MOVE_OPERATOR(VertexAccessor);
 
+bool VertexAccessor::isolated() const { return HALF_CALL(isolated()); }
+
 size_t VertexAccessor::out_degree() const { return HALF_CALL(out_degree()); }
 
 size_t VertexAccessor::in_degree() const { return HALF_CALL(in_degree()); }
diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp
index 9ac3a75df..8e5c91e64 100644
--- a/src/storage/edge_accessor.cpp
+++ b/src/storage/edge_accessor.cpp
@@ -1,5 +1,27 @@
 #include "storage/edge_accessor.hpp"
 
+#include "storage/vertex_record.hpp"
+
+bool EdgeAccessor::remove() const
+{
+    if (RecordAccessor::remove()) {
+        auto from_v = from();
+        bool f_from = from_v.fill();
+        assert(f_from);
+
+        auto to_v = to();
+        bool f_to = to_v.fill();
+        assert(f_to);
+
+        from_v.update().record->data.out.remove(vlist);
+        to_v.update().record->data.in.remove(vlist);
+
+        return true;
+    } else {
+        return false;
+    }
+}
+
 void EdgeAccessor::edge_type(const EdgeType &edge_type)
 {
     this->record->data.edge_type = &edge_type;
diff --git a/src/storage/record_accessor.cpp b/src/storage/record_accessor.cpp
index 422b1b4db..fdbb25a77 100644
--- a/src/storage/record_accessor.cpp
+++ b/src/storage/record_accessor.cpp
@@ -1,8 +1,24 @@
 #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>
+bool RecordAccessor<T, Derived>::remove() const
+{
+    assert(!empty());
+
+    return vlist->remove(record, db.trans);
+}
+
+template class RecordAccessor<TypeGroupEdge, EdgeAccessor>;
+template class RecordAccessor<TypeGroupVertex, VertexAccessor>;
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index 83795ec0c..6b17464ff 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -5,6 +5,11 @@
 #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->data.out.degree();
diff --git a/src/utils/iterator/iterator_base.cpp b/src/utils/iterator/iterator_base.cpp
deleted file mode 100644
index 63615c825..000000000
--- a/src/utils/iterator/iterator_base.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "utils/iterator/iterator.hpp"
-
-template <class T>
-template <class OP>
-auto IteratorBase<T>::map(OP &&op)
-{
-    return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
-                                                          std::move(op));
-}
-
-template <class T>
-template <class OP>
-auto IteratorBase<T>::filter(OP &&op)
-{
-    return iter::make_filter<decltype(std::move(*this)), OP>(std::move(*this),
-                                                             std::move(op));
-}
-
-template <class T>
-auto IteratorBase<T>::to()
-{
-    return map([](auto er) { return er.to(); }).fill();
-}
-
-template <class T>
-auto IteratorBase<T>::fill()
-{
-    return filter([](auto &ra) { return ra.fill(); });
-}
-
-template <class T>
-template <class TYPE>
-auto IteratorBase<T>::type(TYPE const &type)
-{
-    return filter([&](auto &ra) { return ra.edge_type() == type; });
-}
-
-template <class T>
-template <class OP>
-void IteratorBase<T>::for_all(OP &&op)
-{
-    iter::for_all(std::move(*this), std::move(op));
-}