1. 程式人生 > >[已完結]CMU資料庫(15-445)實驗2-B+樹索引實現(下)

[已完結]CMU資料庫(15-445)實驗2-B+樹索引實現(下)

### 4. Index_Iterator實現 這裡就是需要實現迭代器的一些操作,比如begin、end、isend等等 下面是對於`IndexIterator`的建構函式 ```c++ template IndexIterator:: IndexIterator(BPlusTreeLeafPage *leaf, int index_, BufferPoolManager *buff_pool_manager): leaf_(leaf), index_(index_), buff_pool_manager_(buff_pool_manager) {} ``` #### 1. 首先我們來看begin函式的實現 1. 利用key值找到葉子結點 2. 然後獲取當前key值的index就是begin的位置 ```c++ INDEX_TEMPLATE_ARGUMENTS INDEXITERATOR_TYPE BPLUSTREE_TYPE::Begin(const KeyType &key) { auto leaf = reinterpret_cast *>(FindLeafPage(key, false)); int index = 0; if (leaf != nullptr) { index = leaf->KeyIndex(key, comparator_); } return IndexIterator(leaf, index, buffer_pool_manager_); } ``` #### 2. end函式的實現 1. 找到最開始的結點 2. 然後一直向後遍歷直到`nextPageId=-1`結束 3. 這裡注意需要過載`!=`和`==` `end`函式 ```c++ INDEX_TEMPLATE_ARGUMENTS INDEXITERATOR_TYPE BPLUSTREE_TYPE::end() { KeyType key{}; auto leaf= reinterpret_cast *>( FindLeafPage(key, true)); page_id_t new_page; while(leaf->GetNextPageId()!=INVALID_PAGE_ID){ new_page=leaf->GetNextPageId(); leaf=reinterpret_cast *>(buffer_pool_manager_->FetchPage(new_page)); } buffer_pool_manager_->UnpinPage(new_page,false); return IndexIterator(leaf, leaf->GetSize(), buffer_pool_manager_); } ``` `==和 !=`函式 ```c++ bool operator==(const IndexIterator &itr) const { return this->index_==itr.index_&&this->leaf_==itr.leaf_; } bool operator!=(const IndexIterator &itr) const { return !this->operator==(itr); } ``` #### 3. 過載++和*(解引用符號) 1. 過載++ > 簡單的index++然後設定nextPageId即可 ```c++ template IndexIterator &IndexIterator:: operator++() { // // std::cout<<"++"<GetSize() && leaf_->GetNextPageId() != INVALID_PAGE_ID) { // first unpin leaf_, then get the next leaf page_id_t next_page_id = leaf_->GetNextPageId(); auto *page = buff_pool_manager_->FetchPage(next_page_id); if (page == nullptr) { throw Exception("all page are pinned while IndexIterator(operator++)"); } // first acquire next page, then release previous page page->RLatch(); buff_pool_manager_->FetchPage(leaf_->GetPageId())->RUnlatch(); buff_pool_manager_->UnpinPage(leaf_->GetPageId(), false); buff_pool_manager_->UnpinPage(leaf_->GetPageId(), false); auto next_leaf =reinterpret_cast *>(page->GetData()); assert(next_leaf->IsLeafPage()); index_ = 0; leaf_ = next_leaf; } return *this; }; ``` 2. 過載* > return array[index]即可 ```c++ template const MappingType &IndexIterator:: operator*() { if (isEnd()) { throw "IndexIterator: out of range"; } return leaf_->GetItem(index_); } ``` ### 5. 併發機制的實現 #### 0. 首先複習一下讀寫