From e28d15c27217fc2246dd797bb1daebc721e9bead Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dominik=20Tomic=CC=8Cevic=CC=81?=
 <dominik.tomicevic@gmail.com>
Date: Sun, 13 Sep 2015 11:34:17 +0200
Subject: [PATCH] worked on mvcc, compiler and some utils, unfinished

---
 cypher/ast/ast.hpp                           |   5 +
 cypher/ast/ast_visitor.hpp                   |  11 +-
 cypher/ast/match.hpp                         |  22 ++++
 cypher/ast/pattern.hpp                       |  12 +--
 cypher/ast/queries.hpp                       |  22 ++++
 cypher/ast/relationship.hpp                  |   8 +-
 cypher/ast/start.hpp                         |  20 ++++
 cypher/ast/tree.hpp                          |   4 +-
 cypher/ast/where.hpp                         |  20 ++++
 cypher/cypher.y                              |  46 +++++---
 cypher/errors.hpp                            |  26 +++++
 cypher/lexer.hpp                             |   9 +-
 cypher/lexical_error.hpp                     |  15 ---
 data_structures/list/lockfree_list.hpp       | 108 +++++++++++++++++++
 data_structures/list/lockfree_list2.hpp      |  71 ++++++++++++
 data_structures/skiplist/skiplist.hpp        |   4 +-
 data_structures/skiplist/skipnode.hpp        |   2 +-
 data_structures/slstack.hpp                  |  13 ++-
 main.cpp                                     |   2 +-
 memory/{memory_engine.hpp => memory.hpp}     |   5 +-
 mvcc/atom.hpp                                |  57 ++++++++++
 {transaction => mvcc}/commit_log.hpp         |   4 +-
 {storage/model/utils => mvcc}/minmax.hpp     |   9 +-
 {storage/model/utils => mvcc}/mvcc.hpp       |  27 +++--
 mvcc/store.hpp                               |  85 +++++++++++++++
 {transaction => mvcc}/transaction.hpp        |   6 +-
 {transaction => mvcc}/transaction_engine.hpp |   9 +-
 {storage/model/utils => mvcc}/version.hpp    |   9 +-
 server/uv/uvbuffer.inl                       |   6 +-
 storage/{model => }/edge.hpp                 |   8 +-
 storage/graph.hpp                            |  33 ++++++
 storage/model/graph.hpp                      |  16 ---
 storage/model/properties/properties.hpp      |   2 +-
 storage/model/properties/property.hpp        |   2 +-
 storage/model/properties/string.hpp          |   2 +-
 storage/model/record.hpp                     |  15 +--
 storage/model/root.hpp                       |  19 ----
 storage/storage_engine.hpp                   |   2 +
 storage/{model => }/vertex.hpp               |   6 +-
 threading/sync/spinlock.hpp                  |   4 +-
 threading/sync/timed_spinlock.hpp            |  55 ++++++++++
 utils/buffer.hpp                             |  47 ++++++++
 utils/counters/atomic_counter.hpp            |   2 +-
 utils/memory/atomic_shared_ptr.hpp           |  29 +++++
 utils/numerics/ceil.hpp                      |  21 ++++
 45 files changed, 764 insertions(+), 136 deletions(-)
 create mode 100644 cypher/ast/match.hpp
 create mode 100644 cypher/ast/queries.hpp
 create mode 100644 cypher/ast/start.hpp
 create mode 100644 cypher/ast/where.hpp
 create mode 100644 cypher/errors.hpp
 delete mode 100644 cypher/lexical_error.hpp
 create mode 100644 data_structures/list/lockfree_list.hpp
 create mode 100644 data_structures/list/lockfree_list2.hpp
 rename memory/{memory_engine.hpp => memory.hpp} (89%)
 create mode 100644 mvcc/atom.hpp
 rename {transaction => mvcc}/commit_log.hpp (91%)
 rename {storage/model/utils => mvcc}/minmax.hpp (84%)
 rename {storage/model/utils => mvcc}/mvcc.hpp (91%)
 create mode 100644 mvcc/store.hpp
 rename {transaction => mvcc}/transaction.hpp (91%)
 rename {transaction => mvcc}/transaction_engine.hpp (88%)
 rename {storage/model/utils => mvcc}/version.hpp (88%)
 rename storage/{model => }/edge.hpp (52%)
 create mode 100644 storage/graph.hpp
 delete mode 100644 storage/model/graph.hpp
 delete mode 100644 storage/model/root.hpp
 rename storage/{model => }/vertex.hpp (58%)
 create mode 100644 threading/sync/timed_spinlock.hpp
 create mode 100644 utils/buffer.hpp
 create mode 100644 utils/memory/atomic_shared_ptr.hpp
 create mode 100644 utils/numerics/ceil.hpp

diff --git a/cypher/ast/ast.hpp b/cypher/ast/ast.hpp
index 3fc87a0be..1a0cf962c 100644
--- a/cypher/ast/ast.hpp
+++ b/cypher/ast/ast.hpp
@@ -9,5 +9,10 @@
 #include "relationship.hpp"
 #include "node.hpp"
 #include "return.hpp"
+#include "pattern.hpp"
+#include "return.hpp"
+#include "match.hpp"
+#include "queries.hpp"
+#include "start.hpp"
 
 #endif
diff --git a/cypher/ast/ast_visitor.hpp b/cypher/ast/ast_visitor.hpp
index e296dd31a..043b00817 100644
--- a/cypher/ast/ast_visitor.hpp
+++ b/cypher/ast/ast_visitor.hpp
@@ -34,18 +34,27 @@ struct Star;
 struct Slash;
 struct Rem;
 
+struct RelationshipSpecs;
 struct RelationshipList;
 struct Relationship;
 
 struct Node;
 struct LabelList;
 
+struct Pattern;
+
 struct ReturnList;
+struct Match;
+struct Where;
+struct ReadQuery;
+
+struct Start;
 
 struct AstVisitor : Visitor<Accessor, Boolean, Float, Identifier, Integer,
     String, Property, And, Or, Lt, Gt, Ge, Le, Eq, Ne, Plus, Minus, Star,
     Slash, Rem, PropertyList, RelationshipList, Relationship, Node,
