当前位置:首页 > 芯闻号 > 充电吧
[导读]阅读本文可参考: LevelDB源码分析之一:coding LevelDB源码分析之二:comparator LevelDB源码分析之三:arena LevelDB源码分析之四:AtomicPoint

阅读本文可参考:

LevelDB源码分析之一:coding

LevelDB源码分析之二:comparator

LevelDB源码分析之三:arena

LevelDB源码分析之四:AtomicPointer

LevelDb源码分析之五:skiplist(1)

LevelDB源码分析之七:Random

LevelDB中的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);

  // 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
private成员变量:

private:
  enum { kMaxHeight = 12 };

  // Immutable after construction
  Comparator const compare_;
  Arena* const arena_;    // Arena used for allocations of nodes

  Node* const head_;

  // Modified only by Insert().  Read racily by readers, but stale
  // values are ok.
  port::AtomicPointer max_height_;   

  // Read/written only by Insert().
  Random rnd_;
一.构造函数
template
SkipList::SkipList(Comparator cmp, Arena* arena)
    : compare_(cmp),
      arena_(arena),
      head_(NewNode(0 /* any key will do */, kMaxHeight)),
      max_height_(reinterpret_cast(1)),
      rnd_(0xdeadbeef) {
  for (int i = 0; i < kMaxHeight; i++) {
    head_->SetNext(i, NULL);
  }
}
重点注意下head_和rnd_的初始化,NewNode方法如下。
template
typename SkipList::Node*
SkipList::NewNode(const Key& key, int height) {
  char* mem = arena_->AllocateAligned(
      sizeof(Node) + sizeof(port::AtomicPointer) * (height - 1));
  return new (mem) Node(key);
}
这里为什么是“height-1”详见:LevelDb源码分析之五:skiplist(1)。

new (mem) Node(key)使用了placement new技巧,详见:C++中使用placement new

rnd_是一个Random类型的变量,使用0xdeadbeef进行初始化,Random详见LevelDB源码分析之七:Random

二.插入函数

