skiplist.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include"basical/type_checking.h"
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<exception>
  5. #include<random>
  6. namespace nanxing_extend
  7. {
  8. //错误处理机制
  9. class nextpoint_new:std::exception //skip_node分配空间失败的时候
  10. {
  11. const char* what() const noexcept
  12. {
  13. return "malloc next_node point fault";
  14. }
  15. };
  16. class newNode_error:std::exception //申请新的空间的时候
  17. {
  18. const char* what() const noexcept
  19. {
  20. return "malloc new node error";
  21. }
  22. };
  23. class random_error:std::exception //申请预设随机数空间的时候
  24. {
  25. const char* what() const noexcept
  26. {
  27. return "malloc random space error";
  28. }
  29. };
  30. enum class Skip_result //跳表操作的结果
  31. {
  32. successufl,
  33. fault,
  34. full
  35. };
  36. template<typename V>
  37. union skiplistre
  38. {
  39. V value,
  40. Skip_result result
  41. };
  42. //注意这里的V只能是要么是能直接深拷贝的类型,要么是指向堆上数据的指针类型
  43. template<typename K,typename V>
  44. struct skip_node
  45. {
  46. static_assert(nanxing_extend::compare_admit<K>value);
  47. static_assert(nanxing_extend::compare_admit<V>value);
  48. skip_node<K,V>** next_node;
  49. V value;
  50. private:
  51. K key;
  52. int level;
  53. public:
  54. skip_node(){};
  55. skip_node(K _key,V _value,int _level):key(_key),value(_value),level(_level){};
  56. init_next(int level)
  57. {
  58. try
  59. {
  60. next_node=::new (skip_node<K,V>*)[level];
  61. }
  62. catch(std::bad_alloc){ //捕获内存分配错误
  63. throw nextpoint_new(); //重新抛出一个定制的更详细的类型用以明确错误的具体位置
  64. }
  65. std::memset(next_node,0,sizeof(skip_node<K,V>*)*level);
  66. }
  67. K get_key(){ return key; }
  68. };
  69. template<typename K,typename V>
  70. class skipList
  71. {
  72. static_assert(nanxing_extend::compare_admit<K>value);
  73. static_assert(nanxing_extend::compare_admit<V>value);
  74. private:
  75. using Node=skip_node<K,V>;
  76. using ptr=Node*;
  77. using Nptr=Node**;
  78. //由于C++的便利性我们考虑使用带头节点的跳表(C++允许对数据不进行初始化(默认构造函数))
  79. Nptr head; //头节点
  80. int max_level; //最大高度
  81. int* random_level;
  82. int current_level; //跳表当前高度
  83. int current_size; //跳表当前尺寸
  84. //这里出于一个考虑,当跳表单纯作为小数据内存数据库,单表大小限制是没有意义的
  85. //但是像level_db这样作为KV数据库的缓存的时候,就需要限制大小进行落盘
  86. #ifdef SKIP_MAX_SIZE
  87. int max_size; //跳表允许的最大尺寸
  88. #endif
  89. public:
  90. #ifndef SKIP_MAX_SIZE
  91. skipList(int _max_level):max_level(_max_level),random_level(nullptr)
  92. {
  93. try
  94. {
  95. Node* middle=::new skip_node;
  96. middle->init_next(max_level);
  97. head=::new (Node*)[max_level];
  98. for(auto& i in head)
  99. {
  100. i=middle;
  101. }
  102. }
  103. catch(std::bad_alloc)
  104. {
  105. throw newNode_error();
  106. }
  107. }
  108. #elif
  109. skipList(int _max_level,int _max_size):max_size(_max_size),max_level(_max_level),random_level(nullptr)
  110. {
  111. try
  112. {
  113. Node* middle=::new skip_node;
  114. middle->init_next(max_level);
  115. head=::new (Node*)[max_level];
  116. for(auto& i in head)
  117. {
  118. i=middle;
  119. }
  120. }
  121. catch(std::bad_alloc)
  122. {
  123. throw newNode_error();
  124. }
  125. }
  126. #endif
  127. [[nodiscard]] //这个返回值最好不要忽略否则很有可能会出现内存泄漏
  128. skiplistre<V> insert(K _key,V _value) //如果相同的时候我们考虑将value返回因为value很可能会是一个指针,需要手动清空内存
  129. {
  130. int rand_level=0;
  131. ptr updata[max_level]={nullptr}; //用于更新的数组
  132. int level=current_level-1;
  133. ptr point=head[level];
  134. skiplistre<V> sk;
  135. ptr new_node;
  136. for(int i=level;i>=0;i--)
  137. {
  138. for(;;)
  139. {
  140. if(point->next_node[level]==nullptr)
  141. {
  142. updata[level]=point;
  143. break;
  144. }
  145. else if(point->next_node[level]->key>=_key)
  146. {
  147. if(point->next_node[level]->key==_key)
  148. {
  149. sk.value=std::move(point->next_node[level]->value); //这个值已经不需要了,直接移动
  150. point->next_node[level]->value=_value;
  151. return sk;
  152. }
  153. else
  154. {
  155. updata[level]=point;
  156. break;
  157. }
  158. else{
  159. point=point->head[level]; //更新point指针
  160. }
  161. }
  162. }
  163. [[likely]]
  164. if(random_level!=nullptr)
  165. {
  166. rand_level=random_level[current_size%1024];
  167. new_node=new skip_node(_key,_value,rand_level);
  168. }
  169. [[unlikely]]
  170. else
  171. {
  172. rand_level=std::rand(chrono::system_clock::now().time_since_epoch().count())%(1+max_level);
  173. new_node=new skip_node(_key,_value,rand_level);
  174. }
  175. ptr tmp=nullptr;
  176. for(int i=0;i<=rand_level;i++)
  177. {
  178. tmp=updata[i]->next_node[i];
  179. updata[i]->next_node[i]=new_node;
  180. new_node->next_node[i]=tmp;
  181. }
  182. if(rand_level>current_level)
  183. {
  184. current_level=rand_level;
  185. }
  186. current_size++;
  187. #ifdef SKIP_MAX_SIZE
  188. return sk.result=Skip_result::full;
  189. #endif
  190. }
  191. sk.Skip_result=Skip_result::successufl;
  192. }
  193. [[nodiscard]]
  194. skiplistre<V> search(K _key) noexcept //不涉及任何内存分配相关任务,因此是异常安全的
  195. {
  196. skipList<V> sk;
  197. ptr tmp=head[current_level-1];
  198. int tmp_level=current_level-1;
  199. for(i=tmp_level;i>=0;i--)
  200. {
  201. while(tmp->next_node[tmp_level]!=nullptr)
  202. {
  203. if(tmp->next_node[tmp_level]->key>=_key)
  204. {
  205. if(tmp->next_node[tmp_level]->key==_key)
  206. {
  207. return sk.result=tmp->next_node[tmp_level]->key;
  208. }
  209. else{
  210. break; //跳出开始下一层循环
  211. }
  212. }
  213. else{
  214. tmp=tmp->next_node[tmp_level];
  215. }
  216. }
  217. }
  218. return sk.result=Skip_result::fault;
  219. }
  220. void init_skip() //直接生成随机数表
  221. {
  222. try{
  223. random_level=new int[1024]; //刚好是一页的大小(4KB)
  224. }
  225. catch(std::bad_alloc)
  226. {
  227. throw random_error();
  228. }
  229. std::mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
  230. for(auto& i :random_level)
  231. {
  232. i=(rnd()%max_level)+1;
  233. }
  234. }
  235. };
  236. }