From d22eedfe9e20608558a5378622c76969f73c64e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20Tomic=CC=8Cevic=CC=81?=
 <dominik.tomicevic@gmail.com>
Date: Sun, 6 Dec 2015 16:37:42 +0100
Subject: [PATCH] refactored storage engine

---
 mvcc/{mvcc.hpp => record.hpp}                 |  0
 storage/edge.hpp                              | 29 ++++++----
 storage/model/edge_list.hpp                   | 39 ++++++++++++++
 storage/model/edge_model.hpp                  | 14 +++++
 storage/model/edge_type.hpp                   | 35 ++++++++++++
 storage/model/label.hpp                       | 35 ++++++++++++
 storage/model/label_list.hpp                  | 54 +++++++++++++++++++
 storage/model/properties/jsonwriter.hpp       |  6 +--
 storage/model/properties/properties.hpp       | 12 ++---
 storage/model/property_model.hpp              |  9 ++++
 storage/model/record.hpp                      | 10 ++--
 storage/model/vertex_model.hpp                | 12 +++++
 storage/vertex.hpp                            | 34 +++++++-----
 ...action_cache.hpp => transaction_store.hpp} |  0
 14 files changed, 246 insertions(+), 43 deletions(-)
 rename mvcc/{mvcc.hpp => record.hpp} (100%)
 create mode 100644 storage/model/edge_list.hpp
 create mode 100644 storage/model/edge_model.hpp
 create mode 100644 storage/model/edge_type.hpp
 create mode 100644 storage/model/label.hpp
 create mode 100644 storage/model/label_list.hpp
 create mode 100644 storage/model/property_model.hpp
 create mode 100644 storage/model/vertex_model.hpp
 rename transactions/{transaction_cache.hpp => transaction_store.hpp} (100%)

diff --git a/mvcc/mvcc.hpp b/mvcc/record.hpp
similarity index 100%
rename from mvcc/mvcc.hpp
rename to mvcc/record.hpp
diff --git a/storage/edge.hpp b/storage/edge.hpp
index 535be028e..24311c3aa 100644
--- a/storage/edge.hpp
+++ b/storage/edge.hpp
@@ -1,16 +1,23 @@
-#ifndef MEMGRAPH_STORAGE_EDGE_HPP
-#define MEMGRAPH_STORAGE_EDGE_HPP
+#pragma once
 
-#include <vector>
+#include "model/properties/jsonwriter.hpp"
+#include "model/edge_model.hpp"
+#include "mvcc/record.hpp"
 
-#include "model/record.hpp"
+class Edge;
 
-struct Vertex;
-
-struct Edge : public Record<Edge>
+class Edge : public mvcc::Record<Edge>
 {
-    Vertex* from;
-    Vertex* to;
-};
+public:
+    Edge() = default;
+    Edge(const EdgeModel& data) : data(data) {}
+    Edge(EdgeModel&& data) : data(std::move(data)) {}
 
