日期:2014-05-16 浏览次数:20519 次
Iterator* NewIterator(const ReadOptions&options) const; { return NewTwoLevelIterator( rep_->index_block->NewIterator(rep_->options.comparator), &Table::BlockReader,const_cast<Table*>(this), options); } // 函数NewTwoLevelIterator创建了一个TwoLevelIterator对象: Iterator* NewTwoLevelIterator( Iterator* index_iter,BlockFunction block_function, void* arg, constReadOptions& options) { return newTwoLevelIterator(index_iter, block_function, arg, options); }这里有一个函数指针BlockFunction,类型为:
BlockFunction block_function_; // block操作函数 void* arg_; // BlockFunction的自定义参数 const ReadOptions options_; // BlockFunction的read option参数 Status status_; // 当前状态 IteratorWrapper index_iter_; // 遍历block的迭代器 IteratorWrapper data_iter_; // May be NULL-遍历block data的迭代器 // 如果data_iter_ != NULL,data_block_handle_保存的是传递给 // block_function_的index value,以用来创建data_iter_ std::string data_block_handle_;下面分析一下对于Iterator几个接口的实现。
virtual bool Valid() const { return data_iter_.Valid(); } virtual Slice key() const { assert(Valid()); return data_iter_.key(); } virtual Slice value() const { assert(Valid()); return data_iter_.value(); }S2 在分析Seek系函数之前,有必要先了解下面这几个函数的用途。
void InitDataBlock(); void SetDataIterator(Iterator*data_iter); //设置date_iter_ = data_iter voidSkipEmptyDataBlocksForward(); voidSkipEmptyDataBlocksBackward();S2.1首先是InitDataBlock(),它是根据index_iter来初始化data_iter,当定位到新的block时,需要更新data Iterator,指向该block中k/v对的合适位置,函数如下:
if (!index_iter_.Valid()) SetDataIterator(NULL);// index_iter非法 else { Slice handle =index_iter_.value(); if (data_iter_.iter() != NULL&& handle.compare(data_block_handle_) == 0) { //data_iter已经在该block data上了,无须改变 } else { // 根据handle数据定位data iter Iterator* iter =(*block_function_)(arg_, options_, handle); data_block_handle_.assign(handle.data(), handle.size()); SetDataIterator(iter); } }S2.2 SkipEmptyDataBlocksForward,向前跳过空的datablock,函数实现如下:
while (data_iter_.iter() == NULL|| !data_iter_.Valid()) { // 跳到下一个block if (!index_iter_.Valid()) { // 如果index iter非法,设置data iteration为NULL SetDataIterator(NULL); return; } index_iter_.Next(); InitDataBlock(); if (data_iter_.iter() != NULL)data_iter_.SeekToFirst(); // 跳转到开始 }S2.3 SkipEmptyDataBlocksBackward,向后跳过空的datablock,函数实现如下:
while (data_iter_.iter() == NULL|| !data_iter_.Valid()) { // 跳到前一个block if (!index_iter_.Valid()) { // 如果index iter非法,设置data iteration为NULL SetDataIterator(NULL); return; } index_iter_.Prev(); InitDataBlock(); if (data_iter_.iter() != NULL)data_iter_.SeekToLast();// 跳转到开始 }S3 了解了几个跳转的辅助函数,再来看Seek系接口。
void TwoLevelIterator::Seek(const Slice& target) { index_iter_.Seek(target); InitDataBlock(); // 根据index iter设置data iter if (data_iter_.iter() != NULL)data_iter_.Seek(target); // 调整data iter跳转到target SkipEmptyDataBlocksForward(); // 调整iter