b. 否则需要分裂
//case2 insert into parent else { auto parent_page = buffer_pool_manager_->FetchPage(old_node->GetParentPageId()); if (parent_page == nullptr) { throw "no old_node parent page can used"; } auto internal =reinterpret_cast<BPlusTreeInternalPage<KeyType, page_id_t,KeyComparator> *>(parent_page->GetData()); // case 2.a insert directly if (internal->GetSize() < internal->GetMaxSize()) { internal->InsertNodeAfter(old_node->GetPageId(), key, new_node->GetPageId()); new_node->SetParentPageId(internal->GetPageId()); buffer_pool_manager_->UnpinPage(new_node->GetPageId(), true); } //case 2.b the parent node need to split else { page_id_t page_id; auto new_page = buffer_pool_manager_->NewPage(&page_id); if (new_page == nullptr) { throw "no page can used while InsertIntoParent"; } auto virtual_node =reinterpret_cast<BPlusTreeInternalPage<KeyType, page_id_t,KeyComparator> *>(new_page->GetData()); virtual_node->Init(page_id,old_node->GetParentPageId(),internal_max_size_); virtual_node->SetSize(internal->GetSize()); for (int i = 1, j = 0; i <=internal->GetSize(); i++,j++) { if (internal->ValueAt(i-1) == old_node->GetPageId()) { virtual_node->SetKeyAt(j, key); virtual_node->SetValueAt(j, new_node->GetPageId()); j++; } if (i < internal->GetSize()) { virtual_node->SetKeyAt(j, internal->KeyAt(i)); virtual_node->SetValueAt(j, internal->ValueAt(i)); } } assert(virtual_node->GetSize() == virtual_node->GetMaxSize()); auto new_internal =Split<BPlusTreeInternalPage<KeyType, page_id_t, KeyComparator>>(virtual_node); internal->SetSize(virtual_node->GetSize() + 1); for (int i = 0; i < virtual_node->GetSize(); ++i) { internal->SetKeyAt(i + 1, virtual_node->KeyAt(i)); internal->SetValueAt(i + 1, virtual_node->ValueAt(i)); } // set new node parent page id if (comparator_(key, new_internal->KeyAt(0)) < 0) { new_node->SetParentPageId(internal->GetPageId()); } else if (comparator_(key, new_internal->KeyAt(0)) == 0) { new_node->SetParentPageId(new_internal->GetPageId()); } else { new_node->SetParentPageId(new_internal->GetPageId()); old_node->SetParentPageId(new_internal->GetPageId()); } // TODO unpin and delete virtual page buffer_pool_manager_->UnpinPage(new_node->GetPageId(), true); buffer_pool_manager_->UnpinPage(virtual_node->GetPageId(), false); buffer_pool_manager_->DeletePage(virtual_node->GetPageId()); InsertIntoParent(internal, new_internal->KeyAt(0), new_internal); } buffer_pool_manager_->UnpinPage(internal->GetPageId(), true); } }好了实验2的第一部分就到这里了。整个实验都已经写完啦。剩下就是优化代码,写博客记录了,所以实验2的第二部分也会很快更新的。这里面的代码不是很详细。等到第二部分写完之后,会一整个完全上传到GitHub上的。
附上一个pass的截图完成第一部分✅