LevelDB源码剖析之SkipList

来源:互联网 发布:h3c路由器查看端口 编辑:程序博客网 时间:2024/05/17 23:42

SkipList的基本原理及具体实现可参考:http://www.cnblogs.com/xuqiang/archive/2011/05/22/2053516.html(此文中SkipList的实现方式是把多层单链表叠加成一个SkipList链表,SkipList的每个节点中包含一个指向下一个Node的指针数组成员)。如图1:

   

                                                                  图1

另外一种实现方式可见:http://kenby.iteye.com/blog/1187303(这种方式中SkipList实际是由相对独立的多层单链表构成,每层单链表的节点除了有next指针指向自己的后续节点外,还有一个down指针用来指向自己的下一层链表的对应节点,并以此实现各层链表之间的联系。)如图2:



                                                                        图2

尽管具体实现方式不一,但其基本思想是一致的:以空间(增加节点的指针数)换取时间。


LevelDB的SkipList实现采用第一种方式:每个节点包含一个前向指针数组,指向后继节点。   以内部类实现节点和迭代器。空间分配器为Arena



[cpp] view plaincopy
  1. template<typename Key, class Comparator>  
  2. class SkipList {  
  3.  private:  
  4.   struct Node;//链表节点  
  5.   
  6.  public:  
  7.                                                    <span style="font-size: 18px; font-family: Arial, Helvetica, sans-serif;"//构造函数中 构造头节点,并设置头结点的前向指针数组</span>  
[cpp] view plaincopy
  1. explicit SkipList(Comparator cmp, Arena* arena);//在*arena析构时才会释放分配的空间,  
  2.                                                //而*arena作为SkipList的局部变量,因此在SkipList析构时自动析构,释放空间  
  3.   
  4. void Insert(const Key& key);//要求:当前链表中没有与准备插入相等的key  
  5.   
  6. bool Contains(const Key& key) const;//是否包含key的节点  
  7.    
[cpp] view plaincopy
  1.    class Iterator;//迭代器类  
  2.   
  3.  private:  
  4.   enum { kMaxHeight = 12 };  
  5.   
  6.   Comparator const compare_;//比较器  
  7.   Arena* const arena_;    // 空间分配器  
  8.   
  9.   Node* const head_;  //头结点  
  10.   
  11.    
  12.   port::AtomicPointer max_height_;   // 链表节点最大层数  
  13.   
  14.   inline int GetMaxHeight() const {//返回允许最大层数  
  15.     return reinterpret_cast<intptr_t>(max_height_.NoBarrier_Load());  
  16.   }  
  17.   
  18.   
  19.   Random rnd_;//随机数生成器  
  20.   
  21.   Node* NewNode(const Key& key, int height);//产生新节点  
  22.     
  23.   int RandomHeight();//生成随机层数,基数为1,以四分之一概率++  
  24.     
  25.   bool Equal(const Key& a, const Key& b) const { return (compare_(a, b) == 0); }  
  26.   
  27.   bool KeyIsAfterNode(const Key& key, Node* n) const;//key是否比note->key大  
  28.   
  29.   Node* FindGreaterOrEqual(const Key& key, Node** prev) const//查找大等于key的最近值  
  30.   
  31.   Node* FindLessThan(const Key& key) const;//查找小于key的最大节点,没有则返回头节点  
  32.   
  33.   Node* FindLast() const;//返回尾节点  
  34.   
  35.   SkipList(const SkipList&);//禁止拷贝构造或复制操作  
  36.   void operator=(const SkipList&);  
  37. };  

迭代器实现代码:

