如何通过使用迭代器跳过一些键?

时间:2019-06-06 12:45:24

标签: leveldb rocksdb lsm-tree

作为一个例子,我已经向DB添加了几个键,就像

<1 + 2> 
<1 + 3>
<2 + 1>
<2 + 4>
<3 + 2>

首先从Seek()到<1,2>,然后从Next()到<1,3> 之后,我想跳过键<2,1>和<2,4>(其前缀均为2),并将迭代器移至<3,2>,而无需执行新的seek操作。 由于Seek()非常昂贵,因此无法使用新的Seek()操作。 我应该使用哪种方法?

此跳过扫描方法类似于this

我更喜欢像下面的几行进行编程:

DBIter* it = NewDBIterator(...);
set = {key1, key2, key3, ...};
Iterator key_iter = set.begin();
for (it->SeekToFirst(); it->Valid() && key_iter != set.end(); it->SkipToNext(*key_iter), ++ key_iter) {
  // do something
}

1 个答案:

答案 0 :(得分:0)

如文章中所述,您通过在键是按顺序存储的前提下查看键前缀来链接跳过扫描。如果您正在寻找 第二个关键部分中小于3的任何值:

1,2
1,3
1,4
2,1
2,2
2,3
...

当您达到1,3时,您所知道的是将不再有与您的谓词匹配的键前缀为1的键,因此您可以跳到下一个键前缀。这通常仍然意味着您必须至少在寻找下一个前缀或以某种方式查找它的方式上查看每个键前缀。这是否好看。对于对一组不同的键进行的操作,通常可以肯定,单独查找通常是更好的选择,因为除非您非常清楚自己的数据看起来像什么,否则您就不知道必须前缀扫描的键数,并且可能来查看每一个(O(n)),其中k次查找仅花费O(k)* O(log(n))时间。因此只要k << n,就一定可以进行查找。您正在讨论的优化适用于键的谓词,否则您将不得不针对表中的每个键评估谓词。因此,在那种情况下,跳过键是一种优化,因为您必须减少对谓词的评估,而不必进行廉价的谓词比较。