Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(p2): fall 2024 #754

Merged
merged 26 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,17 @@ add_custom_target(submit-p1
)

set(P2_FILES
"src/include/storage/page/page_guard.h"
"src/storage/page/page_guard.cpp"
"src/include/storage/page/extendible_htable_bucket_page.h"
"src/storage/page/extendible_htable_bucket_page.cpp"
"src/include/storage/page/extendible_htable_directory_page.h"
"src/storage/page/extendible_htable_directory_page.cpp"
"src/include/storage/page/extendible_htable_header_page.h"
"src/storage/page/extendible_htable_header_page.cpp"
"src/include/container/disk/hash/disk_extendible_hash_table.h"
"src/container/disk/hash/disk_extendible_hash_table.cpp"
"src/include/storage/page/b_plus_tree_page.h"
"src/storage/page/b_plus_tree_page.cpp"
"src/include/storage/page/b_plus_tree_internal_page.h"
"src/storage/page/b_plus_tree_internal_page.cpp"
"src/include/storage/page/b_plus_tree_leaf_page.h"
"src/storage/page/b_plus_tree_leaf_page.cpp"
"src/include/storage/index/index_iterator.h"
"src/storage/index/index_iterator.cpp"
"src/include/storage/index/b_plus_tree.h"
"src/include/storage/index/b_plus_tree_debug.h"
"src/storage/index/b_plus_tree.cpp"
${P1_FILES}
)
add_custom_target(check-clang-tidy-p2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
// Identification: src/container/disk/hash/disk_extendible_hash_table_utils.cpp
//
// Copyright (c) 2015-2023, Carnegie Mellon University Database Group
// Copyright (c) 2015-2024, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

Expand Down
13 changes: 6 additions & 7 deletions src/include/storage/index/b_plus_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

#include "common/config.h"
#include "common/macros.h"
#include "concurrency/transaction.h"
#include "storage/index/index_iterator.h"
#include "storage/page/b_plus_tree_header_page.h"
#include "storage/page/b_plus_tree_internal_page.h"
Expand Down Expand Up @@ -74,13 +73,13 @@ class BPlusTree {
auto IsEmpty() const -> bool;

// Insert a key-value pair into this B+ tree.
auto Insert(const KeyType &key, const ValueType &value, Transaction *txn = nullptr) -> bool;
auto Insert(const KeyType &key, const ValueType &value) -> bool;

// Remove a key and its value from this B+ tree.
void Remove(const KeyType &key, Transaction *txn);
void Remove(const KeyType &key);

// Return the value associated with a given key
auto GetValue(const KeyType &key, std::vector<ValueType> *result, Transaction *txn = nullptr) -> bool;
auto GetValue(const KeyType &key, std::vector<ValueType> *result) -> bool;

// Return the page id of the root node
auto GetRootPageId() -> page_id_t;
Expand Down Expand Up @@ -112,10 +111,10 @@ class BPlusTree {
auto DrawBPlusTree() -> std::string;

// read data from file and insert one by one
void InsertFromFile(const std::filesystem::path &file_name, Transaction *txn = nullptr);
void InsertFromFile(const std::filesystem::path &file_name);

// read data from file and remove one by one
void RemoveFromFile(const std::filesystem::path &file_name, Transaction *txn = nullptr);
void RemoveFromFile(const std::filesystem::path &file_name);

/**
* @brief Read batch operations from input file, below is a sample file format
Expand All @@ -126,7 +125,7 @@ class BPlusTree {
* (3) (7)
* (1,2) (3,4) (5,6) (7,10,30) // The output tree example
*/
void BatchOpsFromFile(const std::filesystem::path &file_name, Transaction *txn = nullptr);
void BatchOpsFromFile(const std::filesystem::path &file_name);

private:
/* Debug Routines for FREE!! */
Expand Down
275 changes: 275 additions & 0 deletions src/include/storage/index/b_plus_tree_debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
//===----------------------------------------------------------------------===//
//
// BusTub
//
// b_plus_tree_debug.h
//
// Identification: bustub/src/include/storage/index/b_plus_tree_debug.h
//
// Copyright (c) 2024, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <sstream>
#include <string>

#include "common/exception.h"
#include "common/logger.h"
#include "common/rid.h"
#include "storage/index/b_plus_tree.h"
#include "storage/page/b_plus_tree_page.h"

namespace bustub {

/*****************************************************************************
* UTILITIES AND DEBUG
*****************************************************************************/

/*
* This method is used for test only
* Read data from file and insert one by one
*/
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name) {
int64_t key;
std::ifstream input(file_name);
while (input) {
input >> key;

KeyType index_key;
index_key.SetFromInteger(key);
RID rid(key);
Insert(index_key, rid);
}
}
/*
* This method is used for test only
* Read data from file and remove one by one
*/
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name) {
int64_t key;
std::ifstream input(file_name);
while (input) {
input >> key;
KeyType index_key;
index_key.SetFromInteger(key);
Remove(index_key);
}
}

lanlou1554 marked this conversation as resolved.
Show resolved Hide resolved
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::Print(BufferPoolManager *bpm) {
auto root_page_id = GetRootPageId();
if (root_page_id != INVALID_PAGE_ID) {
auto guard = bpm->ReadPage(root_page_id);
PrintTree(guard.GetPageId(), guard.template As<BPlusTreePage>());
}
}

lanlou1554 marked this conversation as resolved.
Show resolved Hide resolved
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) {
if (page->IsLeafPage()) {
auto *leaf = reinterpret_cast<const LeafPage *>(page);
std::cout << "Leaf Page: " << page_id << "\tNext: " << leaf->GetNextPageId() << std::endl;

// Print the contents of the leaf page.
std::cout << "Contents: ";
for (int i = 0; i < leaf->GetSize(); i++) {
std::cout << leaf->KeyAt(i);
if ((i + 1) < leaf->GetSize()) {
std::cout << ", ";
}
}
std::cout << std::endl;
std::cout << std::endl;

} else {
auto *internal = reinterpret_cast<const InternalPage *>(page);
std::cout << "Internal Page: " << page_id << std::endl;

// Print the contents of the internal page.
std::cout << "Contents: ";
for (int i = 0; i < internal->GetSize(); i++) {
std::cout << internal->KeyAt(i) << ": " << internal->ValueAt(i);
lanlou1554 marked this conversation as resolved.
Show resolved Hide resolved
if ((i + 1) < internal->GetSize()) {
std::cout << ", ";
}
}
std::cout << std::endl;
std::cout << std::endl;
for (int i = 0; i < internal->GetSize(); i++) {
auto guard = bpm_->ReadPage(internal->ValueAt(i));
PrintTree(guard.GetPageId(), guard.template As<BPlusTreePage>());
}
}
}

/**
* This method is used for debug only, You don't need to modify
*/
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::Draw(BufferPoolManager *bpm, const std::filesystem::path &outf) {
if (IsEmpty()) {
LOG_WARN("Drawing an empty tree");
return;
}

std::ofstream out(outf);
out << "digraph G {" << std::endl;
auto root_page_id = GetRootPageId();
auto guard = bpm->ReadPage(root_page_id);
ToGraph(guard.GetPageId(), guard.template As<BPlusTreePage>(), out);
out << "}" << std::endl;
out.close();
}

/**
* This method is used for debug only, You don't need to modify
*/
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::ToGraph(page_id_t page_id, const BPlusTreePage *page, std::ofstream &out) {
std::string leaf_prefix("LEAF_");
std::string internal_prefix("INT_");
if (page->IsLeafPage()) {
auto *leaf = reinterpret_cast<const LeafPage *>(page);
// Print node name
out << leaf_prefix << page_id;
// Print node properties
out << "[shape=plain color=green ";
// Print data of the node
out << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\n";
// Print data
out << "<TR><TD COLSPAN=\"" << leaf->GetSize() << "\">P=" << page_id << "</TD></TR>\n";
out << "<TR><TD COLSPAN=\"" << leaf->GetSize() << "\">"
<< "max_size=" << leaf->GetMaxSize() << ",min_size=" << leaf->GetMinSize() << ",size=" << leaf->GetSize()
<< "</TD></TR>\n";
out << "<TR>";
for (int i = 0; i < leaf->GetSize(); i++) {
out << "<TD>" << leaf->KeyAt(i) << "</TD>\n";
}
out << "</TR>";
// Print table end
out << "</TABLE>>];\n";
// Print Leaf node link if there is a next page
if (leaf->GetNextPageId() != INVALID_PAGE_ID) {
out << leaf_prefix << page_id << " -> " << leaf_prefix << leaf->GetNextPageId() << ";\n";
out << "{rank=same " << leaf_prefix << page_id << " " << leaf_prefix << leaf->GetNextPageId() << "};\n";
}
} else {
auto *inner = reinterpret_cast<const InternalPage *>(page);
// Print node name
out << internal_prefix << page_id;
// Print node properties
out << "[shape=plain color=pink "; // why not?
// Print data of the node
out << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\n";
// Print data
out << "<TR><TD COLSPAN=\"" << inner->GetSize() << "\">P=" << page_id << "</TD></TR>\n";
out << "<TR><TD COLSPAN=\"" << inner->GetSize() << "\">"
<< "max_size=" << inner->GetMaxSize() << ",min_size=" << inner->GetMinSize() << ",size=" << inner->GetSize()
<< "</TD></TR>\n";
out << "<TR>";
for (int i = 0; i < inner->GetSize(); i++) {
out << "<TD PORT=\"p" << inner->ValueAt(i) << "\">";
if (i > 0) {
out << inner->KeyAt(i);
} else {
out << " ";
}
out << "</TD>\n";
}
out << "</TR>";
// Print table end
out << "</TABLE>>];\n";
// Print leaves
for (int i = 0; i < inner->GetSize(); i++) {
auto child_guard = bpm_->ReadPage(inner->ValueAt(i));
auto child_page = child_guard.template As<BPlusTreePage>();
ToGraph(child_guard.GetPageId(), child_page, out);
if (i > 0) {
auto sibling_guard = bpm_->ReadPage(inner->ValueAt(i - 1));
auto sibling_page = sibling_guard.template As<BPlusTreePage>();
if (!sibling_page->IsLeafPage() && !child_page->IsLeafPage()) {
out << "{rank=same " << internal_prefix << sibling_guard.GetPageId() << " " << internal_prefix
<< child_guard.GetPageId() << "};\n";
}
}
out << internal_prefix << page_id << ":p" << child_guard.GetPageId() << " -> ";
if (child_page->IsLeafPage()) {
out << leaf_prefix << child_guard.GetPageId() << ";\n";
} else {
out << internal_prefix << child_guard.GetPageId() << ";\n";
}
}
}
}

INDEX_TEMPLATE_ARGUMENTS
auto BPLUSTREE_TYPE::DrawBPlusTree() -> std::string {
if (IsEmpty()) {
return "()";
}

PrintableBPlusTree p_root = ToPrintableBPlusTree(GetRootPageId());
std::ostringstream out_buf;
p_root.Print(out_buf);

return out_buf.str();
}

/*
* This method is used for test only
* Read data from file and insert/remove one by one
*/
INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name) {
int64_t key;
char instruction;
std::ifstream input(file_name);
while (input) {
input >> instruction >> key;
RID rid(key);
KeyType index_key;
index_key.SetFromInteger(key);
switch (instruction) {
case 'i':
Insert(index_key, rid);
break;
case 'd':
Remove(index_key);
break;
default:
break;
}
}
}