[cpp] view plaincopy
  1. /****************************************************************/  
  2. //迭代器类  :数据成员 包含一个要操作的SkipList指针,以及一个当前节点note指针  
  3.  class Iterator {  
  4.   public:  
  5.   
  6.    explicit Iterator(const SkipList* list);  
  7.   
  8.    bool Valid() const;//当前节点是否有效  
  9.   
  10.    const Key& key() const;//返回当前节点的key  
  11.   
  12.    void Next();//移动到后继节点  
  13.   
  14.    void Prev();//移动到前一节点(实际是通过查找*list中小于当前key的最大节点)  
  15.   
  16.    void Seek(const Key& target);//移动到第一个大等于target的节点处  
  17.   
  18.    void SeekToFirst();//移动到链表第一个节点(header的next)  
  19.   
  20.    void SeekToLast();//移动到链表尾节点  
  21.   
  22.   private:  
  23.    const SkipList* list_;   //迭代器操作的链表   
  24.    Node* node_;//当前迭代器指向的节点  
  25.  };  
  26.   
  27.  /****************************************************************/<pre name="code" class="cpp">/***********************************************************/  
[cpp] view plaincopy
  1. <span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">  
  2. </span>  
[cpp] view plaincopy
  1. <span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">  
  2. </span>  
[cpp] view plaincopy
  1. <span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">SkipList 方法实现代码:</span>  
