#ifndef _SKIPLIST_H
#define _SKIPLIST_H
#include <iostream>
#include<atomic>
#define DEBUG 1
namespace microdb
{
template<typename Key>
class SkipList
{
public:
static const unsigned int MAXLEVEL = 4;
class Node
{
public:
explicit Node(const Key& key);
bool setNext(Node* expected, Node* node, unsigned int level);
void setNextWithoutAtomic(Node* node, unsigned int level);
Node* getNext(unsigned int level);
const Key& key() const;
private:
Key key_;
std::atomic<Node*> next_[MAXLEVEL];
};
class Iterator
{
public:
Iterator();
explicit Iterator(Node* node);
Iterator next(unsigned int level);
Node* operator->();
Node& operator*();
bool operator==(Iterator& itr) const;
bool operator!=(Iterator& itr) const;
const Key& key() const;
Node* node() const;
private:
Node* node_;
};
explicit SkipList(const Key& key);
void put(const Key& key);
bool get(const Key& key);
void remove(const Key& key);
void print();
Iterator& begin();
Iterator& end();
#if DEBUG
struct _debug_counter
{
std::atomic<unsigned int> inserted_counter;
std::atomic<unsigned int> not_inserted_counter;
std::atomic<unsigned int> in_list_counter;
}debug_counter;
void inListCount();
#endif
private:
int random();
SkipList<Key>::Iterator lowerBound(const Key& key, unsigned int level);
SkipList<Key>::Iterator upperBound(const Key& key, unsigned int level);
Node* head_;
Iterator begin_;
Iterator end_;
};
template<typename Key>
SkipList<Key>::N