版权声明:本文为博主原创文章,未经博主允许不得转载。 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。