From a4cadedffe798e2aebba50d8e4d56442e2570759 Mon Sep 17 00:00:00 2001
From: Marko Budiselic <mbudiselicbuda@gmail.com>
Date: Sun, 5 Jun 2016 12:12:25 +0200
Subject: [PATCH] more appropriate test for storage/indexes/index.hpp (very
 beginning of indexes work); utils/type_discovery.hpp is created

---
 README.md                     |   2 +
 src/storage/indexes/index.hpp |  27 +++++++--
 src/utils/type_discovery.hpp  | 100 ++++++++++++++++++++++++++++++++++
 tests/db_index.cpp            |  23 +++++++-
 4 files changed, 146 insertions(+), 6 deletions(-)
 create mode 100644 src/utils/type_discovery.hpp

diff --git a/README.md b/README.md
index 0a01bd535..aa02a42cd 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,8 @@ on a 64 bit linux kernel.
 cd build
 cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
 make
+ctest
 ctest -V
+ctest -R test_name
 ```
 
diff --git a/src/storage/indexes/index.hpp b/src/storage/indexes/index.hpp
index fbc6229f1..acb038552 100644
--- a/src/storage/indexes/index.hpp
+++ b/src/storage/indexes/index.hpp
@@ -8,22 +8,41 @@
 template <class Key, class Item>
 class Index
 {
+public:
     using skiplist_t = SkipList<Key, Item*>;
     using iterator_t = typename skiplist_t::Iterator;
     using accessor_t = typename skiplist_t::Accessor;
     using K = typename Key::key_t;
-
     using cursor_t = Cursor<accessor_t, iterator_t, K>;
 
-public:
-    cursor_t insert(const K& key, Item* item, tx::Transaction& t)
+    // cursor_t insert(const K& key, Item* item, tx::Transaction& t)
+    auto insert(const K& key, Item* item)
     {
+        // Item has to be some kind of container for the real data like Vertex,
+        // the container has to be transactionally aware
+        // in other words index or something that wraps index has to be
+        // transactionally aware
+
         auto accessor = skiplist.access();
         auto result = accessor.insert_unique(key, item);
 
-        // todo handle existing insert
+        // TODO: handle existing insert
+
+        return result;
     }
 
+    auto remove(const K& key)
+    {
+        auto accessor = skiplist.access();
+        return accessor.remove(key);
+    }
+
+    auto find(const K& key)
+    {
+        auto accessor = skiplist.access();
+        return accessor.find(key);
+    }
+    
 private:
     skiplist_t skiplist;
 };
diff --git a/src/utils/type_discovery.hpp b/src/utils/type_discovery.hpp
new file mode 100644
index 000000000..9d49a2665
--- /dev/null
+++ b/src/utils/type_discovery.hpp
@@ -0,0 +1,100 @@
+#pragma once
+
+// USAGE:
+//     type_name<decltype<variable>>();
+// current solution has been taken from http://stackoverflow.com/questions/81870/is-it-possible-to-print-a-variables-type-in-standard-c
+// TODO: create more appropriate solution
+
+#include <cstddef>
+#include <stdexcept>
+#include <cstring>
+#include <ostream>
+
+#ifndef _MSC_VER
+#  if __cplusplus < 201103
+#    define CONSTEXPR11_TN
+#    define CONSTEXPR14_TN
+#    define NOEXCEPT_TN
+#  elif __cplusplus < 201402
+#    define CONSTEXPR11_TN constexpr
+#    define CONSTEXPR14_TN
+#    define NOEXCEPT_TN noexcept
+#  else
+#    define CONSTEXPR11_TN constexpr
+#    define CONSTEXPR14_TN constexpr
+#    define NOEXCEPT_TN noexcept
+#  endif
+#else  // _MSC_VER
+#  if _MSC_VER < 1900
+#    define CONSTEXPR11_TN
+#    define CONSTEXPR14_TN
+#    define NOEXCEPT_TN
+#  elif _MSC_VER < 2000
+#    define CONSTEXPR11_TN constexpr
+#    define CONSTEXPR14_TN
+#    define NOEXCEPT_TN noexcept
+#  else
+#    define CONSTEXPR11_TN constexpr
+#    define CONSTEXPR14_TN constexpr
+#    define NOEXCEPT_TN noexcept
+#  endif
+#endif  // _MSC_VER
+
+class static_string
+{
+    const char* const p_;
+    const std::size_t sz_;
+
+public:
+    typedef const char* const_iterator;
+
+    template <std::size_t N>
+    CONSTEXPR11_TN static_string(const char(&a)[N]) NOEXCEPT_TN
+        : p_(a)
+        , sz_(N-1)
+        {}
+
+    CONSTEXPR11_TN static_string(const char* p, std::size_t N) NOEXCEPT_TN
+        : p_(p)
+        , sz_(N)
+        {}
+
+    CONSTEXPR11_TN const char* data() const NOEXCEPT_TN {return p_;}
+    CONSTEXPR11_TN std::size_t size() const NOEXCEPT_TN {return sz_;}
+
+    CONSTEXPR11_TN const_iterator begin() const NOEXCEPT_TN {return p_;}
+    CONSTEXPR11_TN const_iterator end()   const NOEXCEPT_TN {return p_ + sz_;}
+
+    CONSTEXPR11_TN char operator[](std::size_t n) const
+    {
+        return n < sz_ ? p_[n] : throw std::out_of_range("static_string");
+    }
+};
+
+inline
+std::ostream&
+operator<<(std::ostream& os, static_string const& s)
+{
+    return os.write(s.data(), s.size());
+}
+
+template <class T>
+CONSTEXPR14_TN
+static_string
+type_name()
+{
+#ifdef __clang__
+    static_string p = __PRETTY_FUNCTION__;
+    return static_string(p.data() + 31, p.size() - 31 - 1);
+#elif defined(__GNUC__)
+    static_string p = __PRETTY_FUNCTION__;
+#  if __cplusplus < 201402
+    return static_string(p.data() + 36, p.size() - 36 - 1);
+#  else
+    return static_string(p.data() + 46, p.size() - 46 - 1);
+#  endif
+#elif defined(_MSC_VER)
+    static_string p = __FUNCSIG__;
+    return static_string(p.data() + 38, p.size() - 38 - 7);
+#endif
+}
diff --git a/tests/db_index.cpp b/tests/db_index.cpp
index 60680c353..568ef642c 100644
--- a/tests/db_index.cpp
+++ b/tests/db_index.cpp
@@ -1,16 +1,35 @@
 #include <iostream>
+#include <utility>
 
 #include "storage/indexes/index.hpp"
 
+// boilerplate
 using std::cout;
 using std::endl;
 
-using StringUniqueKeyAsc = UniqueKeyAsc<std::string>;
+// types
+using StringUniqueKeyAsc = UniqueKeyAsc<std::shared_ptr<std::string>>;
+using index_t = Index<StringUniqueKeyAsc, std::string>;
 
 int main(void)
 {
     // index creation
-    auto index = std::make_shared<Index<StringUniqueKeyAsc, std::string>>();
+    auto index = std::make_shared<index_t>();
+
+    // prepare values
+    StringUniqueKeyAsc key(std::make_shared<std::string>("test_key"));
+    auto value_ptr = std::make_shared<std::string>("test_value");
+
+    // insert into and unpack pair
+    index_t::skiplist_t::Iterator find_iterator;
+    bool insertion_succeeded;
+    std::tie(find_iterator, insertion_succeeded) = 
+        index->insert(key, value_ptr.get());
+    assert(insertion_succeeded == true);
+    
+    // get inserted value
+    auto inserted_value = *index->find(key);
+    assert(*inserted_value.second == *value_ptr);
 
     return 0;
 }