MemTableIterator·
读这篇文章前,请先阅读 skiplist实现和memtable两篇文章。
MemTableIteraotr是用来遍历MemTable的Iterator。
1. 基本定义·
下面是它的代码,代码很短:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class MemTableIterator : public Iterator { public : explicit MemTableIterator (MemTable::Table* table) : iter_(table) { } MemTableIterator (const MemTableIterator&) = delete ; MemTableIterator& operator =(const MemTableIterator&) = delete ; ~MemTableIterator () override = default ; bool Valid () const override { return iter_.Valid (); } void Seek (const Slice& k) override { iter_.Seek (EncodeKey (&tmp_, k)); } void SeekToFirst () override { iter_.SeekToFirst (); } void SeekToLast () override { iter_.SeekToLast (); } void Next () override { iter_.Next (); } void Prev () override { iter_.Prev (); } Slice key () const override { return GetLengthPrefixedSlice (iter_.key ()); } Slice value () const override { Slice key_slice = GetLengthPrefixedSlice (iter_.key ()); return GetLengthPrefixedSlice (key_slice.data () + key_slice.size ()); } Status status () const override { return Status::OK (); } private : MemTable::Table::Iterator iter_; std::string tmp_; };
可以看到,MemTableIterator是对MemTable::Table::Iterator的简单封装,也就是说,真正的iterator是MemTable::Table::Iterator,
MemTable::Table其实是SkipList的别名,所以最终就是对SkipList的Iterator的封装。所以要求对MemTable的SkipList实现有所了解。
虽然MemTableIterator只是对SkipList的Iter的薄薄封装,但这里有两个地方特殊,那就是key和value。
如果你之前阅读了本系列的ksiplist文章, 那应该知道skiplist中只有key没有value, key里面存放的东西就是本文开篇中给出的图。它既包含了key也包含了value。下图是iter中的key的布局:
2. key·
1 2 3 4 5 6 7 8 Slice key () const override { return GetLengthPrefixedSlice (iter_.key ()); } static Slice GetLengthPrefixedSlice (const char * data) { uint32_t len; const char * p = data; p = GetVarint32Ptr (p, p + 5 , &len); return Slice (p, len); }
先获取internal key 的长度,然后得到Internal key。
3. value·
1 2 3 4 Slice value () const override { Slice key_slice = GetLengthPrefixedSlice (iter_.key ()); return GetLengthPrefixedSlice (key_slice.data () + key_slice.size ()); }
获取internal key后,给第二个GetLengthPrefixedSlice传入的参数
1 key_slice.data () + key_slice.size ()
是value size字段的首地址,所以这里返回的是实际的value。
到这里我们可以补充一条内容,MemTable中存放的key是整个MemTable key(包括internel key size 和 internal key), 但是对外部呈现的却是一个internal key。