线程安全的skiplist,lockfree,CAS,c11版
来源:互联网 发布:美国gdp数据公布时间 编辑:程序博客网 时间:2024/05/16 14:17
#ifndef _SKIPLIST_H#define _SKIPLIST_H#include <iostream>#include<atomic>#define DEBUG 1namespace 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 DEBUGstruct _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();#endifprivate: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>::Node::Node(const Key& key){key_ = key;for (auto i = 0; i < MAXLEVEL; ++i){next_[i] = nullptr;}}template<typename Key>bool SkipList<Key>::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!"<<std::endl;//}//}}template<typename Key>void SkipList<Key>::Node::setNextWithoutAtomic(Node* node, unsigned int level){ next_[level].store(node);}template<typename Key>typename SkipList<Key>::Node* SkipList<Key>::Node::getNext(unsigned int level){return next_[level].load(std::memory_order_seq_cst);}template<typename Key>const Key& SkipList<Key>::Node::key() const{return key_;}template<typename Key>SkipList<Key>::Iterator::Iterator(Node* node){node_ = node; }template<typename Key>SkipList<Key>::Iterator::Iterator(){ node_ = nullptr;}template<typename Key>typename SkipList<Key>::Iterator SkipList<Key>::Iterator::next(unsigned int level){Iterator tmp(node_);if (tmp.node_){tmp.node_ = tmp.node_->getNext(level);}return tmp;}template<typename Key>typename SkipList<Key>::Node* SkipList<Key>::Iterator::operator->(){return node_;}template<typename Key>typename SkipList<Key>::Node& SkipList<Key>::Iterator::operator*(){return *node_;}template<typename Key>bool SkipList<Key>::Iterator::operator==(Iterator& itr) const{return (node_ == itr.node_);}template<typename Key>bool SkipList<Key>::Iterator::operator!=(Iterator& itr) const{return (node_ != itr.node_);}template<typename Key>const Key& SkipList<Key>::Iterator::key() const{return node_->key();}template<typename Key>typename SkipList<Key>::Node* SkipList<Key>::Iterator::node() const{return node_;}template<typename Key>typename SkipList<Key>::Iterator& SkipList<Key>::begin(){return begin_;}template<typename Key>typename SkipList<Key>::Iterator& SkipList<Key>::end(){return end_;}#if DEBUGtemplate<typename Key>void SkipList<Key>::inListCount(){for (auto itr = begin().next(0); itr != end(); itr = itr.next(0)){++debug_counter.in_list_counter;}}#endiftemplate<typename Key>int SkipList<Key>::random(){return rand() % MAXLEVEL;}template<typename Key>SkipList<Key>::SkipList(const Key& key){head_ = new Node(key);begin_ = Iterator(head_);end_ = Iterator(nullptr);#if DEBUGdebug_counter.inserted_counter = 0;debug_counter.not_inserted_counter = 0;debug_counter.in_list_counter = 0;#endif}template<typename Key>typename SkipList<Key>::Iterator SkipList<Key>::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 Key>typename SkipList<Key>::Iterator SkipList<Key>::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<typename Key>void SkipList<Key>::put(const Key& key){int level = random();SkipList<Key>::Iterator pre;SkipList<Key>::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! "<<key<<" Just return"<<std::endl;delete new_node;return;}}new_node->setNextWithoutAtomic(next.node(), i);auto tmp = next.node();if (pre->setNext(tmp, new_node, i)){break;}}}#if DEBUG++debug_counter.inserted_counter;#endif}template<typename Key>void SkipList<Key>::print(){std::cout<<"################## Print my Skiplist ##################"<<std::endl;for (auto i = 0; i < MAXLEVEL; ++i){std::cout<<"Level "<<i<<" :"<<std::endl;for (auto itr = begin().next(i); itr != end(); itr = itr.next(i)){std::cout<<itr->key()<<" ";}std::cout<<std::endl;}std::cout<<"########## Print my Skiplist, it is the end ##########"<<std::endl;}} // namespace microdb#endif // _SKIPLIST_H
#include "skiplist.h"#include <sys/time.h>#include <thread>int main(){microdb::SkipList<int> 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<int>::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 "<<time<<std::endl;#if DEBUGskiplist.inListCount();std::cout<<"Inserted "<<skiplist.debug_counter.inserted_counter<<" and not inserted "<<skiplist.debug_counter.not_inserted_counter<<" and total "<<skiplist.debug_counter.inserted_counter + skiplist.debug_counter.not_inserted_counter<<" and in list "<<skiplist.debug_counter.in_list_counter<<std::endl;#endifreturn 0;}
阅读全文
1 0
- 线程安全的skiplist,lockfree,CAS,c11版
- CAS lockfree 循环队列
- CAS lockfree 循环队列
- C11、线程池的使用
- MemoryPool的LockFree实现
- MemoryPool的LockFree实现
- MemoryPool的LockFree实现
- lockfree 的队列的实现
- 实现一个lockfree 的队列
- 有关c11的functional
- C11的标准特性
- 利用CAS算法实现通用线程安全状态机
- atomic工作原理 使用CAS实现线程安全
- c11
- c11
- .NET的代码访问安全(CAS)机制
- .NET的代码访问安全(CAS)机制
- 多线程安全CAS实现的无锁
- Fragment onActivityResult 收不到
- AngularJS 路由及传值功能
- PopupWindow全屏显示
- Android读取内存中的文件返回一个byte数组
- 怎样防止ios系统被抓包
- 线程安全的skiplist,lockfree,CAS,c11版
- unity中的.asset
- HDU 1503 Advanced Fruits 最长公共子串应用(LCS算法应用)
- Python基础知识点
- Android Monkey参数说明
- svn提交格式
- 华为手机onActivityResult()方法不执行问题
- 哈夫曼树构造规则
- Golang从入门到精通(六):Golang控制语句之for