【leveldb】TwoLevelIterator(十五)

在分析SSTable代碼過程中涉及到了二級迭代器,此篇藉此展開分析下。二級迭代器的存在便於對SSTable的DataBlock數據進行訪問,其結構如下:
在這裏插入圖片描述

圖1

對於SSTable來說:

  • Level_1是Index Block迭代器;
  • Level_2是指向DataBlock迭代器。

源碼解讀

namespace leveldb {

namespace {

//設置二級迭代器時傳入的回調函數
typedef Iterator* (*BlockFunction)(void*, const ReadOptions&, const Slice&);

class TwoLevelIterator : public Iterator {
 public:
  
  //構造。對於SSTable來說:
  //1、index_iter是指向index block的迭代器;
  //2、block_function是Table::BlockReader,即讀取一個block;
  //3、arg是指向一個SSTable;
  //4、options 讀選項。
  TwoLevelIterator(Iterator* index_iter, BlockFunction block_function,
                   void* arg, const ReadOptions& options);

  ~TwoLevelIterator() override;

  //針對一級迭代器,target是一個index block元素,
  //這裏就是seek到index block對應元素位置
  void Seek(const Slice& target) override;
  //針對一級迭代器操作
  void SeekToFirst() override;
  //針對一級迭代器操作
  void SeekToLast() override;
  //針對二級迭代器,DataBlock中的下一個Entry
  void Next() override;
  //針對二級迭代器,DataBlock中的前一個Entry
  void Prev() override;

  //針對二級迭代器,指向DataBlock的迭代器是否有效
  bool Valid() const override { return data_iter_.Valid(); }
  //針對二級迭代器,DataBlock中的一個Entry的Key
  Slice key() const override {
    assert(Valid());
    return data_iter_.key();
  }
  //針對二級迭代器,DataBlock中的一個Entry的Value
  Slice value() const override {
    assert(Valid());
    return data_iter_.value();
  }

  //當前二級迭代器的操作狀態
  Status status() const override {
    // It'd be nice if status() returned a const Status& instead of a Status
    if (!index_iter_.status().ok()) {
      return index_iter_.status();
    } else if (data_iter_.iter() != nullptr && !data_iter_.status().ok()) {
      return data_iter_.status();
    } else {
      return status_;
    }
  }

 private:
  //保存錯誤狀態,如果最近一次狀態是非ok狀態,
  //則不保存
  void SaveError(const Status& s) {
    if (status_.ok() && !s.ok()) status_ = s;
  }
  //跳過當前空的DataBlock,轉到下一個DataBlock
  void SkipEmptyDataBlocksForward();
  //跳過當前空的DataBlock,轉到前一個DataBlock
  void SkipEmptyDataBlocksBackward();
  //設置二級迭代器data_iter
  void SetDataIterator(Iterator* data_iter);
  //初始化DataBlock的二級迭代器
  void InitDataBlock();

  BlockFunction block_function_;
  void* arg_;
  const ReadOptions options_;
  Status status_;
  //一級迭代器,對於SSTable來說就是指向index block
  IteratorWrapper index_iter_; 
  //二級迭代器,對於SSTable來說就是指向DataBlock
  IteratorWrapper data_iter_;  // May be nullptr
  
  //對於SSTable來說,保存index block中的offset+size。
  // If data_iter_ is non-null, then "data_block_handle_" holds the
  // "index_value" passed to block_function_ to create the data_iter_.
  std::string data_block_handle_;
};

//構造二級迭代器。
//一級迭代器賦值爲index_iner,
//二級迭代器賦值爲nullptr。
TwoLevelIterator::TwoLevelIterator(Iterator* index_iter,
                                   BlockFunction block_function, void* arg,
                                   const ReadOptions& options)
    : block_function_(block_function),
      arg_(arg),
      options_(options),
      index_iter_(index_iter),
      data_iter_(nullptr) {}

TwoLevelIterator::~TwoLevelIterator() = default;

//1、seek到target對應的一級迭代器位置;
//2、初始化二級迭代器;
//3、跳過當前空的DataBlock。
void TwoLevelIterator::Seek(const Slice& target) {
  index_iter_.Seek(target);
  InitDataBlock();
  if (data_iter_.iter() != nullptr) data_iter_.Seek(target);
  SkipEmptyDataBlocksForward();
}

//流程同Seek()
void TwoLevelIterator::SeekToFirst() {
  index_iter_.SeekToFirst();
  InitDataBlock();
  if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
  SkipEmptyDataBlocksForward();
}

//流程同Seek()
void TwoLevelIterator::SeekToLast() {
  index_iter_.SeekToLast();
  InitDataBlock();
  if (data_iter_.iter() != nullptr) data_iter_.SeekToLast();
  SkipEmptyDataBlocksBackward();
}

//二級迭代器的下一個元素,
//對SSTable來說就是DataBlock中的下一個元素。
//需要檢查跳過空的DataBlck。
void TwoLevelIterator::Next() {
  assert(Valid());
  data_iter_.Next();
  SkipEmptyDataBlocksForward();
}

//二級迭代器的前一個元素,
//對SSTable來說就是DataBlock中的前一個元素。
//需要檢查跳過空的DataBlck。
void TwoLevelIterator::Prev() {
  assert(Valid());
  data_iter_.Prev();
  SkipEmptyDataBlocksBackward();
}

//針對二級迭代器。
//如果當前二級迭代器指向爲空或者非法;
//那就向後跳到下一個非空的DataBlock。
void TwoLevelIterator::SkipEmptyDataBlocksForward() {
  while (data_iter_.iter() == nullptr || !data_iter_.Valid()) {
    // Move to next block
    if (!index_iter_.Valid()) {
      SetDataIterator(nullptr);
      return;
    }
    index_iter_.Next();
    InitDataBlock();
    if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
  }
}

//針對二級迭代器。
//如果當前二級迭代器指向爲空或者非法;
//那就向前跳到下一個非空的DataBlock。
void TwoLevelIterator::SkipEmptyDataBlocksBackward() {
  while (data_iter_.iter() == nullptr || !data_iter_.Valid()) {
    // Move to next block
    if (!index_iter_.Valid()) {
      SetDataIterator(nullptr);
      return;
    }
    index_iter_.Prev();
    InitDataBlock();
    if (data_iter_.iter() != nullptr) data_iter_.SeekToLast();
  }
}

//設置二級迭代器
void TwoLevelIterator::SetDataIterator(Iterator* data_iter) {
  if (data_iter_.iter() != nullptr) SaveError(data_iter_.status());
  data_iter_.Set(data_iter);
}

//初始化二級迭代器指向。
//對SSTable來說就是獲取DataBlock的迭代器賦值給二級迭代器。
void TwoLevelIterator::InitDataBlock() {
  if (!index_iter_.Valid()) {
    SetDataIterator(nullptr);
  } else {
    Slice handle = index_iter_.value();
    if (data_iter_.iter() != nullptr &&
        handle.compare(data_block_handle_) == 0) {
      // data_iter_ is already constructed with this iterator, so
      // no need to change anything
    } else {
      Iterator* iter = (*block_function_)(arg_, options_, handle);
      data_block_handle_.assign(handle.data(), handle.size());
      SetDataIterator(iter);
    }
  }
}

}  // namespace

//構造結構
Iterator* NewTwoLevelIterator(Iterator* index_iter,
                              BlockFunction block_function, void* arg,
                              const ReadOptions& options) {
  return new TwoLevelIterator(index_iter, block_function, arg, options);
}

}  // namespace leveldb
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章