INDEX_TEMPLATE_ARGUMENTS
auto BPLUSTREE_TYPE::ToPrintableBPlusTree(page_id_t root_id) -> PrintableBPlusTree {
auto root_page_guard = bpm_->ReadPage(root_id);
auto root_page = root_page_guard.template As<BPlusTreePage>();
PrintableBPlusTree proot;

if (root_page->IsLeafPage()) {
auto leaf_page = root_page_guard.template As<LeafPage>();
proot.keys_ = leaf_page->ToString();
proot.size_ = proot.keys_.size() + 4; // 4 more spaces for indent

return proot;
}

// draw internal page
auto internal_page = root_page_guard.template As<InternalPage>();
proot.keys_ = internal_page->ToString();
proot.size_ = 0;
for (int i = 0; i < internal_page->GetSize(); i++) {
page_id_t child_id = internal_page->ValueAt(i);
PrintableBPlusTree child_node = ToPrintableBPlusTree(child_id);
proot.size_ += child_node.size_;
proot.children_.push_back(child_node);
}

return proot;
}
} // namespace bustub
3 changes: 2 additions & 1 deletion src/include/storage/index/index_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* For range scan of b+ tree
*/
#pragma once
#include <utility>
#include "storage/page/b_plus_tree_leaf_page.h"

namespace bustub {
Expand All @@ -28,7 +29,7 @@ class IndexIterator {

auto IsEnd() -> bool;

auto operator*() -> const MappingType &;
auto operator*() -> std::pair<const KeyType &, const ValueType &>;

auto operator++() -> IndexIterator &;

Expand Down
Loading
Loading