线程安全的skiplist,lockfree,CAS,c11版

#ifndef _SKIPLIST_H
#define _SKIPLIST_H

#include 
#include

#define DEBUG 1

namespace microdb
{

template
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 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 inserted_counter;
		std::atomic not_inserted_counter;
		std::atomic in_list_counter;
	}debug_counter;

	void inListCount();
#endif
private:
	int random();
 	SkipList::Iterator lowerBound(const Key& key, unsigned int level);
	SkipList::Iterator upperBound(const Key& key, unsigned int level);

	Node* head_;
	Iterator begin_;
	Iterator end_;
};

template
SkipList::Node::Node(const Key& key)
{
	key_ = key;
	for (auto i = 0; i < MAXLEVEL; ++i)
	{
		next_[i] = nullptr;
	}
}

template
bool SkipList::Node::setNext(Node* expected, Node* node, unsigned int level)
{
	return next_[level].compare_exchange_strong(expected, node, std::memory_order_seq_cst, std::memory_order_seq_cst);
	//while (true)
//	{
//		if (next_[level].compare_exchange_strong(expected, node, std::memory_order_seq_cst, std::memory_order_seq_cst))
//		{
//			return;
//		}
//		else
//		{
//			std::cout<<"Update failed!"<
void SkipList::Node::setNextWithoutAtomic(Node* node, unsigned int level)
{
        next_[level].store(node);
}

template
typename SkipList::Node* SkipList::Node::getNext(unsigned int level)
{
	return next_[level].load(std::memory_order_seq_cst);
}

template
const Key& SkipList::Node::key() const
{
	return key_;
}

template
SkipList::Iterator::Iterator(Node* node)
{
	node_ = node; 
}

template
SkipList::Iterator::Iterator()
{
        node_ = nullptr;
}

template
typename SkipList::Iterator SkipList::Iterator::next(unsigned int level)
{
	Iterator tmp(node_);
	if (tmp.node_)
	{
		tmp.node_ = tmp.node_->getNext(level);
	}
	return tmp;
}

template
typename SkipList::Node* SkipList::Iterator::operator->()
{
	return node_;
}

template
typename SkipList::Node& SkipList::Iterator::operator*()
{
	return *node_;
}

template
bool SkipList::Iterator::operator==(Iterator& itr) const
{
	return (node_ == itr.node_);
}

template
bool SkipList::Iterator::operator!=(Iterator& itr) const
{
	return (node_ != itr.node_);
}

template
const Key& SkipList::Iterator::key() const
{
	return node_->key();
}

template
typename SkipList::Node* SkipList::Iterator::node() const
{
	return node_;
}

template
typename SkipList::Iterator& SkipList::begin()
{
	return begin_;
}

template
typename SkipList::Iterator& SkipList::end()
{
	return end_;
}

#if DEBUG
template
void SkipList::inListCount()
{
	for (auto itr = begin().next(0); itr != end(); itr = itr.next(0))
	{
		++debug_counter.in_list_counter;
	}	
}
#endif

template
int SkipList::random()
{
	return rand() % MAXLEVEL;
}

template
SkipList::SkipList(const Key& key)
{
	head_ = new Node(key);
	begin_ = Iterator(head_);
	end_ = Iterator(nullptr);
#if DEBUG
	debug_counter.inserted_counter = 0;
	debug_counter.not_inserted_counter = 0;
	debug_counter.in_list_counter = 0;
#endif
}

template
typename SkipList::Iterator SkipList::lowerBound(const Key& key, unsigned int level)
{
	auto itr = begin();
	for (itr = begin().next(level); itr != end() && key > itr->key(); itr = itr.next(level))
	{
		
	}
	return itr;
}

template
typename SkipList::Iterator SkipList::upperBound(const Key& key, unsigned int level)
{
	auto last_itr = begin();
        for (auto itr = begin().next(level); itr != end() && key > itr->key(); itr = itr.next(level))
        {
		last_itr = itr;
        }
	return last_itr;
}

template
void SkipList::put(const Key& key)
{
	int level = random();
	SkipList::Iterator pre;
	SkipList::Iterator next;
	Node* new_node = new Node(key);
	for (auto i = level; i >= 0; --i)
	{
		while (true)
		{
			pre = upperBound(key, i);
			next = pre.next(i);
			if (next != end())
			{
				if (next->key() == key)
				{
	#if DEBUG
					++debug_counter.not_inserted_counter;
	#endif
					//std::cout<<"The key has existed! "<setNextWithoutAtomic(next.node(), i);
			auto tmp = next.node();
			if (pre->setNext(tmp, new_node, i))
			{
				break;
			}
		}
	}
#if DEBUG
	++debug_counter.inserted_counter;
#endif
}

template
void SkipList::print()
{
	std::cout<<"################## Print my Skiplist ##################"<key()<<" ";	
		}
		std::cout<


#include "skiplist.h"
#include 
#include 

int main()
{
	microdb::SkipList skiplist(0);
	std::thread threads[10000];
	timeval start, end;
	gettimeofday(&start, NULL); 
	for (auto i = 0; i < 10000; ++i)
        {
                threads[i] = std::thread(std::mem_fn(µdb::SkipList::put), &skiplist, i);
        }

        for (auto i = 0; i < 10000; ++i)
        {
                threads[i].join();
        }
        gettimeofday(&end, NULL);
        unsigned long time = 1000000L * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);
        std::cout<<"Total insert time "<


你可能感兴趣的:(源码剖析)