-#endif
+    Edge(const Edge&) = delete;
+    Edge(Edge&&) = delete;
+
+    Edge& operator=(const Edge&) = delete;
+    Edge& operator=(Edge&&) = delete;
+
+    EdgeModel data;
+};
diff --git a/storage/model/edge_list.hpp b/storage/model/edge_list.hpp
new file mode 100644
index 000000000..fccafa7b4
--- /dev/null
+++ b/storage/model/edge_list.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <vector>
+#include "mvcc/version_list.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.push_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();
+    }
+
+private:
+    std::vector<EdgeRecord*> edges;
+};
diff --git a/storage/model/edge_model.hpp b/storage/model/edge_model.hpp
new file mode 100644
index 000000000..00c23833a
--- /dev/null
+++ b/storage/model/edge_model.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "property_model.hpp"
+#include "edge_type.hpp"
+#include "mvcc/version_list.hpp"
+
+class EdgeModel : public PropertyModel
+{
+public:
+    VertexRecord* from;
+    VertexRecord* to;
+
+    EdgeType edge_type;
+};
diff --git a/storage/model/edge_type.hpp b/storage/model/edge_type.hpp
new file mode 100644
index 000000000..df7a511a8
--- /dev/null
+++ b/storage/model/edge_type.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <stdint.h>
+#include <ostream>
+#include "utils/total_ordering.hpp"
+
+class EdgeType : public TotalOrdering<EdgeType>
+{
+public:
+    EdgeType(const std::string& id) : id(id) {}
+    EdgeType(std::string&& id) : id(std::move(id)) {}
+
+    friend bool operator<(const EdgeType& lhs, const EdgeType& rhs)
+    {
+        return lhs.id < rhs.id;
+    }
+
+    friend bool operator==(const EdgeType& lhs, const EdgeType& rhs)
+    {
+        return lhs.id == rhs.id;
+    }
+
+    friend std::ostream& operator<<(std::ostream& stream, const EdgeType& type)
+    {
+       return stream << type.id;
+    }
+
+    operator const std::string&() const
+    {
+        return id;
+    }
+
+private:
+    std::string id;
+};
diff --git a/storage/model/label.hpp b/storage/model/label.hpp
new file mode 100644
index 000000000..46ffdcb83
--- /dev/null
+++ b/storage/model/label.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <stdint.h>
+#include <ostream>
+#include "utils/total_ordering.hpp"
+
+class Label : public TotalOrdering<Label>
+{
+public:
+    Label(const std::string& id) : id(id) {}
+    Label(std::string&& id) : id(std::move(id)) {}
+
+    friend bool operator<(const Label& lhs, const Label& rhs)
+    {
+        return lhs.id < rhs.id;
+    }
+
+    friend bool operator==(const Label& lhs, const Label& rhs)
+    {
+        return lhs.id == rhs.id;
+    }
+
+    friend std::ostream& operator<<(std::ostream& stream, const Label& label)
+    {
+        return stream << label.id;
+    }
+
+    operator const std::string&() const
+    {
+        return id;
+    }
+
+private:
+    std::string id;
+};
diff --git a/storage/model/label_list.hpp b/storage/model/label_list.hpp
new file mode 100644
index 000000000..f72dfe824
--- /dev/null
+++ b/storage/model/label_list.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <set>
+#include "label.hpp"
+
+class LabelList
+{
+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(Label&& label)
+    {
+        return labels.insert(std::move(label)).second;
+    }
+
+    bool add(const Label& label)
+    {
+        return labels.insert(label).second;
+    }
+
+    bool has(const Label& label) const
+    {
+        return labels.count(label);
+    }
+
+    size_t count() const
+    {
+        return labels.size();
+    }
+
+    bool remove(const Label& label)
+    {
+        auto it = labels.find(label);
+
+        if(it == labels.end())
+            return false;
+
+        return labels.erase(it), true;
+    }
+
+    void clear()
+    {
+        labels.clear();
+    }
+
+private:
+    std::set<Label> labels;
+};
diff --git a/storage/model/properties/jsonwriter.hpp b/storage/model/properties/jsonwriter.hpp
index 50802df8e..56f628e5c 100644
--- a/storage/model/properties/jsonwriter.hpp
+++ b/storage/model/properties/jsonwriter.hpp
@@ -1,8 +1,6 @@
-#ifndef MEMGRAPH_STORAGE_PROPERTIES_JSONWRITER_HPP
-#define MEMGRAPH_STORAGE_PROPERTIES_JSONWRITER_HPP
+#pragma once
 
 #include "properties.hpp"
-#include "storage/model/properties/jsonwriter.hpp"
 
 template <class Buffer>
 struct JsonWriter
@@ -95,5 +93,3 @@ public:
 private:
     std::string data;
 };
-
-#endif
diff --git a/storage/model/properties/properties.hpp b/storage/model/properties/properties.hpp
index 1050b3790..adaecbfc5 100644
--- a/storage/model/properties/properties.hpp
+++ b/storage/model/properties/properties.hpp
@@ -1,8 +1,6 @@
-#ifndef MEMGRAPH_STORAGE_MODEL_PROPERTIES_PROPERTIES_HPP
-#define MEMGRAPH_STORAGE_MODEL_PROPERTIES_PROPERTIES_HPP
+#pragma once
 
 #include <map>
