上QQ阅读APP看书,第一时间看更新
2.4 迭代器接口
在许多编程语言中均有迭代器(Iterator)接口,通过该迭代器,设计人员只需要调用相应的接口,就可以实现对容器数据类型的遍历访问。LevelDB采用C++开发,同样具有相应的迭代器遍历功能。本节将介绍LevelDB中迭代器接口的具体实现方法。
与2.3节中介绍的Comparator一样,迭代器也定义了一个纯虚类的接口,LevelDB中的任何集合类型对象的迭代器均基于这一纯虚类进行实现。具体代码如下:
class Iterator{ public: Iterator(); virtual ~Iterator(); virtual bool Valid() const = 0; virtual void SeekToFirst() = 0; virtual void SeekToLast() = 0; virtual void Seek(const Slice& target) = 0; virtual void Next() = 0; virtual void Prev() = 0; virtual Slice key() const = 0; virtual Slice value() const = 0; virtual Status status() const = 0; typedef void (*CleanupFunction)(void* arg1, void* arg2); void RegisterCleanup(CleanupFunction, void* arg1, void* arg2); private: struct Cleanup { CleanupFunction function; void* arg1; void* arg2; Cleanup* next; }; Cleanup cleanup_; }
这些接口函数的具体作用参见表2-2。从表2-2中可以看出,LevelDB中定义的迭代器不仅支持直接对集合中的首元素和末尾元素进行访问,如SeekToFirst和SeekToLast,还可以根据实际的key进行元素的定位,如Seek(target)。此外,一般的迭代器支持正向迭代,而LevelDB中的迭代器对象不仅支持正向迭代Next(),还支持反向迭代Prev(),可见其迭代器的功能还是相当强大的。
表2-2 迭代器的主要接口描述
值得注意的是,Iterator中定义了一个名为Cleanup的结构体,该结构体主要由相应的函数指针与两个参数构成,并且Cleanup中包含一个next指针,从而可以定义一条Cleanup链表。而Iterator中唯一的非虚函数RegisterCleanup则用于注册相对应的回收函数,并将之保存到cleanup_这一变量中。最终Iterator析构函数会遍历cleanup_中所有的节点,并调用相对应的函数,实现迭代器相关资源的释放与清除。