123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- #include"basical/type_checking.h"
- #include<cstdlib>
- #include<cstring>
- #include<exception>
- #include<random>
- namespace nanxing_extend
- {
- //错误处理机制
- class nextpoint_new:std::exception //skip_node分配空间失败的时候
- {
- const char* what() const noexcept
- {
- return "malloc next_node point fault";
- }
- };
-
- class newNode_error:std::exception //申请新的空间的时候
- {
- const char* what() const noexcept
- {
- return "malloc new node error";
- }
- };
- class random_error:std::exception //申请预设随机数空间的时候
- {
- const char* what() const noexcept
- {
- return "malloc random space error";
- }
- };
-
-
- enum class Skip_result //跳表操作的结果
- {
- successufl,
- fault,
- full
- };
- template<typename V>
- union skiplistre
- {
- V value,
- Skip_result result
- };
-
- //注意这里的V只能是要么是能直接深拷贝的类型,要么是指向堆上数据的指针类型
- template<typename K,typename V>
- struct skip_node
- {
- static_assert(nanxing_extend::compare_admit<K>value);
- static_assert(nanxing_extend::compare_admit<V>value);
- skip_node<K,V>** next_node;
- V value;
- private:
- K key;
- int level;
-
- public:
-
- skip_node(){};
- skip_node(K _key,V _value,int _level):key(_key),value(_value),level(_level){};
- init_next(int level)
- {
- try
- {
- next_node=::new (skip_node<K,V>*)[level];
- }
- catch(std::bad_alloc){ //捕获内存分配错误
- throw nextpoint_new(); //重新抛出一个定制的更详细的类型用以明确错误的具体位置
- }
- std::memset(next_node,0,sizeof(skip_node<K,V>*)*level);
- }
- K get_key(){ return key; }
- };
- template<typename K,typename V>
- class skipList
- {
- static_assert(nanxing_extend::compare_admit<K>value);
- static_assert(nanxing_extend::compare_admit<V>value);
- private:
- using Node=skip_node<K,V>;
- using Nptr=Node**;
- //由于C++的便利性我们考虑使用带头节点的跳表(C++允许对数据不进行初始化(默认构造函数))
- Nptr head; //头节点
- int max_level; //最大高度
- int* random_level;
- int current_level; //跳表当前高度
- int current_size; //跳表当前尺寸
- //这里出于一个考虑,当跳表单纯作为小数据内存数据库,单表大小限制是没有意义的
- //但是像level_db这样作为KV数据库的缓存的时候,就需要限制大小进行落盘
- #ifdef SKIP_MAX_SIZE
- int max_size; //跳表允许的最大尺寸
- #endif
- public:
- #ifndef SKIP_MAX_SIZE
- skipList(int _max_level):max_level(_max_level),random_level(nullptr)
- {
- try
- {
- Node* middle=::new skip_node;
- middle->init_next(max_level);
- head=::new (Node*)[max_level];
- for(auto& i in head)
- {
- i=middle;
- }
- }
- catch(std::bad_alloc)
- {
- throw newNode_error();
- }
- }
- #elif
- skipList(int _max_level,int _max_size):max_size(_max_size),max_level(_max_level),random_level(nullptr)
- {
- try
- {
- Node* middle=::new skip_node;
- middle->init_next(max_level);
- head=::new (Node*)[max_level];
- for(auto& i in head)
- {
- i=middle;
- }
- }
- catch(std::bad_alloc)
- {
- throw newNode_error();
- }
- }
- #endif
- [[nodiscard]] //这个返回值最好不要忽略否则很有可能会出现内存泄漏
- skiplistre<V> insert(K _key,V _value) //如果相同的时候我们考虑将value返回因为value很可能会是一个指针,需要手动清空内存
- {
- using ptr=Node*;
- int rand_level=0;
- ptr updata[max_level]={nullptr}; //用于更新的数组
- int level=current_level-1;
- ptr point=head[level];
- skiplistre<V> sk;
- ptr new_node;
- for(int i=level;i>=0;i--)
- {
- for(;;)
- {
- if(point->next_node[level]==nullptr)
- {
- updata[level]=point;
- break;
- }
- else if(point->next_node[level]->key>=_key)
- {
- if(point->next_node[level]->key==_key)
- {
-
- sk.value=std::move(point->next_node[level]->value); //这个值已经不需要了,直接移动
- point->next_node[level]->value=_value;
- return sk;
- }
- else
- {
- updata[level]=point;
- break;
- }
- else{
- point=point->head[level]; //更新point指针
- }
- }
- }
- [[likely]]
- if(random_level!=nullptr)
- {
- rand_level=random_level[current_size%1024];
- new_node=new skip_node(_key,_value,rand_level);
- }
- [[unlikely]]
- else
- {
- rand_level=std::rand(chrono::system_clock::now().time_since_epoch().count())%(1+max_level);
- new_node=new skip_node(_key,_value,rand_level);
- }
- ptr tmp=nullptr;
- for(int i=0;i<=level;i++)
- {
- tmp=updata[i]->next_node[i];
- updata[i]->next_node[i]=new_node;
- new_node->next_node[i]=tmp;
- }
- }
- sk.Skip_result=Skip_result::successufl;
- }
-
- skiplistre<V> search(K _key)
- {
- }
- void init_skip() //直接生成随机数表
- {
- try{
- random_level=new int[1024]; //刚好是一页的大小(4KB)
- }
- catch(std::bad_alloc)
- {
- throw random_error();
- }
- std::mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
- for(auto& i :random_level)
- {
- i=(rnd()%max_level)+1;
- }
- }
- };
-
- }
|