[leveldb] 2-SkipList 跳表数据结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/simonyucsdy/article/details/79618538

leveldb中对SkipList的处理方式简单易操作,主要接口包括构造、插入和判断key值是否存在SkipList中

public:
      // Create a new SkipList object that will use "cmp" for comparing keys,  
      // and will allocate memory using "*arena".  Objects allocated in the arena  
      // must remain allocated for the lifetime of the skiplist object.  
      explicit SkipList(Comparator cmp, Arena* arena);  //Arena
      
      // Insert key into the list.  
      // REQUIRES: nothing that compares equal to key is currently in the list.  
      void Insert(const Key& key);  
      
      // Returns true iff an entry that compares equal to key is in the list.  
      bool Contains(const Key& key) const  

1.构造函数

    template<typedef Key, class Comparator>
    SkipList<Key,Comparator>::SkipList(Comparator cmp, Arena* arena)  
        : compare_(cmp),  
          arena_(arena),  
          head_(NewNode(0 /* any key will do */, kMaxHeight)),  
          max_height_(reinterpret_cast<void*>(1)),  
          rnd_(0xdeadbeef) {  
      for (int i = 0; i < kMaxHeight; i++) {  
        head_->SetNext(i, NULL);  
      }  
    }  

头结点成员head_的初始化利用到了NewNode方法,返回一个新的节点数组,height为深度

template<typename Key, class Comparator>  
typename SkipList<Key,Comparator>::Node*  
SkipList<Key,Comparator>::NewNode(const Key& key, int height) {  
  char* mem = arena_->AllocateAligned(  
      sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));  
  return new (mem) Node(key);  
}//节点的next中存放了一位数据,所以新建node只要height-1的数据长度

2.插入函数

template<typename Key, class Comparator>
void SkipList<Key,Comparator>::Insert(const Key& key) {
  // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()
  // here since Insert() is externally synchronized.
  Node* prev[kMaxHeight];    //prev是长度为kMaxHeight的Node节点数组,存放的数据为每层比key
值小的最大数据(即找到比key大或者相等的节点后,前一个节点即为要找的节点),直到寻找到最低等级的list
为止。
  Node* x = FindGreaterOrEqual(key, prev);  //实现插入功能

  // Our data structure does not allow duplicate insertion
  assert(x == NULL || !Equal(key, x->key)); //x中不允许有重复的元素

  int height = RandomHeight();    //随机产生要插入的list所处的深度
  if (height > GetMaxHeight()) {  //如果深度大于最大的分级,则每一个级别中prev数组都先插入
头节点
    for (int i = GetMaxHeight(); i < height; i++) {
      prev[i] = head_;
    }

    //fprintf(stderr, "Change height from %d to %d\n", max_height_, height);

    // It is ok to mutate max_height_ without any synchronization
    // with concurrent readers.  A concurrent reader that observes
    // the new value of max_height_ will see either the old value of
    // new level pointers from head_ (NULL), or a new value set in
    // the loop below.  In the former case the reader will
    // immediately drop to the next level since NULL sorts after all
    // keys.  In the latter case the reader will use the new node.
    max_height_.NoBarrier_Store(reinterpret_cast<void*>(height));
  }

  x = NewNode(key, height);
  for (int i = 0; i < height; i++) {
    // NoBarrier_SetNext() suffices since we will add a barrier when
    // we publish a pointer to "x" in prev[i].
    x->NoBarrier_SetNext(i, prev[i]->NoBarrier_Next(i));
    prev[i]->SetNext(i, x);
  }
}

其中用到了FindGreaterOrEqual方法,返回节点数组,,

template<typename Key, class Comparator>
typename SkipList<Key,Comparator>::Node* SkipList<Key,Comparator>::FindGreaterOrEqual
  (const Key& key, Node** prev) const 
{   //返回一个节点数组,prev是数组的数组,存放的是每层的
  Node* x = head_;        //x是跳表类的成员头节点,
  int level = GetMaxHeight() - 1;  //level等级,等于最大的深度减一
  while (true) 
  {
    Node* next = x->Next(level);   //???
    if (KeyIsAfterNode(key, next)) //判断key是否大于next中的所有key值,即暂时没找到大于等于
key的节点,继续在list中搜索。
    {
      // Keep searching in this list
      x = next;
    } 
    else 
    {
      if (prev != NULL) prev[level] = x;  //
      if (level == 0) 
      {
        return next;    //搜索到最低等级list,返回节点数组。
      } 
      else 
      {
        // Switch to next list
        level--;    //跳转到更低等级list继续处理。
      }
    }
  }
}

3 Contains函数

template<typename Key, class Comparator>
bool SkipList<Key,Comparator>::Contains(const Key& key) const {
  Node* x = FindGreaterOrEqual(key, NULL);
  if (x != NULL && Equal(key, x->key)) {
    return true;
  } else {
    return false;
  }
}

节点数组x,如果不为空切key值等于参数key,则返回true。

猜你喜欢

转载自blog.csdn.net/simonyucsdy/article/details/79618538