123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- #ifndef _SKIPLISTS_H_
- #define _SKIPLISTS_H_
- #include<ostream>
- #include<cstdlib>
- #include<type_traits>
- #include<shared_mutex>
- #include<mutex>
- #include<cstring>
- #include<random>
- #include<chrono>
- #include<optional>
- #include"nanxing_memory.h"
- namespace nanxing
- {
- template<typename K,typename V=int>
- struct SkiplistNode
- {
-
- private:
- K key;
- V Value;
- public:
- using deep_point=SkiplistNode**;
- explicit SkiplistNode(){}
- SkiplistNode(K _k,V _v,int _deep):key(_k),Value(_v),deep_level(_deep)
- {
- forward= new SkiplistNode*[deep_level+1];
- std::memset(forward,0,sizeof(SkiplistNode*)*(deep_level+1));
- }
- ~SkiplistNode()
- {
-
- delete[] forward;
- }
- [[nodiscard]]
- V get_value()const{return Value;};
- [[nodiscard]]
- K get_key()const{return key;}
- void set_value(V _v){Value=_v;}
- [[nodiscard]]
- V reset_value(V _v){Value=_v;}
-
- deep_point forward;
- int deep_level;
- };
- template<typename K,typename V,typename alloc=nanxing::allocator<SkiplistNode<K,V>>>
- class Skiplists
- {
- public:
- using Node=SkiplistNode<K,V>;
- Skiplists(int _max_level):Creater(),max_level(_max_level){
- current_level=0;
- Node_count=0;
- K key;
- V value;
- head=(this->Creater.allocate(sizeof(SkiplistNode<K,V>)));
- Creater.construct(head,key,value,_max_level);
- for(int i=0;i<10000;i++)
- {
- random_map[i]=get_random();
- }
- }
- [[nodiscard]]
- SkiplistNode<K,V>* creat_node(K key,V value,int level)
- {
- SkiplistNode<K,V>* tmp=static_cast<SkiplistNode<K,V>*>(Creater.allocate(sizeof(SkiplistNode<K,V>(key,value,level)))) ;
- Creater.construct(tmp,key,value,level);
- return tmp;
- }
- int List_size(){return {Node_count};}
- [[nodiscard]]
- int insert_Node(K key,V value)
- {
- #ifdef _THREAD_
- std::unique_lock<std::shared_mutex>lk{RWmutex};
- #endif
- Node* tmp=this->head;
- Node* updata[max_level]={0};
-
- for(int i= current_level;i>=0;i--)
- {
- while(tmp->forward[i]!=nullptr&&tmp->forward[i]->get_key()<key)
- {
-
- tmp=tmp->forward[i];
-
-
- }
- updata[i]=tmp;
- }
- tmp=tmp->forward[0];
- if(tmp!=nullptr&&tmp->get_key()==key)
- {
- return 2;
- }
- else
- {
- int _node_level=random_map[random_point%10000];
- random_point++;
-
- if(_node_level>current_level)
- {
- for(int i=_node_level+1;i>=current_level+1;i--)
- {
- updata[i]=head;
- }
- current_level=_node_level;
- }
- Node* _insert=creat_node(key,value,_node_level);
- for(int i=0;i<=_node_level;i++)
- {
- _insert->forward[i]=updata[i]->forward[i];
- updata[i]->forward[i]=_insert;
- }
- Node_count++;
- return 1;
- }
-
-
- return -1;
- }
- int insert_Node(SkiplistNode<K,V>* _insert)
- {
- #ifdef _THREAD_
- RWmutex.lock();
- #endif
- K key=_insert->get_key();
- Node* tmp=this->head;
- Node* updata[max_level]={0};
-
- for(int i= current_level;i>=0;i--)
- {
- while(tmp->forward[i]!=nullptr&&tmp->forward[i]->get_key()<key)
- {
- tmp=tmp->forward[i];
- }
- updata[i]=tmp;
- }
- tmp=tmp->forward[0];
- if(tmp!=nullptr&&tmp->get_key()==key)
- {
- #ifdef _THREAD_
- RWmutex.unlock();
- #endif
- return 2;
- }
- else
- {
- int _node_level=_insert->deep_level;
- if(_node_level>current_level)
- {
- for(int i=_node_level+1;i>current_level+1;i--)
- {
- updata[i]=head;
- }
- }
- for(int i=0;i<=_node_level;i++)
- {
- _insert->forward[i]=updata[i]->forward[i];
- updata[i]->forward[i]=_insert;
- }
- Node_count++;
- #ifdef _THREAD_
- RWmutex.unlock();
- #endif
- return 1;
- }
- #ifdef _THREAD_
- RWmutex.unlock();
- #endif
- return -1;
- #ifdef _THREAD_
- RWmutex.unlock();
- #endif
- }
- bool search_Node(K key)
- {
- #ifdef _THREAD_
- RWmutex.lock_shared();
- #endif
- using Node=SkiplistNode<K,V>;
- Node* tmp=head;
- for(int i=current_level;i>=0;i--)
- {
- while(tmp->forward[i]!=nullptr&&tmp->forward[i]->get_key()<key)
- {
- tmp=tmp->forward[i];
- }
- }
- tmp=tmp->forward[0];
- if(tmp!=nullptr&&tmp->get_key()==key)
- {
- return true;
- }
- else
- {
- return false;
- }
- #ifdef _THREAD_
- RWmutex.unlock_shared();
- #endif
- }
- std::optional<V> get_value_from_key(K key)
- {
- #ifdef _THREAD_
- RWmutex.lock_shared();
- #endif
- using Node=SkiplistNode<K,V>;
- std::optional<V> opt;
- Node* tmp=head;
- for(int i=current_level;i>=0;i--)
- {
- while(tmp->forward[i]!=nullptr&&tmp->forward[i]->get_key()<key)
- {
- tmp=tmp->forward[i];
- }
- }
- tmp=tmp->forward[0];
- if(tmp!=nullptr&&tmp->get_key()==key)
- {
- opt=tmp->get_value();
- }
- else
- {
- opt = std::nullopt;
- }
- return opt;
- #ifdef _THREAD_
- RWmutex.unlock_shared();
- #endif
- }
- int delete_Node(K key)
- {
- #ifdef _THREAD_
- RWmutex.lock();
- #endif
- using Node=SkiplistNode<K,V>;
- Node* updata[current_level]={nullptr};
-
- Node* tmp=head;
- for(int i=current_level;i>=0;i++)
- {
- while(tmp->forward[i]!=nullptr&&tmp->forward[i]->get_key()<key)
- {
- tmp=tmp->forward[i];
- }
- updata[i]=tmp;
- }
- tmp=tmp->forward[0];
- if(tmp!=nullptr&&tmp->get_key()==key)
- {
- Node* deletes=tmp;
- for(int i=0;i<current_level;i++)
- {
- if(updata[i]->forward[i]!=key)
- {
- break;
- }
- updata->forward[i]=tmp->forward[i];
- }
- Creater.destory(deletes);
- Creater.deallocate(deletes);
- return 1;
- }
- else
- {
- return 0;
- }
- return -1;
-
- #ifdef _THREAD_
- RWmutex.unlock();
- #endif
- }
- void Print_basic()
- {
- using Node=SkiplistNode<K,V>;
- Node* tmp=head;
- if(tmp->forward[0]!=nullptr)
- {
- tmp =tmp ->forward[0];
- std::cout<<"("<<tmp->get_key()<<","<<tmp->get_value()<<")";
- }
- while(tmp->forward[0]!=nullptr)
- {
- tmp=tmp->forward[0];
- std::cout<<"->"<<"("<<tmp->get_key()<<","<<tmp->get_value()<<")";
-
- }
- std::cout<<std::endl;
- }
- private:
- int get_random()
- {
-
- auto now = std::chrono::system_clock::now();
-
- auto duration_since_epoch = now.time_since_epoch();
-
- unsigned long seed = std::chrono::duration_cast<std::chrono::nanoseconds>(duration_since_epoch).count();
-
-
- std::mt19937 rng(seed);
-
-
- std::uniform_int_distribution<int> dist(0, max_level);
-
-
- return dist(rng);
-
-
- }
- private:
- int max_level;
- int current_level;
- #ifdef _THREAD_
- std::shared_mutex RWmutex;
- #endif
- alloc Creater;
- SkiplistNode<K,V>* head;
- int Node_count;
- int random_map[10000]={0};
- int random_point=0;
- };
- }
- #endif
|