[已完結]CMU資料庫(15-445)實驗2-B+樹索引實現(下)
阿新 • • 發佈:2021-01-27
### 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. 首先複習一下讀寫