首页 > 技术文章 > [已完结]CMU数据库(15-445)实验2-B+树索引实现(下)

JayL-zxl 2021-01-27 09:33 原文

[已完结]CMU数据库(15-445)实验2-B+树索引实现(下)

4. Index_Iterator实现#

这里就是需要实现迭代器的一些操作,比如begin、end、isend等等

下面是对于IndexIterator的构造函数

其中idx表示当前page中的第几个tuple

INDEXITERATOR_TYPE::IndexIterator(LeafPage *leftmost_leaf, int idx, BufferPoolManager *buffer_pool_manager)
    : curr_page(leftmost_leaf), curr_index(idx), bpm(buffer_pool_manager) {}

1. 首先我们来看begin函数的实现#

  1. 利用key值找到叶子结点
  2. 然后获取当前key值的index就是begin的位置
Page *page = FindLeafPage(KeyType{}, true);  // leftmost_leaf pinned
  LeafPage *leftmost_leaf = reinterpret_cast<LeafPage *>(page->GetData());
  buffer_pool_manager_->UnpinPage(leftmost_leaf->GetPageId(), false);
  return INDEXITERATOR_TYPE(leftmost_leaf, 0, buffer_pool_manager_);

2. end函数的实现#

  1. 找到最开始的结点
  2. 然后一直向后遍历直到nextPageId=-1结束
  3. 这里注意需要重载!===

end函数

// find the right most page
  Page *page = FindLeafPage(KeyType{}, true);  // page pinned
  LeafPage *leaf = reinterpret_cast<LeafPage *>(page->GetData());

  while (leaf->GetNextPageId() != INVALID_PAGE_ID) {
    page_id_t next_page_id = leaf->GetNextPageId();
    buffer_pool_manager_->UnpinPage(leaf->GetPageId(), false);  // page unpinned

    Page *next_page = buffer_pool_manager_->FetchPage(next_page_id);  // next_page pinned
    leaf = reinterpret_cast<LeafPage *>(next_page->GetData());
  }

  return INDEXITERATOR_TYPE(leaf, leaf->GetSize(), buffer_pool_manager_);

==和 !=函数

这里注意在!= 那里不能写成itr != *this

INDEX_TEMPLATE_ARGUMENTS
bool INDEXITERATOR_TYPE::operator==(const IndexIterator &itr) const {
  return itr.curr_page == curr_page && itr.curr_index == curr_index;
}

INDEX_TEMPLATE_ARGUMENTS
bool INDEXITERATOR_TYPE::operator!=(const IndexIterator &itr) const { return !(itr == *this); }

3. 重载++和*(解引用符号)#

  1. 重载++

简单的index++然后设置nextPageId即可

INDEX_TEMPLATE_ARGUMENTS
INDEXITERATOR_TYPE &INDEXITERATOR_TYPE::operator++() {
  curr_index++;
  if (curr_index == curr_page->GetSize() && curr_page->GetNextPageId() != INVALID_PAGE_ID) {
    page_id_t next_pid = curr_page->GetNextPageId();
    Page *next_page = bpm->FetchPage(next_pid);  // pined page

    LeafPage *next_node = reinterpret_cast<LeafPage *>(next_page->GetData());
    curr_page = next_node;
    bpm->UnpinPage(next_page->GetPageId(), false);
    curr_index = 0;
  }
  return *this;
}
  1. 重载*

return array[index]即可

const MappingType &INDEXITERATOR_TYPE::operator*() { return curr_page->GetItem(curr_index); }

5. 并发机制的实现#

0. 首先复习一下读写

推荐阅读