-    LabelList, ReturnList> {};
+    RelationshipSpecs, LabelList, ReturnList, Pattern, Match, ReadQuery,
+    Start, Where> {};
 
 }
 
diff --git a/cypher/ast/match.hpp b/cypher/ast/match.hpp
new file mode 100644
index 000000000..b50155ceb
--- /dev/null
+++ b/cypher/ast/match.hpp
@@ -0,0 +1,22 @@
+#ifndef MEMGRAPH_CYPHER_AST_MATCH_HPP
+#define MEMGRAPH_CYPHER_AST_MATCH_HPP
+
+#include "ast_node.hpp"
+#include "pattern.hpp"
+#include "where.hpp"
+
+namespace ast
+{
+
+struct Match : public AstNode<Match>
+{
+    Match(Pattern* pattern, Where* where)
+        : pattern(pattern), where(where) {}
+
+    Pattern* pattern;
+    Where* where;
+};
+
+}
+
+#endif
diff --git a/cypher/ast/pattern.hpp b/cypher/ast/pattern.hpp
index 397d1ca3d..2337abdad 100644
--- a/cypher/ast/pattern.hpp
+++ b/cypher/ast/pattern.hpp
@@ -2,20 +2,18 @@
 #define MEMGRAPH_CYPHER_AST_PATTERN_HPP
 
 #include "ast_node.hpp"
+#include "relationship.hpp"
 
 namespace ast
 {
 
-template <class Derived>
-struct Direction : public AstNode<Derived> {};
-
-struct DirectionLeft : public Direction<DirectionLeft> {};
-struct DirectionRight : public Direction<DirectionLeft> {};
-struct Unidirectional : public Direction<DirectionLeft> {};
-
 struct Pattern : public AstNode<Pattern>
 {
+    Pattern(Node* node, Relationship* relationship, Pattern* next)
+        : node(node), relationship(relationship), next(next) {}
+
     Node* node;
+    Relationship* relationship;
     Pattern* next;
 };
 
diff --git a/cypher/ast/queries.hpp b/cypher/ast/queries.hpp
new file mode 100644
index 000000000..c1c5a8692
--- /dev/null
+++ b/cypher/ast/queries.hpp
@@ -0,0 +1,22 @@
+#ifndef MEMGRAPH_CYPHER_AST_QUERIES_HPP
+#define MEMGRAPH_CYPHER_AST_QUERIES_HPP
+
+#include "ast_node.hpp"
+#include "match.hpp"
+#include "return.hpp"
+
+namespace ast
+{
+
+struct ReadQuery : public AstNode<ReadQuery>
+{
+    ReadQuery(Match* match, ReturnList* return_list)
+        : match(match), return_list(return_list) {}
+
+    Match* match;
+    ReturnList* return_list;
+};
+
+}
+
+#endif
diff --git a/cypher/ast/relationship.hpp b/cypher/ast/relationship.hpp
index 99fa4d73a..a6d20a1e8 100644
--- a/cypher/ast/relationship.hpp
+++ b/cypher/ast/relationship.hpp
@@ -24,7 +24,13 @@ struct RelationshipSpecs : public AstNode<RelationshipSpecs>
 
 struct Relationship : public AstNode<Relationship>
 {
-    Relationship()
+    enum Direction { Left, Right, Both };
+
+    Relationship(RelationshipSpecs* specs, Direction direction)
+        : specs(specs), direction(direction) {}
+
+    RelationshipSpecs* specs;
+    Direction direction;
 };
 
 }
diff --git a/cypher/ast/start.hpp b/cypher/ast/start.hpp
new file mode 100644
index 000000000..93ba59d05
--- /dev/null
+++ b/cypher/ast/start.hpp
@@ -0,0 +1,20 @@
+#ifndef MEMGRAPH_CYPHER_AST_START_HPP
+#define MEMGRAPH_CYPHER_AST_START_HPP
+
+#include "ast_node.hpp"
+#include "queries.hpp"
+
+namespace ast
+{
+
+struct Start : public AstNode<Start>
+{
+    Start(ReadQuery* read_query)
+        : read_query(read_query) {}
+
+    ReadQuery* read_query;
+};
+
+};
+
+#endif
diff --git a/cypher/ast/tree.hpp b/cypher/ast/tree.hpp
index 89225e0a4..c3db1c216 100644
--- a/cypher/ast/tree.hpp
+++ b/cypher/ast/tree.hpp
@@ -13,7 +13,7 @@ class Ast
 public:
     Ast() {}
 
-    AstVisitable::uptr root;
+    AstVisitable* root;
 
     void traverse(AstVisitor& visitor)
     {
@@ -32,7 +32,7 @@ private:
     // basically a gc vector that destroys all ast nodes once this object is
     // destroyed. parser generator is written in c and works only with raw
     // pointers so this is what makes it leak free after the parser finishes
-    // parsing
+    // parsing without using shared pointers
     std::vector<AstVisitable::uptr> items;
 };
 
diff --git a/cypher/ast/where.hpp b/cypher/ast/where.hpp
new file mode 100644
index 000000000..2da3e2af9
--- /dev/null
+++ b/cypher/ast/where.hpp
@@ -0,0 +1,20 @@
+#ifndef MEMGRAPH_CYPHER_AST_WHERE_HPP
+#define MEMGRAPH_CYPHER_AST_WHERE_HPP
+
+#include "ast_node.hpp"
+#include "expr.hpp"
+
+namespace ast
+{
+
+struct Where : public AstNode<Where>
+{
+    Where(Expr* expr)
+        : expr(expr) {}
+
+    Expr* expr;
+};
+
+}
+
+#endif
diff --git a/cypher/cypher.y b/cypher/cypher.y
index e61aacef3..ddcdb1bac 100644
--- a/cypher/cypher.y
+++ b/cypher/cypher.y
@@ -13,13 +13,12 @@
 
 %syntax_error
 {
-    std::cout << "syntax error near '" << TOKEN->value << "'." << std::endl;
-    throw "";
+    throw SyntaxError(TOKEN->value);
 }
 
 %stack_overflow
 {
-    std::cout << "parser stack overflow" << std::endl;
+    throw ParserError("Parser stack overflow");
 }
 
 %name cypher_parser
