[施工中] levelDB 代码阅读笔记 06 iterator
Overview
接口
一个ABC,后面会继承这个类做各种实现
clean up function
代码比较好懂,唯一让我感到疑惑的是 clean up function 这部分
1
2 // FIXME: 不太理解为什么需要很多个clean up function
3 // Cleanup functions are stored in a single-linked list.
4 // The list's head node is inlined in the iterator.
5 struct CleanupNode {
6 // True if the node is not used. Only head nodes might be unused.
7 bool IsEmpty() const { return function == nullptr; }
8 // Invokes the cleanup function.
9 void Run() {
10 assert(function != nullptr);
11 (*function)(arg1, arg2);
12 }
13
14 // The head node is used if the function pointer is not null.
15 CleanupFunction function;
16 void* arg1;
17 void* arg2;
18 CleanupNode* next;
19 };
20 CleanupNode cleanup_head_;
21};
22
从 table/iterator.cc 的析构函数中,可以看到在iterator析构的时候会依次调用多个clean up function
1
2Iterator::~Iterator() {
3 if (!cleanup_head_.IsEmpty()) {
4 cleanup_head_.Run();
5 for (CleanupNode* node = cleanup_head_.next; node != nullptr;) {
6 node->Run();
7 CleanupNode* next_node = node->next;
8 delete node;
9 node = next_node;
10 }
11 }
12}
13
clean up funtion可以通过调用注册函数添加到列表里
1
2void Iterator::RegisterCleanup(CleanupFunction func, void* arg1, void* arg2) {
3 assert(func != nullptr);
4 CleanupNode* node;
5 if (cleanup_head_.IsEmpty()) {
6 node = &cleanup_head_;
7 } else {
8 // 头插法。 新的node插在了clean_head后面
9 node = new CleanupNode();
10 node->next = cleanup_head_.next;
11 cleanup_head_.next = node;
12 }
13 node->function = func;
14 node->arg1 = arg1;
15 node->arg2 = arg2;
16}
17
18
这里有两部分让人不懂
Info
- 为什么需要多个clean up function?
- clean up funtion的参数是在注册时就唯一确定了,而不是在调用时。 clean up function究竟是在清理什么?
带着这些疑问,继续往下读
iteratorWrapper
这里包了一层,目的是把key()和valid()的结果cache住,节省了依次取地址的开销
带来的代价就是,对于会影响key()和valid()结果的operation,需要额外的update操作,变得更重了。
猜测是有某些频繁读key()和valid()的场景,因此做了这样一个trade-off
1
2
3// A internal wrapper class with an interface similar to Iterator that
4// caches the valid() and key() results for an underlying iterator.
5// This can help avoid virtual function calls and also gives better
6// cache locality.
7class IteratorWrapper {
8 public:
9 IteratorWrapper() : iter_(nullptr), valid_(false) {}
10 explicit IteratorWrapper(Iterator* iter) : iter_(nullptr) { Set(iter); }
11 ~IteratorWrapper() { delete iter_; }
12 Iterator* iter() const { return iter_; }
13
14 // Takes ownership of "iter" and will delete it when destroyed, or
15 // when Set() is invoked again.
16 void Set(Iterator* iter) {
17 delete iter_;
18 iter_ = iter;
19 if (iter_ == nullptr) {
20 valid_ = false;
21 } else {
22 Update();
23 }
24 }
25
26 // Iterator interface methods
27 bool Valid() const { return valid_; }
28 Slice key() const {
29 assert(Valid());
30 return key_;
31 }
32 Slice value() const {
33 assert(Valid());
34 return iter_->value();
35 }
36 // Methods below require iter() != nullptr
37 Status status() const {
38 assert(iter_);
39 return iter_->status();
40 }
41 void Next() {
42 assert(iter_);
43 iter_->Next();
44 Update();
45 }
46 void Prev() {
47 assert(iter_);
48 iter_->Prev();
49 Update();
50 }
51 void Seek(const Slice& k) {
52 assert(iter_);
53 iter_->Seek(k);
54 Update();
55 }
56 void SeekToFirst() {
57 assert(iter_);
58 iter_->SeekToFirst();
59 Update();
60 }
61 void SeekToLast() {
62 assert(iter_);
63 iter_->SeekToLast();
64 Update();
65 }
66
67 private:
68 void Update() {
69 valid_ = iter_->Valid();
70 if (valid_) {
71 key_ = iter_->key();
72 }
73 }
74
75 Iterator* iter_;
76 bool valid_;
77 Slice key_;
78};
79
two level iterator
一个二级迭代器 第一层为index iterator, index iterator对应的value是一个data block, 对应date iterator
比较重要的是这个函数,每到一个新的index位置,会用来生成下一级的第一个data iterator
data_block_handle_ 可以理解成对data block的一个标识,避免重复初始化这个data block的data iterator
1
2// note: 每次InitDataBlock是可能改变成员变量data_iter_的值的
3void TwoLevelIterator::InitDataBlock() {
4 if (!index_iter_.Valid()) {
5 SetDataIterator(nullptr);
6 } else {
7 Slice handle = index_iter_.value();
8 if (data_iter_.iter() != nullptr &&
9 handle.compare(data_block_handle_) == 0) {
10 // data_iter_ is already constructed with this iterator, so
11 // no need to change anything
12 } else {
13 Iterator* iter = (*block_function_)(arg_, options_, handle);
14 data_block_handle_.assign(handle.data(), handle.size());
15 // note: data iterator是由block function创建出来的
16 SetDataIterator(iter);
17 }
18 }
19}
Posts in this Series
- [施工中] levelDB 代码阅读笔记 06 iterator
- levelDB 代码阅读笔记 05 arena
- levelDB 代码阅读笔记 04 filter
- levelDB 代码阅读笔记 03 cache
- levelDB 代码阅读笔记 02 comparator
- levelDB 代码阅读笔记 01 db.h
- murmurhash源码分析
- 内存屏障(Memory Barriers)
- 文本相似度判断-simhash算法学习笔记