-#include "rapidjson/document.h"
 
 #include "property.hpp"
 
@@ -15,7 +13,7 @@ public:
     {
         return props.find(key);
     }
-    
+
     Property* at(const std::string& key)
     {
         auto it = props.find(key);
@@ -49,14 +47,14 @@ public:
     }
 
     template <class Handler>
-    void accept(Handler& handler)
+    void accept(Handler& handler) const
     {
         bool first = true;
 
         for(auto& kv : props)
         {
             handler.handle(kv.first, *kv.second, first);
-            
+
             if(first)
                 first = false;
         }
@@ -65,5 +63,3 @@ public:
 private:
     props_t props;
 };
-
-#endif
diff --git a/storage/model/property_model.hpp b/storage/model/property_model.hpp
new file mode 100644
index 000000000..a03ac6294
--- /dev/null
+++ b/storage/model/property_model.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "properties/properties.hpp"
+
+class PropertyModel
+{
+public:
+    Properties props;
+};
diff --git a/storage/model/record.hpp b/storage/model/record.hpp
index e652553d4..eb614d744 100644
--- a/storage/model/record.hpp
+++ b/storage/model/record.hpp
@@ -14,16 +14,14 @@
 #include "properties/properties.hpp"
 
 template <class Derived>
-class Record
-    : public Crtp<Derived>,
-      public mvcc::Mvcc<Derived>
+class Record : public Crtp<Derived>, public mvcc::Mvcc<Derived>
 {
 public:
     // a record contains a key value map containing data
     Properties properties;
-    
-    // each record can have one or more distinct labels. 
-    std::set<uint16_t> labels;
+
+    // each record can have one or more distinct labels.
+    // std::set<uint16_t> labels;
 };
 
 #endif
diff --git a/storage/model/vertex_model.hpp b/storage/model/vertex_model.hpp
new file mode 100644
index 000000000..b04f32184
--- /dev/null
+++ b/storage/model/vertex_model.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "property_model.hpp"
+#include "label_list.hpp"
+#include "edge_list.hpp"
+
+class VertexModel : public PropertyModel
+{
+public:
+    EdgeList in, out;
+    LabelList labels;
+};
diff --git a/storage/vertex.hpp b/storage/vertex.hpp
index 372c0d1a3..75923eeba 100644
--- a/storage/vertex.hpp
+++ b/storage/vertex.hpp
@@ -1,29 +1,37 @@
 #pragma once
 
-#include <vector>
-
 #include "model/properties/jsonwriter.hpp"
-#include "model/record.hpp"
-#include "edge.hpp"
+#include "model/vertex_model.hpp"
+#include "mvcc/record.hpp"
 
-struct Vertex : public Record<Vertex>
+class Vertex : public mvcc::Record<Vertex>
 {
-    std::vector<Edge*> in;
-    std::vector<Edge*> out;
+public:
+    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;
 };
 
-inline std::ostream& operator<<(std::ostream& stream, Vertex& record)
+inline std::ostream& operator<<(std::ostream& stream, const Vertex& record)
 {
     StringBuffer buffer;
     JsonWriter<StringBuffer> writer(buffer);
 
     // dump properties in this buffer
-    record.properties.accept(writer);
+    record.data.props.accept(writer);
     writer.finish();
 
-    return stream << "Vertex" 
-                  << "(xmin = " << record.tx.min()
-                  << ", xmax = " << record.tx.max()
+    return stream << "Vertex"
+                  << "(xmin = " << record.tx.cre()
+                  << ", xmax = " << record.tx.exp()
                   << "): " << buffer.str();
 }
 
@@ -35,7 +43,7 @@ inline std::string properties_to_string(Vertex* vertex)
     JsonWriter<StringBuffer> writer(buffer);
 
     // dump properties in this buffer
-    vertex->properties.accept(writer);
+    vertex->data.props.accept(writer);
     writer.finish();
 
     // respond to the use with the buffer
diff --git a/transactions/transaction_cache.hpp b/transactions/transaction_store.hpp
similarity index 100%
rename from transactions/transaction_cache.hpp
rename to transactions/transaction_store.hpp