@@ -31,6 +30,7 @@
     #include <cstdlib>
 
     #include "token.hpp"
+    #include "errors.hpp"
     #include "ast/ast.hpp"
     #include "ast/tree.hpp"
 
@@ -46,33 +46,45 @@
 %left PLUS MINUS.
 %left STAR SLASH REM.
 
-start ::= read_query.
+start ::= read_query(RQ). {
+   ast->root = ast->create<ast::Start>(RQ);
+}
 
-read_query ::= match_clause return_clause.
+%type read_query {ast::ReadQuery*}
 
-match_clause ::= MATCH pattern where_clause.
+read_query(RQ) ::= match_clause(M) return_clause(R). {
+    RQ = ast->create<ast::ReadQuery>(M, R);
+}
+
+%type match_clause {ast::Match*}
+
+match_clause(M) ::= MATCH pattern(P) where_clause(W). {
+    M = ast->create<ast::Match>(P, W);
+}
 
 %type pattern {ast::Pattern*}
 
 // pattern specification
-pattern ::= node rel pattern. {
-
+pattern(P) ::= node(N) rel(R) pattern(NEXT). {
+    P = ast->create<ast::Pattern>(N, R, NEXT);
 }
 
-pattern ::= node. {
-    
+pattern(P) ::= node(N). {
+    P = ast->create<ast::Pattern>(N, nullptr, nullptr);
 }
 
-rel ::= MINUS rel_spec MINUS. { // unidirectional
+%type rel {ast::Relationship*}
 
+rel(R) ::= MINUS rel_spec(S) MINUS. { // unidirectional
+    R = ast->create<ast::Relationship>(S, ast::Relationship::Both);
 }
 
-rel ::= LT MINUS rel_spec MINUS { // left
-
+rel(R) ::= LT MINUS rel_spec(S) MINUS. { // left
+    R = ast->create<ast::Relationship>(S, ast::Relationship::Left);
 }
 
-rel(R) ::= MINUS rel_spec(S) MINUS GT { // right
-    R = ast->create<ast::Relationship>(
+rel(R) ::= MINUS rel_spec(S) MINUS GT. { // right
+    R = ast->create<ast::Relationship>(S, ast::Relationship::Right);
 }
 
 %type rel_spec {ast::RelationshipSpecs*}
@@ -148,11 +160,11 @@ label_idn(L) ::= . {
     L = nullptr;
 }
 
-%type where_clause {ast::Expr*}
+%type where_clause {ast::Where*}
 
 // where clause
 where_clause(W) ::= WHERE expr(E). {
-    W = E;
+    W = ast->create<ast::Where>(E);
 }
 
 where_clause(W) ::= . {
diff --git a/cypher/errors.hpp b/cypher/errors.hpp
new file mode 100644
index 000000000..e5bea3625
--- /dev/null
+++ b/cypher/errors.hpp
@@ -0,0 +1,26 @@
+#ifndef MEMGRAPH_CYPHER_ERRORS_HPP
+#define MEMGRAPH_CYPHER_ERRORS_HPP
+
+#include <stdexcept>
+#include "token.hpp"
+
+class SyntaxError : public std::runtime_error
+{
+public:
+    SyntaxError(const std::string& near)
+        : std::runtime_error("Syntax error near '" + near + "'.") {}
+};
+
+class LexicalError : public std::runtime_error
+{
+public:
+    LexicalError(const Token& token)
+        : std::runtime_error("Unrecognized token '" + token.value + "'.") {}
+};
+
+class ParserError : public std::runtime_error
+{
+    using runtime_error::runtime_error;
+};
+
+#endif
diff --git a/cypher/lexer.hpp b/cypher/lexer.hpp
index 9353407c4..6a0b15226 100644
--- a/cypher/lexer.hpp
+++ b/cypher/lexer.hpp
@@ -3,16 +3,21 @@
 
 #include <cstdint>
 
+// unfortunatelly, lexertl uses some stuff deprecated in c++11 so we get some
+// warnings during compile time, mainly for the auto_ptr
+// auto_ptr<lexertl::detail::basic_re_token<char, char> > is deprecated
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #include "lexertl/generator.hpp"
 #include "lexertl/lookup.hpp"
+#pragma GCC diagnostic pop
 
-#include "lexical_error.hpp"
+#include "errors.hpp"
 #include "token.hpp"
 
 class Lexer
 {
 public:
-
     class Tokenizer
     {
     public:
diff --git a/cypher/lexical_error.hpp b/cypher/lexical_error.hpp
deleted file mode 100644
index c11ca3a35..000000000
--- a/cypher/lexical_error.hpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef MEMGRAPH_CYPHER_LEXER_LEXICAL_ERROR_HPP
-#define MEMGRAPH_CYPHER_LEXER_LEXICAL_ERROR_HPP
-
-#include <stdexcept>
-
-#include "token.hpp"
-
-class LexicalError : public std::runtime_error
-{
-public:
-    LexicalError(const Token& token)
-        : std::runtime_error("Unrecognized token '" + token.value + "'.") {}
-};
-
-#endif
diff --git a/data_structures/list/lockfree_list.hpp b/data_structures/list/lockfree_list.hpp
new file mode 100644
index 000000000..96185904d
--- /dev/null
+++ b/data_structures/list/lockfree_list.hpp
@@ -0,0 +1,108 @@
+#ifndef MEMGRAPH_DATA_STRUCTURES_LIST_LOCKFREE_LIST_HPP
+#define MEMGRAPH_DATA_STRUCTURES_LIST_LOCKFREE_LIST_HPP
+
+#include <atomic>
+#include <memory>
+#include <unistd.h>
+
+namespace lockfree
+{
+
+template <class T, size_t sleep_time = 250>
+class List
+{
+    struct Node
+    {
+        T item;
+        std::shared_ptr<Node> next;
+    };
+
+public:
+    List() = default;
+    
+    // the default destructor is recursive so it could blow the stack if the
+    // list is long enough. the head node is destructed first via a shared_ptr
+    // and then it automatically destructs the second node and the second
+    // destructs the third and so on. keep that in mind
+    ~List() = default;
+
+    List(List&) = delete;
+    void operator=(List&) = delete;
+
+    class iterator
+    {
+    public:
+        iterator(std::shared_ptr<Node> ptr) : ptr(ptr) {}
+
+        T& operator*() { return ptr->item; }
+        T* operator->() { return &ptr->item; }
+
+        iterator& operator++()
+        {
+            if(ptr)
+                ptr = ptr->next;
+
+            return *this;
+        }
+  
+        iterator& operator++(int)
+        {
+            operator++();
+            return *this;
+        }
+
+    private:
+        std::shared_ptr<Node> ptr;
+    };
+
+    iterator begin() { return iterator(std::move(head.load())); }
+    iterator end() { return iterator(nullptr); }
+
+    auto find(T item)
+    {
+        auto p = head.load();
+
+        while(p && p->item != item)
+            p = p->next;
+
+        return iterator(std::move(p));
+    }
+
+    iterator push_front(T item)
+    {
+        auto p = std::make_shared<Node>();
+        p->item = item;
+        p->next = std::move(head.load());
+
+        while(!head.compare_exchange_weak(p->next, p))
+            usleep(sleep_time);
+
+        return iterator(p);
+    }
+
+    iterator pop_front()
+    {
+        auto p = head.load();
+        auto q = p;
+
+        while(p && !head.compare_exchange_weak(p, p->next))
+        {
+            q = p;
+            usleep(sleep_time);
+        }
+
+        return iterator(q);
+    }
+
+    // TODO think about how to make this lock free and safe from ABA
+    // this can easily be thread safe if there is ONLY ONE concurrent
+    // remove operation
+    //bool remove(T item);
+   
+private:
+    std::atomic<std::shared_ptr<Node>> head { nullptr };
+};
+
+};
+
+#endif
diff --git a/data_structures/list/lockfree_list2.hpp b/data_structures/list/lockfree_list2.hpp
new file mode 100644
index 000000000..a9d762cff
--- /dev/null
+++ b/data_structures/list/lockfree_list2.hpp
@@ -0,0 +1,71 @@
+#ifndef MEMGRAPH_DATA_STRUCTURES_LOCKFREE_LIST2_HPP
+#define MEMGRAPH_DATA_STRUCTURES_LOCKFREE_LIST2_HPP
+
+#include <atomic>
+
+#include "threading/sync/spinlock.hpp"
+#include "threading/sync/lockable.hpp"
+
+namespace lockfree
+{
+
+template <class T>
+class List2 : Lockable<SpinLock>
+{
+    struct Node { T value; std::atomic<Node*> next; };
+
+    class iterator
+    {
+        iterator(Node* node) : node(node) {}
+
+        T& operator*() const { return *node; }
+        T* operator->() const { return node; }
+
+        bool end() const
+        {
+            return node == nullptr;
+        }
+
+        iterator& operator++()
+        {
+            node = node->next.load(std::memory_order_relaxed);
+            return *this;
+        }
+
+        iterator& operator++(int)
+        {
+            return operator++();
+        }
+
+    protected:
+        Node* node;
+    };
+
+public:
+
+    ~List2()
+    {
+        Node* next, node = head.load(std::memory_order_relaxed);
+
+        for(; node != nullptr; node = next)
+        {
+            next = node->next;
+            delete node;
+        }
+    }
+
+    void insert(T value)
+    {
+        auto guard = acquire();
+        head.store(new Node { value, head });
+    }
+
+    iterator begin() { return iterator(head.load()); }
+
+private:
+    std::atomic<Node*> head;
+};
+
+}
+
+#endif
diff --git a/data_structures/skiplist/skiplist.hpp b/data_structures/skiplist/skiplist.hpp
index 6916865fc..d0d380cef 100644
--- a/data_structures/skiplist/skiplist.hpp
+++ b/data_structures/skiplist/skiplist.hpp
@@ -84,11 +84,9 @@ public:
                 lfound = level;
 
             preds[level] = pred;
-            succs[level] = node; // TODO what's FB doing here?
+            succs[level] = node;
         }
 
-        //std::cout << "lfound = " << lfound << std::endl;
-
         return lfound;
     }
 
diff --git a/data_structures/skiplist/skipnode.hpp b/data_structures/skiplist/skipnode.hpp
index e03d76f7f..1aeb45fce 100644
--- a/data_structures/skiplist/skipnode.hpp
+++ b/data_structures/skiplist/skipnode.hpp
@@ -5,7 +5,7 @@
 #include <atomic>
 #include <mutex>
 
-#include "sync/spinlock.hpp"
+#include "threading/sync/spinlock.hpp"
 
 // concurrent skiplist node based on the implementation described in
 // "A Provably Correct Scalable Concurrent Skip List"
diff --git a/data_structures/slstack.hpp b/data_structures/slstack.hpp
index 7f2b19d65..dbde180a4 100644
--- a/data_structures/slstack.hpp
+++ b/data_structures/slstack.hpp
@@ -3,30 +3,29 @@
 
 #include <stack>
 
-#include "utils/sync/spinlock.hpp"
+#include "threading/sync/spinlock.hpp"
+#include "threading/sync/lockable.hpp"
 
 template <class T>
-class SpinLockStack
+class SpinLockStack : Lockable<SpinLock>
 {
 public:
 
     T pop()
     {
-        lock.acquire();
+        auto guard = acquire();
 
         T elem = stack.top();
         stack.pop();
 
-        lock.release();
-
         return elem;
     }
 
     void push(const T& elem)
     {
-        lock.acquire();
+        auto guard = acquire();
+
         stack.push(elem);
-        lock.release();
     }
 
 private:
diff --git a/main.cpp b/main.cpp
index 131548399..355567605 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,7 +1,7 @@
 #include <iostream>
 #include <thread>
 
-#include "sync/spinlock.hpp"
+#include "threading/sync/spinlock.hpp"
 
 #include "transaction/transaction_engine.hpp"
 #include "memory/memory_engine.hpp"
diff --git a/memory/memory_engine.hpp b/memory/memory.hpp
similarity index 89%
rename from memory/memory_engine.hpp
rename to memory/memory.hpp
index 7735f726b..7d379d70a 100644
--- a/memory/memory_engine.hpp
+++ b/memory/memory.hpp
@@ -1,10 +1,9 @@
-#ifndef MEMGRAPH_MEMORY_MEMORY_ENGINE_HPP
-#define MEMGRAPH_MEMORY_MEMORY_ENGINE_HPP
+#ifndef MEMGRAPH_MEMORY_MEMORY_HPP
+#define MEMGRAPH_MEMORY_MEMORY_HPP
 
 #include <atomic>
 #include <mutex>
 
-#include "transaction/transaction.hpp"
 #include "storage/model/record.hpp"
 #include "storage/model/vertex.hpp"
 #include "storage/model/edge.hpp"
diff --git a/mvcc/atom.hpp b/mvcc/atom.hpp
new file mode 100644
index 000000000..ab3e8570f
--- /dev/null
+++ b/mvcc/atom.hpp
@@ -0,0 +1,57 @@
+#ifndef MEMGRAPH_MVCC_ATOM_HPP
+#define MEMGRAPH_MVCC_ATOM_HPP
+
+#include "threading/sync/lockable.hpp"
+
+#include "transaction.hpp"
+#include "version.hpp"
+
+namespace mvcc
+{
+
+template <class T>
+class Atom : public Version<T>,
+             public Lockable<>
+{
+public:
+    Atom(uint64_t id, T* first)
+        : Version<T>(first), id(id)
+    {
+        // it's illegal that the first version is nullptr. there should be at
+        // least one version of a record
+        assert(first != nullptr);
+    }
+
+    T* first()
+    {
+        return this->newer();
+    }
+
+    // inspects the record change history and returns the record version visible
+    // to the current transaction if it exists, otherwise it returns nullptr
+    T* latest_visible(const Transaction& t)
+    {
+        return first()->latest_visible(t);
+    }
+
+    // inspects the record change history and returns the newest available
+    // version from all transactions
+    T& newest_available()
+    {
+        T* record = this->newer(), newer = this->newer();
+
+        while(newer != nullptr)
+            record = newer, newer = record->newer();
+
+        return record;
+    }
+
+    // every record has a unique id. 2^64 = 1.8 x 10^19. that should be enough
+    // for a looong time :) but keep in mind that some vacuuming would be nice
+    // to reuse indices for deleted nodes.
+    uint64_t id;
+};
+
+}
+
+#endif
diff --git a/transaction/commit_log.hpp b/mvcc/commit_log.hpp
similarity index 91%
rename from transaction/commit_log.hpp
rename to mvcc/commit_log.hpp
index 7a235e876..1a6a2bc11 100644
--- a/transaction/commit_log.hpp
+++ b/mvcc/commit_log.hpp
@@ -5,8 +5,8 @@
 
 #include <boost/dynamic_bitset/dynamic_bitset.hpp>
 
-#include "sync/spinlock.hpp"
-#include "sync/lockable.hpp"
+#include "threading/sync/spinlock.hpp"
+#include "threading/sync/lockable.hpp"
 
 // optimize allocation performance by preallocating chunks in like 2MB or so
 // optimize memory by purging old transactions after vacuuming or something
diff --git a/storage/model/utils/minmax.hpp b/mvcc/minmax.hpp
similarity index 84%
rename from storage/model/utils/minmax.hpp
rename to mvcc/minmax.hpp
index bca402a4d..29bf76524 100644
--- a/storage/model/utils/minmax.hpp
+++ b/mvcc/minmax.hpp
@@ -1,8 +1,11 @@
-#ifndef MEMGRAPH_STORAGE_MODEL_UTILS_MINMAX_HPP
-#define MEMGRAPH_STORAGE_MODEL_UTILS_MINMAX_HPP
+#ifndef MEMGRAPH_MVCC_MINMAX_HPP
+#define MEMGRAPH_MVCC_MINMAX_HPP
 
 #include <atomic>
 
+namespace mvcc
+{
+
 template <class T>
 class MinMax
 {
@@ -35,4 +38,6 @@ private:
     std::atomic<T> min_, max_;
 };
 
+}
+
 #endif
diff --git a/storage/model/utils/mvcc.hpp b/mvcc/mvcc.hpp
similarity index 91%
rename from storage/model/utils/mvcc.hpp
rename to mvcc/mvcc.hpp
index ce1005e77..9d80cb86b 100644
--- a/storage/model/utils/mvcc.hpp
+++ b/mvcc/mvcc.hpp
@@ -3,15 +3,16 @@
 
 #include <atomic>
 
-#include "transaction/transaction.hpp"
-#include "storage/model/utils/minmax.hpp"
-#include "storage/model/utils/version.hpp"
-
-#include "transaction/commit_log.hpp"
+#include "transaction.hpp"
+#include "minmax.hpp"
+#include "version.hpp"
 
 // the mvcc implementation used here is very much like postgresql's
 // more info: https://momjian.us/main/writings/pgsql/mvcc.pdf
 
+namespace mvcc
+{
+
 template <class T>
 class Mvcc : public Version<T>
 {
@@ -62,7 +63,7 @@ public:
 
     // inspects the record change history and returns the record version visible
     // to the current transaction if it exists, otherwise it returns nullptr
-    T* latest(const Transaction& t)
+    T* latest_visible(const Transaction& t)
     {
         T* record = this, newer = this->newer();
         
@@ -75,6 +76,18 @@ public:
         return record;
     }
 
+    void mark_created(const Transaction& t)
+    {
+        tx.min(t.id);
+        cmd.min(t.cid);
+    }
+
+    void mark_deleted(const Transaction& t)
+    {
+        tx.max(t.id);
+        cmd.max(t.cid);
+    }
+
 protected:
     // known committed and known aborted for both xmax and xmin
     // this hints are used to quickly check the commit/abort status of the
@@ -84,4 +97,6 @@ protected:
     std::atomic<uint8_t> hints;
 };
 
+}
+
 #endif
diff --git a/mvcc/store.hpp b/mvcc/store.hpp
new file mode 100644
index 000000000..8b72d957c
--- /dev/null
+++ b/mvcc/store.hpp
@@ -0,0 +1,85 @@
+#ifndef MEMGRAPH_STORAGE_MVCC_STORE_HPP
+#define MEMGRAPH_STORAGE_MVCC_STORE_HPP
+
+#include <stdexcept>
+
+#include "mvcc/transaction.hpp"
+#include "mvcc/atom.hpp"
+
+#include "data_structures/list/lockfree_list.hpp"
+#include "utils/counters/atomic_counter.hpp"
+
+// some interesting concepts described there, keep in mind for the future
+// Serializable Isolation for Snapshot Databases, J. Cahill, et al.
+
+namespace mvcc
+{
+
+class MvccError : public std::runtime_error
+{
+public:
+    using runtime_error::runtime_error;
+};
+
+template <class T>
+class MvccStore
+{
+    using list_t = lockfree::List<Atom<T>>;
+
+public:
+    using iterator = typename list_t::iterator;
+
+    MvccStore() : counter(0) {}
+
+    iterator insert(const Transaction& t)
+    {
+        auto record = new T();
+
+        record->mark_created(t);
+
+        return data.push_front(Atom<T>(counter.next(), record));
+    }
+
+    T* update(Atom<T>& atom, T& record, const Transaction& t)
+    {
+        auto guard = atom.acquire();
+
+        // if xmax is not zero, that means there is a newer version of this
+        // record or it has been deleted. we cannot do anything here
+        if(record.tx.max())
+            throw MvccError("can't serialize due to concurrent operation(s)");
+
+        // make a new version
+        auto updated = new T();
+        *updated = *record;
+
+        // mark the new version as created
+        updated->mark_created(t);
+
+        // mark the current version as deleted
+        record.mark_deleted(t);
+        record.newer(updated);
+
+        return updated;
+    }
+
+    void remove(Atom<T>& atom, T& record, const Transaction& t)
+    {
+        auto guard = atom.acquire();
+
+        // if xmax is not zero, that means there is a newer version of this
+        // record or it has been deleted. we cannot do anything here
+        if(record.tx.max())
+            throw MvccError("can't serialize due to concurrent operation(s)");
+
+        record.mark_deleted(t);
+    }
+
+private:
+    AtomicCounter<uint64_t> counter;
+    lockfree::List<Atom<T>> data;
+};
+
+}
+
+#endif
diff --git a/transaction/transaction.hpp b/mvcc/transaction.hpp
similarity index 91%
rename from transaction/transaction.hpp
rename to mvcc/transaction.hpp
index 24d814ee4..80a38748c 100644
--- a/transaction/transaction.hpp
+++ b/mvcc/transaction.hpp
@@ -1,11 +1,11 @@
-#ifndef MEMGRAPH_TRANSACTION_TRANSACTION_HPP
-#define MEMGRAPH_TRANSACTION_TRANSACTION_HPP
+#ifndef MEMGRAPH_MVCC_TRANSACTION_HPP
+#define MEMGRAPH_MVCC_TRANSACTION_HPP
 
 #include <cstdlib>
 #include <cstdint>
 #include <vector>
 
-#include "transaction/commit_log.hpp"
+#include "commit_log.hpp"
 
 struct Transaction
 {
diff --git a/transaction/transaction_engine.hpp b/mvcc/transaction_engine.hpp
similarity index 88%
rename from transaction/transaction_engine.hpp
rename to mvcc/transaction_engine.hpp
index caf9a57ba..d6ce74a91 100644
--- a/transaction/transaction_engine.hpp
+++ b/mvcc/transaction_engine.hpp
@@ -1,5 +1,5 @@
-#ifndef MEMGRAPH_TRANSACTION_TRANSACTIONENGINE_HPP
-#define MEMGRAPH_TRANSACTION_TRANSACTIONENGINE_HPP
+#ifndef MEMGRAPH_MVCC_TRANSACTIONENGINE_HPP
+#define MEMGRAPH_MVCC_TRANSACTIONENGINE_HPP
 
 #include <cstdlib>
 #include <atomic>
@@ -12,8 +12,8 @@
 #include "transaction.hpp"
 #include "utils/counters/simple_counter.hpp"
 
-#include "sync/spinlock.hpp"
-#include "sync/lockable.hpp"
+#include "threading/sync/spinlock.hpp"
+#include "threading/sync/lockable.hpp"
 
 class TransactionEngine : Lockable<SpinLock>
 {
@@ -47,7 +47,6 @@ public:
         finalize(t);
     }
 
-    // id of the last finished transaction
     uint64_t last_known_active()
     {
         auto guard = this->acquire();
diff --git a/storage/model/utils/version.hpp b/mvcc/version.hpp
similarity index 88%
rename from storage/model/utils/version.hpp
rename to mvcc/version.hpp
index 36af46039..bbc99a1be 100644
--- a/storage/model/utils/version.hpp
+++ b/mvcc/version.hpp
@@ -1,8 +1,11 @@
-#ifndef MEMGRAPH_STORAGE_MODEL_UTILS_VERSION_HPP
-#define MEMGRAPH_STORAGE_MODEL_UTILS_VERSION_HPP
+#ifndef MEMGRAPH_MVCC_VERSION_HPP
+#define MEMGRAPH_MVCC_VERSION_HPP
 
 #include <atomic>
 
+namespace mvcc
+{
+
 template <class T>
 class Version
 {
@@ -31,4 +34,6 @@ private:
     std::atomic<T*> versions;
 };
 
+}
+
 #endif
diff --git a/server/uv/uvbuffer.inl b/server/uv/uvbuffer.inl
index 95afc3082..2fea17b53 100644
--- a/server/uv/uvbuffer.inl
+++ b/server/uv/uvbuffer.inl
@@ -70,7 +70,11 @@ UvBuffer& UvBuffer::append(const char* data, size_t n)
         buffer.base = static_cast<char*>(realloc(buffer.base, new_size));
     }
 
-    std::memcpy(buffer.base + size(), data, n);
+    auto ptr = buffer.base + size();
+
+    for(size_t i = 0; i < n; ++i, ++ptr, ++data)
+        *ptr = *data;
+
     buffer.len = new_size;
 
     return *this;
diff --git a/storage/model/edge.hpp b/storage/edge.hpp
similarity index 52%
rename from storage/model/edge.hpp
rename to storage/edge.hpp
index 207fceb9d..535be028e 100644
--- a/storage/model/edge.hpp
+++ b/storage/edge.hpp
@@ -1,14 +1,12 @@
-#ifndef MEMGRAPH_DATA_MODEL_EDGE_HPP
-#define MEMGRAPH_DATA_MODEL_EDGE_HPP
+#ifndef MEMGRAPH_STORAGE_EDGE_HPP
+#define MEMGRAPH_STORAGE_EDGE_HPP
 
 #include <vector>
 
-#include "record.hpp"
+#include "model/record.hpp"
 
 struct Vertex;
 
-struct 
-
 struct Edge : public Record<Edge>
 {
     Vertex* from;
diff --git a/storage/graph.hpp b/storage/graph.hpp
new file mode 100644
index 000000000..c0d15acf6
--- /dev/null
+++ b/storage/graph.hpp
@@ -0,0 +1,33 @@
+#ifndef MEMGRAPH_STORAGE_GRAPH_HPP
+#define MEMGRAPH_STORAGE_GRAPH_HPP
+
+#include <list>
+
+#include "mvcc/atom.hpp"
+#include "mvcc/store.hpp"
+
+#include "vertex.hpp"
+#include "edge.hpp"
+
+using VertexStore = mvcc::MvccStore<Vertex>;
+using EdgeStore = mvcc::MvccStore<Edge>;
+
+class Graph
+{
+public:
+    Graph() {}
+
+    EdgeStore::iterator connect(Vertex a, Vertex b, const Transaction& t)
+    {
+         auto it = edges.insert(t);
+
+         it->
+         
+         return it;
+    }
+
+    VertexStore vertices;
+    EdgeStore edges;
+};
+
+#endif
diff --git a/storage/model/graph.hpp b/storage/model/graph.hpp
deleted file mode 100644
index c6ab98ce8..000000000
--- a/storage/model/graph.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef MEMGRAPH_DATA_MODEL_GRAPH_HPP
-#define MEMGRAPH_DATA_MODEL_GRAPH_HPP
-
-#include <list>
-
-#include "vertex.hpp"
-#include "edge.hpp"
-
-class Graph
-{
-
-private:
-    std::list<
-};
-
-#endif
diff --git a/storage/model/properties/properties.hpp b/storage/model/properties/properties.hpp
index 28dfa76ec..1f47178bf 100644
--- a/storage/model/properties/properties.hpp
+++ b/storage/model/properties/properties.hpp
@@ -5,7 +5,7 @@
 
 #include "property.hpp"
 
-namespace props
+namespace model
 {
 
 class Properties
diff --git a/storage/model/properties/property.hpp b/storage/model/properties/property.hpp
index c01d2e282..1da19b419 100644
--- a/storage/model/properties/property.hpp
+++ b/storage/model/properties/property.hpp
@@ -4,7 +4,7 @@
 #include <memory>
 #include <string>
 
-namespace props
+namespace model
 {
 
 class Property
diff --git a/storage/model/properties/string.hpp b/storage/model/properties/string.hpp
index 91787f254..49bb82d50 100644
--- a/storage/model/properties/string.hpp
+++ b/storage/model/properties/string.hpp
@@ -3,7 +3,7 @@
 
 #include "property.hpp"
 
-namespace props
+namespace model
 {
 
 class String : public Value<std::string>
diff --git a/storage/model/record.hpp b/storage/model/record.hpp
index cbf6e43a1..0d4f42d27 100644
--- a/storage/model/record.hpp
+++ b/storage/model/record.hpp
@@ -2,24 +2,27 @@
 #define MEMGRAPH_STORAGE_RECORD_HPP
 
 #include <mutex>
+#include <set>
 
 #include "utils/crtp.hpp"
 
-#include "sync/spinlock.hpp"
-#include "sync/lockable.hpp"
+#include "threading/sync/spinlock.hpp"
 
-#include "storage/model/utils/mvcc.hpp"
+#include "mvcc/mvcc.hpp"
 
 #include "properties/properties.hpp"
 
 template <class Derived>
 class Record
     : public Crtp<Derived>,
-      public Mvcc<Derived>,
-      Lockable<SpinLock>
+      public mvcc::Mvcc<Derived>
 {
 public:
-    Properties props;
+    // a record contains a key value map containing data
+    model::Properties properties;
+    
+    // each record can have one or more distinct labels. 
+    std::set<uint16_t> labels;
 };
 
 #endif
diff --git a/storage/model/root.hpp b/storage/model/root.hpp
deleted file mode 100644
index d52023026..000000000
--- a/storage/model/root.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef MEMGRAPH_STORAGE_MODEL_ROOT_HPP
-#define MEMGRAPH_STORAGE_MODEL_ROOT_HPP
-
-#include "utils/version.hpp"
-
-template <class T>
-class Root : public Version<T>
-{
-public:
-    Root(uint64_t id, T* first)
-        : Version<T>(first), id(id) {}
-
-    // every record has a unique id. 2^64 = 1.8 x 10^19. that should be enough
-    // for a looong time :) but keep in mind that some vacuuming would be nice
-    // to reuse indices for deleted nodes.
-    uint64_t id;
-};
-
-#endif
diff --git a/storage/storage_engine.hpp b/storage/storage_engine.hpp
index 324646869..61d536afa 100644
--- a/storage/storage_engine.hpp
+++ b/storage/storage_engine.hpp
@@ -9,6 +9,8 @@
 #include "memory/memory_engine.hpp"
 #include "utils/counters/atomic_counter.hpp"
 
+#include "storage/model/root.hpp"
+
 class StorageEngine
 {
 public:
diff --git a/storage/model/vertex.hpp b/storage/vertex.hpp
similarity index 58%
rename from storage/model/vertex.hpp
rename to storage/vertex.hpp
index 97bfc9aa8..13e0da874 100644
--- a/storage/model/vertex.hpp
+++ b/storage/vertex.hpp
@@ -1,9 +1,9 @@
-#ifndef MEMGRAPH_STORAGE_MODEL_VERTEX_HPP
-#define MEMGRAPH_STORAGE_MODEL_VERTEX_HPP
+#ifndef MEMGRAPH_STORAGE_VERTEX_HPP
+#define MEMGRAPH_STORAGE_VERTEX_HPP
 
 #include <vector>
 
-#include "record.hpp"
+#include "model/record.hpp"
 #include "edge.hpp"
 
 struct Vertex : public Record<Vertex>
diff --git a/threading/sync/spinlock.hpp b/threading/sync/spinlock.hpp
index bd03b4f07..af218462b 100644
--- a/threading/sync/spinlock.hpp
+++ b/threading/sync/spinlock.hpp
@@ -1,5 +1,5 @@
-#ifndef MEMGRAPH_UTILS_SYNC_SPINLOCK_HPP
-#define MEMGRAPH_UTILS_SYNC_SPINLOCK_HPP
+#ifndef MEMGRAPH_THREADING_SYNC_SPINLOCK_HPP
+#define MEMGRAPH_THREADING_SYNC_SPINLOCK_HPP
 
 #include <atomic>
 #include <unistd.h>
diff --git a/threading/sync/timed_spinlock.hpp b/threading/sync/timed_spinlock.hpp
new file mode 100644
index 000000000..5758843b6
--- /dev/null
+++ b/threading/sync/timed_spinlock.hpp
@@ -0,0 +1,55 @@
+#ifndef MEMGRAPH_THREADING_SYNC_TIMED_SPINLOCK_HPP
+#define MEMGRAPH_THREADING_SYNC_TIMED_SPINLOCK_HPP
+
+#include <atomic>
+#include <chrono>
+#include <stdexcept>
+
+#include <unistd.h>
+
+class LockExpiredError : public std::runtime_error
+{
+    using runtime_error::runtime_error;
+};
+
+class TimedSpinLock
+{
+public:
+    TimedSpinLock(std::chrono::seconds expiration)
+        : expiration(expiration) {}
+
+    TimedSpinLock(std::chrono::milliseconds expiration)
+        : expiration(expiration) {}
+
+    void lock()
+    {
+        using clock = std::chrono::high_resolution_clock;
+
+        auto start = clock::now();
+
+        while(lock_flag.test_and_set(std::memory_order_acquire))
+        {
+            // how long have we been locked? if we exceeded the expiration
+            // time, throw an exception and stop being blocked because this
+            // might be a deadlock!
+
+            if(clock::now() - start > expiration)
+                throw LockExpiredError("This lock has expired");
+
+            usleep(250);
+        }
+    }
+
+    void unlock()
+    {
+        lock_flag.clear(std::memory_order_release);
+    }
+
+private:
+    std::chrono::milliseconds expiration;
+
+    // guaranteed by standard to be lock free!
+    std::atomic_flag lock_flag = ATOMIC_FLAG_INIT;
+};
+
+#endif
diff --git a/utils/buffer.hpp b/utils/buffer.hpp
new file mode 100644
index 000000000..584328100
--- /dev/null
+++ b/utils/buffer.hpp
@@ -0,0 +1,47 @@
+#ifndef MEMGRAPH_UTILS_STRING_BUFFER_HPP
+#define MEMGRAPH_UTILS_STRING_BUFFER_HPP
+
+#include <string>
+
+#include "numerics/ceil.hpp"
+
+class Buffer
+{
+public:
+    Buffer(size_t capacity, size_t chunk_size)
+        : capacity(capacity), chunk_size(chunk_size) {}
+
+    Buffer& append(const std::string& string)
+    {
+        return this->append(string.c_str(), string.size());
+    }
+
+    Buffer& append(const char* string, size_t n)
+    {
+        auto new_size = size() + n;
+
+        if(capacity < new_size)
+        {
+            capacity = new_size;
+            data = static_cast<char*>(realloc(data, new_size));
+        }
+
+        size = new_size;
+    }
+
+    Buffer& operator<<(const std::string& string)
+    {
+
+    }
+
+    size_t size() const
+    {
+        return str.size();
+    }
+
+private:
+    size_t size_, capacity, chunk_size;
+    char* data;
+};
+
+#endif
diff --git a/utils/counters/atomic_counter.hpp b/utils/counters/atomic_counter.hpp
index 4fbba83e5..b4671ac80 100644
--- a/utils/counters/atomic_counter.hpp
+++ b/utils/counters/atomic_counter.hpp
@@ -11,7 +11,7 @@ public:
 
     T next()
     {
-        return counter.fetch_add(1, std::memory_order_relaxed);
+        return counter.fetch_add(1);
     }
 
 private:
diff --git a/utils/memory/atomic_shared_ptr.hpp b/utils/memory/atomic_shared_ptr.hpp
new file mode 100644
index 000000000..441029e6f
--- /dev/null
+++ b/utils/memory/atomic_shared_ptr.hpp
@@ -0,0 +1,29 @@
+#ifndef MEMGRAPH_UTILS_MEMORY_ATOMIC_SHARED_PTR_HPP
+#define MEMGRAPH_UTILS_MEMORY_ATOMIC_SHARED_PTR_HPP
+
+#include <atomic>
+#include <memory>
+
+template<class T>
+class atomic_shared_ptr final
+{
+public:
+    atomic_shared_ptr(std::shared_ptr<T>&& ptr)
+        : ptr(ptr) {}
+
+    std::shared_ptr<T> load()
+    {
+        return std::move(std::atomic_load(&ptr));
+    }
+
+    bool compare_exchange_weak(std::shared_ptr<T>& expected,
+                               std::shared_ptr<T> desired)
+    {
+        return atomic_compare_exchange_weak(&ptr, &expected, desired);
+    }
+
+private:
+    std::shared_ptr<T> ptr;
+};
+
+#endif
diff --git a/utils/numerics/ceil.hpp b/utils/numerics/ceil.hpp
new file mode 100644
index 000000000..959b661e1
--- /dev/null
+++ b/utils/numerics/ceil.hpp
@@ -0,0 +1,21 @@
+#ifndef MEMGRAPH_UTILS_NUMERICS_COMMON_HPP
+#define MEMGRAPH_UTILS_NUMERICS_COMMON_HPP
+
+#include <type_traits>
+
+namespace num
+{
+
+template <class T,
+          typename std::enable_if<std::is_integral<T>::value>::type* = nullptr>
+T iceil(T x, T y)
+{
+    // this may seem inefficient, but on x86_64, when you already perform
+    // division (x / y) the remainder is already computed and therefore x % y
+    // is basically free!
+    return x / y + (x % y != 0);
+}
+
+}
+
+#endif