[cpp] view plaincopy
  1. template<typename Key, class Comparator>  
  2. typename SkipList<Key,Comparator>::Node*  
  3. SkipList<Key,Comparator>::NewNode(const Key& key, int height) {  
  4.   char* mem = arena_->AllocateAligned(  
  5.       sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));  
  6.   return new (mem) Node(key);//布局new  
  7. }  
  8.   
  9. template<typename Key, class Comparator>  
  10. inline SkipList<Key,Comparator>::Iterator::Iterator(const SkipList* list) {  
  11.   list_ = list;  
  12.   node_ = NULL;  
  13. }  
  14.   
  15. template<typename Key, class Comparator>  
  16. inline bool SkipList<Key,Comparator>::Iterator::Valid() const {  
  17.   return node_ != NULL;  
  18. }  
  19.   
  20. template<typename Key, class Comparator>  
  21. inline const Key& SkipList<Key,Comparator>::Iterator::key() const {  
  22.   assert(Valid());  
  23.   return node_->key;  
  24. }  
  25.   
  26. template<typename Key, class Comparator>  
  27. inline void SkipList<Key,Comparator>::Iterator::Next() {  
  28.   assert(Valid());  
  29.   node_ = node_->Next(0);  
  30. }  
  31.   
  32. template<typename Key, class Comparator>  
  33. inline void SkipList<Key,Comparator>::Iterator::Prev() {  
  34.   
  35.   assert(Valid());  
  36.   node_ = list_->FindLessThan(node_->key);  
  37.   if (node_ == list_->head_) {  
  38.     node_ = NULL;  
  39.   }  
  40. }  
  41.   
  42. template<typename Key, class Comparator>  
  43. inline void SkipList<Key,Comparator>::Iterator::Seek(const Key& target) {  
  44.   node_ = list_->FindGreaterOrEqual(target, NULL);//查找大等于key的最近值  
  45. }  
  46.   
  47. template<typename Key, class Comparator>  
  48. inline void SkipList<Key,Comparator>::Iterator::SeekToFirst() {  
  49.   node_ = list_->head_->Next(0);  
  50. }  
  51.   
  52. template<typename Key, class Comparator>  
  53. inline void SkipList<Key,Comparator>::Iterator::SeekToLast() {  
  54.   node_ = list_->FindLast();  
  55.   if (node_ == list_->head_) {  
  56.     node_ = NULL;  
  57.   }  
  58. }  
  59.   
  60. template<typename Key, class Comparator>  
  61. int SkipList<Key,Comparator>::RandomHeight() {  
  62.   static const unsigned int kBranching = 4;  
  63.   int height = 1;  
  64.   while (height < kMaxHeight && ((rnd_.Next() % kBranching) == 0)) {  
  65.     height++;  
  66.   }  
  67.   assert(height > 0);  
  68.   assert(height <= kMaxHeight);  
  69.   return height;  
  70. }  
  71.   
  72. template<typename Key, class Comparator>  
  73. bool SkipList<Key,Comparator>::KeyIsAfterNode(const Key& key, Node* n) const {  
  74.   return (n != NULL) && (compare_(n->key, key) < 0);  
  75. }  
  76.   
  77. template<typename Key, class Comparator>  
  78. typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindGreaterOrEqual(const Key& key, Node** prev)  
  79.     const {  
  80.   Node* x = head_;  
  81.   int level = GetMaxHeight() - 1;  
  82.   while (true) {  
  83.     Node* next = x->Next(level);  
  84.     if (KeyIsAfterNode(key, next)) {//如果key在该节点的后面  
  85.       x = next;  
  86.     } else {  
  87.       if (prev != NULL) prev[level] = x;//把每层的最后转折节点指针放入prev  
  88.       if (level == 0) {  
  89.         return next;//最后需要返回的值在最底层时返回  
  90.       } else {  
  91.         // Switch to next list  
  92.         level--;  
  93.       }  
  94.     }  
  95.   }  
  96. }  
  97.   
  98. template<typename Key, class Comparator>  
  99. typename SkipList<Key,Comparator>::Node*  
  100. SkipList<Key,Comparator>::FindLessThan(const Key& key) const {  
  101.   Node* x = head_;  
  102.   int level = GetMaxHeight() - 1;  
  103.   while (true) {  
  104.     assert(x == head_ || compare_(x->key, key) < 0);  
  105.     Node* next = x->Next(level);  
  106.     if (next == NULL || compare_(next->key, key) >= 0) {  
  107.       if (level == 0) {  
  108.         return x;  
  109.       } else {  
  110.         // Switch to next list  
  111.         level--;  
  112.       }  
  113.     } else {  
  114.       x = next;  
  115.     }  
  116.   }  
  117. }  
  118.   
  119. template<typename Key, class Comparator>  
  120. typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindLast()  
  121.     const {  
  122.   Node* x = head_;  
  123.   int level = GetMaxHeight() - 1;  
  124.   while (true) {  
  125.     Node* next = x->Next(level);  
  126.     if (next == NULL) {  
  127.       if (level == 0) {  
  128.         return x;  
  129.       } else {  
  130.         // Switch to next list  
  131.         level--;  
  132.       }  
  133.     } else {  
  134.       x = next;  
  135.     }  
  136.   }  
  137. }  
  138.   
  139. template<typename Key, class Comparator>  
  140. SkipList<Key,Comparator>::SkipList(Comparator cmp, Arena* arena)  
  141.     : compare_(cmp),  
  142.       arena_(arena),  
  143.       head_(NewNode(0 /* any key will do */, kMaxHeight)),  
  144.       max_height_(reinterpret_cast<void*>(1)),  
  145.       rnd_(0xdeadbeef) {  
  146.   for (int i = 0; i < kMaxHeight; i++) {  
  147.     head_->SetNext(i, NULL);  
  148.   }  
  149. }  
  150.   
  151. template<typename Key, class Comparator>  
  152. void SkipList<Key,Comparator>::Insert(const Key& key) {  
  153.   Node* prev[kMaxHeight];//前向指针数组  max_height_:当前最大层数  
  154.   Node* x = FindGreaterOrEqual(key, prev);  
  155.   
  156.   // 不允许重复插入  
  157.   assert(x == NULL || !Equal(key, x->key));  
  158.   
  159.   int height = RandomHeight();//随机产生插入节点的层数  
  160.   if (height > GetMaxHeight()) {//插入节点层数大于允许的最大层数,把新节点的新增前向指针指向头结点  
  161.     for (int i = GetMaxHeight(); i < height; i++) {   
  162.       prev[i] = head_;  
  163.     }  
  164.    
  165.     max_height_.NoBarrier_Store(reinterpret_cast<void*>(height));  
  166.   }  
  167.   
  168.   x = NewNode(key, height);  
  169.   for (int i = 0; i < height; i++) {  
  170.     x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));  
  171.     prev[i]->SetNext(i, x);  
  172.   }  
  173. }  
  174.   
  175.   
  176. template<typename Key, class Comparator>  
  177. bool SkipList<Key,Comparator>::Contains(const Key& key) const {  
  178.   Node* x = FindGreaterOrEqual(key, NULL);  
  179.   if (x != NULL && Equal(key, x->key)) {  
  180.     return true;  
  181.   } else {  
  182.     return false;  
  183.   }  
  184. }  
  185.   
  186. }  
0 0
原创粉丝点击