template
void SkipList::Insert(const Key& key) {
  // TODO(opt): We can use a barrier-free variant of FindGreaterOrEqual()
  // here since Insert() is externally synchronized.
  // prev记录的是查询路径,下面需要使用prev来修改新生成结点的指针  
  // prev相当于LevelDb源码分析之五:skiplist(1)中的update
  // 整个流程与LevelDb源码分析之五:skiplist(1)相似,这里不再详细解释
  Node* prev[kMaxHeight];
  // 返回大于等于key的结点或者NULL,原因详见FindGreaterOrEqual的分析
  Node* x = FindGreaterOrEqual(key, prev);

  // Our data structure does not allow duplicate insertion
  // 不允许插入重复的值  
  assert(x == NULL || !Equal(key, x->key));
  // 产生一个随机层数height
  int height = RandomHeight();
  // 如果height大于原最大层数,则更新prev,并更新最大层数
  if (height > GetMaxHeight()) {
    for (int i = GetMaxHeight(); i < height; i++) {
      prev[i] = head_;
    }
    //fprintf(stderr, "Change height from %d to %dn", 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(height));
  }
  // 创建一个待插入的结点x,从低到高一层层插入
  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。FindGreaterOrEqual中完成查询操作,就是向下(level控制)和向右(x控制)移动过程,并不断将经过路径保存到参数prev中。

template
typename SkipList::Node* SkipList::FindGreaterOrEqual(const Key& key, Node** prev)
    const {
  Node* x = head_;
  int level = GetMaxHeight() - 1;
  // 从最高层往下,每层都查找插入位置,当遍历到该层的尾部(x->next[level]==NULL)  
  // 也没有找到比key大的结点时,将该层的最后一个结点的指针放到prev[level]中。  
  // 如果在某层中找到了比key大或等于key的结点时,将该结点之前的那个比key小的结点的指针  
  // 放到prev[level]中。  
  while (true) {
    Node* next = x->Next(level);
    if (KeyIsAfterNode(key, next)) {
      // Keep searching in this list
      x = next;
    } else {
      if (prev != NULL) prev[level] = x;
	  // 当查到第一层时,有两种情况:
	  // 1.第一层中有满足要求的结点,此时next刚好是不小于key的那个结点
	  // 2.第一层中没有满足要求的结点,此时实际上到了尾部,next=NULL
      if (level == 0) {
        return next;
      } else {
        // Switch to next list
        level--;
      }
    }
  }
}
三.查找函数

查找操作基本上就是调用函数上面的函数FindGreaterOrEqual实现。

template
bool SkipList::Contains(const Key& key) const {
  Node* x = FindGreaterOrEqual(key, NULL);
  if (x != NULL && Equal(key, x->key)) {
    return true;
  } else {
    return false;
  }
}
需要注意的是,LevelDB中没有提供显式的删除节点操作,但实际上是可以删除的,因为当我们插入数据时,key的形式为key:value,当删除数据时,则插入key:deleted类似删除的标记,等到Compaction再删除。

参考链接:http://blog.csdn.net/xuqianghit/article/details/6948554













本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

May 20, 2024 ---- 据TrendForce集邦咨询研究,三大原厂开始提高先进制程的投片,继存储器合约价翻扬后,公司资金投入开始增加,产能提升将集中在今年下半年,预期1alpha nm(含)以上投片至年底将...

关键字: 晶圆 HBM 存储器

2024年5月18日,强国机械制造有限公司正式宣布,全力支持国家提出的“中国制造2050”战略。公司将把智能制造作为未来发展的核心方向,致力于在这一领域实现重大突破,提升中国制造业的全球竞争力。

关键字: 智能制造 物联网

每次与老友见面时总是免不了谈论以前美好的回忆,但时间渐长,我们的记忆也渐渐模糊,还有电子设备帮助我们留下痕迹,只是翻找起来有些许麻烦。不过我们倒是没有这样的困扰,那是因为我有铁威马NAS,无论什么时间的照片都能放在nas...

关键字: 数据中心 数据存储

合肥2024年5月18日 /美通社/ -- 5月17日,以"致新世界"为主题,国轩高科第13届科技大会在包河总部隆重启幕,瞄准用户最为关切的高安全性、长续航、快速充电等核心需求和痛点问题,重磅发布三大...

关键字: 国轩高科 快充 电芯 能量密度

上海2024年5月19日 /美通社/ -- 5月18日,一年一度佳通商用车胎产品日如期而至。结合新市场、新机遇、新挑战,佳通轮胎召开"数智赋能 佳境无限"为主题的2024年度商用车胎技术暨产品发布会,...

关键字: 轮胎 数字化 零部件 TPMS

NRT14 于 2025 年底竣工后,园区容量将提高到104 兆瓦, 以满足日本对下一代基础设施和无缝接入互联数据社区日益增长的需求 北京2024年5月20日 /美通社/ -- 世界领先的...

关键字: DIGITAL 人工智能 数字化 数据中心

北京2024年5月20日 /美通社/ -- 过去五年里,支付和收款方式日新月异,其发展和变化比过去五十年都要迅猛。从嵌入式数字商务的出现,到"一拍即付"的...

关键字: VI BSP PAY COM

杭州2024年5月20日 /美通社/ -- 5月20日,百世供应链旗下百世云仓在2024年全国网络大会上,宣布了其全面出海战略。聚焦于东南亚市场的新机遇,并积极推动品牌走向国际市场。 百世供应链召开2024年百世云仓全...

关键字: 供应链 网络 触点 软件

上海2024年5月20日 /美通社/ -- 仲夏伊始,光芒新生,5月17日,由上海工业商务展览有限公司主办的、以"拥抱新质生产力,助力新型工业化"为主题的第九届广东国际机器人及智能装备博览会(以下简称...

关键字: IAR 机器人 自动化 RS

开幕在即!SEMI-e第六届深圳国际半导体展将在深圳国际会展中心(宝安)4/6/8号馆拉开精彩帷幕!

关键字: 半导体
关闭
关闭