From e5cf0d3d4972c5c887c77bd8915d3149d341d1ec Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sat, 21 Sep 2024 23:42:26 -0400 Subject: [PATCH 01/22] refactor(p2): remove transaction from b plus tree --- src/storage/index/b_plus_tree_index.cpp | 6 ++--- test/storage/b_plus_tree_concurrent_test.cpp | 26 +++++-------------- test/storage/b_plus_tree_contention_test.cpp | 4 +-- test/storage/b_plus_tree_delete_test.cpp | 18 +++---------- test/storage/b_plus_tree_insert_test.cpp | 18 +++---------- .../b_plus_tree_sequential_scale_test.cpp | 5 +--- .../b_plus_tree_printer.cpp | 16 +++++------- 7 files changed, 25 insertions(+), 68 deletions(-) diff --git a/src/storage/index/b_plus_tree_index.cpp b/src/storage/index/b_plus_tree_index.cpp index 5b613729d..20b8e4f95 100644 --- a/src/storage/index/b_plus_tree_index.cpp +++ b/src/storage/index/b_plus_tree_index.cpp @@ -29,7 +29,7 @@ auto BPLUSTREE_INDEX_TYPE::InsertEntry(const Tuple &key, RID rid, Transaction *t KeyType index_key; index_key.SetFromKey(key); - return container_->Insert(index_key, rid, transaction); + return container_->Insert(index_key, rid); } INDEX_TEMPLATE_ARGUMENTS @@ -38,7 +38,7 @@ void BPLUSTREE_INDEX_TYPE::DeleteEntry(const Tuple &key, RID rid, Transaction *t KeyType index_key; index_key.SetFromKey(key); - container_->Remove(index_key, transaction); + container_->Remove(index_key); } INDEX_TEMPLATE_ARGUMENTS @@ -47,7 +47,7 @@ void BPLUSTREE_INDEX_TYPE::ScanKey(const Tuple &key, std::vector *result, T KeyType index_key; index_key.SetFromKey(key); - container_->GetValue(index_key, result, transaction); + container_->GetValue(index_key, result); } INDEX_TEMPLATE_ARGUMENTS diff --git a/test/storage/b_plus_tree_concurrent_test.cpp b/test/storage/b_plus_tree_concurrent_test.cpp index 9aff57211..e36bc3701 100644 --- a/test/storage/b_plus_tree_concurrent_test.cpp +++ b/test/storage/b_plus_tree_concurrent_test.cpp @@ -46,15 +46,12 @@ void InsertHelper(BPlusTree, RID, GenericComparator<8>> *tree, con __attribute__((unused)) uint64_t thread_itr = 0) { GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree->Insert(index_key, rid, transaction); + tree->Insert(index_key, rid); } - delete transaction; } // helper function to seperate insert @@ -62,30 +59,24 @@ void InsertHelperSplit(BPlusTree, RID, GenericComparator<8>> *tree int total_threads, __attribute__((unused)) uint64_t thread_itr) { GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); for (auto key : keys) { if (static_cast(key) % total_threads == thread_itr) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree->Insert(index_key, rid, transaction); + tree->Insert(index_key, rid); } } - delete transaction; } // helper function to delete void DeleteHelper(BPlusTree, RID, GenericComparator<8>> *tree, const std::vector &remove_keys, __attribute__((unused)) uint64_t thread_itr = 0) { GenericKey<8> index_key; - // create transaction - auto *transaction = new Transaction(0); for (auto key : remove_keys) { index_key.SetFromInteger(key); - tree->Remove(index_key, transaction); + tree->Remove(index_key); } - delete transaction; } // helper function to seperate delete @@ -93,20 +84,16 @@ void DeleteHelperSplit(BPlusTree, RID, GenericComparator<8>> *tree const std::vector &remove_keys, int total_threads, __attribute__((unused)) uint64_t thread_itr) { GenericKey<8> index_key; - // create transaction - auto *transaction = new Transaction(0); for (auto key : remove_keys) { if (static_cast(key) % total_threads == thread_itr) { index_key.SetFromInteger(key); - tree->Remove(index_key, transaction); + tree->Remove(index_key); } } - delete transaction; } void LookupHelper(BPlusTree, RID, GenericComparator<8>> *tree, const std::vector &keys, uint64_t tid, __attribute__((unused)) uint64_t thread_itr = 0) { - auto *transaction = new Transaction(static_cast(tid)); GenericKey<8> index_key; RID rid; for (auto key : keys) { @@ -114,12 +101,11 @@ void LookupHelper(BPlusTree, RID, GenericComparator<8>> *tree, con rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); std::vector result; - bool res = tree->GetValue(index_key, &result, transaction); + bool res = tree->GetValue(index_key, &result); ASSERT_EQ(res, true); ASSERT_EQ(result.size(), 1); ASSERT_EQ(result[0], rid); } - delete transaction; } TEST(BPlusTreeConcurrentTest, DISABLED_InsertTest1) { @@ -368,7 +354,7 @@ TEST(BPlusTreeConcurrentTest, DISABLED_MixTest2) { size_t num_threads = 6; for (size_t i = 0; i < num_threads; i++) { - threads.emplace_back(std::thread{tasks[i % tasks.size()], i}); + threads.emplace_back(tasks[i % tasks.size()], i); } for (size_t i = 0; i < num_threads; i++) { threads[i].join(); diff --git a/test/storage/b_plus_tree_contention_test.cpp b/test/storage/b_plus_tree_contention_test.cpp index be78f4cbb..e07837a1c 100644 --- a/test/storage/b_plus_tree_contention_test.cpp +++ b/test/storage/b_plus_tree_contention_test.cpp @@ -43,7 +43,6 @@ bool BPlusTreeLockBenchmarkCall(size_t num_threads, int leaf_node_size, bool wit auto func = [&tree, &mtx, i, keys_per_thread, with_global_mutex]() { GenericKey<8> index_key; RID rid; - auto *transaction = new Transaction(static_cast(i + 1)); const auto end_key = keys_stride * i + keys_per_thread; for (auto key = i * keys_stride; key < end_key; key++) { int64_t value = key & 0xFFFFFFFF; @@ -52,12 +51,11 @@ bool BPlusTreeLockBenchmarkCall(size_t num_threads, int leaf_node_size, bool wit if (with_global_mutex) { mtx.lock(); } - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); if (with_global_mutex) { mtx.unlock(); } } - delete transaction; }; auto t = std::thread(std::move(func)); threads.emplace_back(std::move(t)); diff --git a/test/storage/b_plus_tree_delete_test.cpp b/test/storage/b_plus_tree_delete_test.cpp index 99a4e40b7..31c9d08ef 100644 --- a/test/storage/b_plus_tree_delete_test.cpp +++ b/test/storage/b_plus_tree_delete_test.cpp @@ -36,15 +36,13 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest1) { BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); std::vector keys = {1, 2, 3, 4, 5}; for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); } std::vector rids; @@ -61,7 +59,7 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest1) { std::vector remove_keys = {1, 5}; for (auto key : remove_keys) { index_key.SetFromInteger(key); - tree.Remove(index_key, transaction); + tree.Remove(index_key); } int64_t size = 0; @@ -81,10 +79,7 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest1) { size = size + 1; } } - EXPECT_EQ(size, 3); - - delete transaction; delete bpm; } @@ -101,15 +96,13 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest2) { BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); std::vector keys = {1, 2, 3, 4, 5}; for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); } std::vector rids; @@ -126,7 +119,7 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest2) { std::vector remove_keys = {1, 5, 3, 4}; for (auto key : remove_keys) { index_key.SetFromInteger(key); - tree.Remove(index_key, transaction); + tree.Remove(index_key); } int64_t size = 0; @@ -146,10 +139,7 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest2) { size = size + 1; } } - EXPECT_EQ(size, 1); - - delete transaction; delete bpm; } } // namespace bustub diff --git a/test/storage/b_plus_tree_insert_test.cpp b/test/storage/b_plus_tree_insert_test.cpp index 3267df7aa..1413c79ac 100644 --- a/test/storage/b_plus_tree_insert_test.cpp +++ b/test/storage/b_plus_tree_insert_test.cpp @@ -36,14 +36,12 @@ TEST(BPlusTreeTests, DISABLED_InsertTest1) { BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 2, 3); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); int64_t key = 42; int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); auto root_page_id = tree.GetRootPageId(); auto root_page_guard = bpm->ReadPage(root_page_id); @@ -55,7 +53,6 @@ TEST(BPlusTreeTests, DISABLED_InsertTest1) { ASSERT_EQ(root_as_leaf->GetSize(), 1); ASSERT_EQ(comparator(root_as_leaf->KeyAt(0), index_key), 0); - delete transaction; delete bpm; } @@ -72,15 +69,13 @@ TEST(BPlusTreeTests, DISABLED_InsertTest2) { BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 2, 3); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); std::vector keys = {1, 2, 3, 4, 5}; for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); } std::vector rids; @@ -108,10 +103,7 @@ TEST(BPlusTreeTests, DISABLED_InsertTest2) { EXPECT_EQ(rids[0].GetSlotNum(), key); size = size + 1; } - EXPECT_EQ(size, keys.size()); - - delete transaction; delete bpm; } @@ -128,15 +120,13 @@ TEST(BPlusTreeTests, DISABLED_InsertTest3) { BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); std::vector keys = {5, 4, 3, 2, 1}; for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); } std::vector rids; @@ -171,8 +161,6 @@ TEST(BPlusTreeTests, DISABLED_InsertTest3) { EXPECT_EQ(location.GetSlotNum(), current_key); current_key = current_key + 1; } - - delete transaction; delete bpm; } } // namespace bustub diff --git a/test/storage/b_plus_tree_sequential_scale_test.cpp b/test/storage/b_plus_tree_sequential_scale_test.cpp index ed093c496..32c9cde9c 100644 --- a/test/storage/b_plus_tree_sequential_scale_test.cpp +++ b/test/storage/b_plus_tree_sequential_scale_test.cpp @@ -42,8 +42,6 @@ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 2, 3); GenericKey<8> index_key; RID rid; - // create transaction - auto *transaction = new Transaction(0); int64_t scale = 5000; std::vector keys; @@ -58,7 +56,7 @@ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); } std::vector rids; for (auto key : keys) { @@ -71,7 +69,6 @@ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT ASSERT_EQ(rids[0].GetSlotNum(), value); } - delete transaction; delete bpm; } } // namespace bustub diff --git a/tools/b_plus_tree_printer/b_plus_tree_printer.cpp b/tools/b_plus_tree_printer/b_plus_tree_printer.cpp index 5e8c041fe..3ed2f584d 100644 --- a/tools/b_plus_tree_printer/b_plus_tree_printer.cpp +++ b/tools/b_plus_tree_printer/b_plus_tree_printer.cpp @@ -27,7 +27,6 @@ using bustub::GenericKey; using bustub::page_id_t; using bustub::ParseCreateStatement; using bustub::RID; -using bustub::Transaction; auto UsageMessage() -> std::string { std::string message = @@ -80,8 +79,7 @@ auto main(int argc, char **argv) -> int { // create b+ tree BPlusTree, RID, GenericComparator<8>> tree("foo_pk", root_pid, bpm, comparator, leaf_max_size, internal_max_size); - // create transaction - auto *transaction = new Transaction(0); + while (!quit) { std::cout << "> "; std::cin >> instruction; @@ -91,26 +89,26 @@ auto main(int argc, char **argv) -> int { switch (instruction) { case 'c': std::cin >> filename; - tree.RemoveFromFile(filename, transaction); + tree.RemoveFromFile(filename); break; case 'x': std::cin >> filename; - tree.BatchOpsFromFile(filename, transaction); + tree.BatchOpsFromFile(filename); break; case 'd': std::cin >> key; index_key.SetFromInteger(key); - tree.Remove(index_key, transaction); + tree.Remove(index_key); break; case 'i': std::cin >> key; rid.Set(static_cast(key >> 32), static_cast(key & 0xFFFFFFFF)); index_key.SetFromInteger(key); - tree.Insert(index_key, rid, transaction); + tree.Insert(index_key, rid); break; case 'f': std::cin >> filename; - tree.InsertFromFile(filename, transaction); + tree.InsertFromFile(filename); break; case 'q': quit = true; @@ -136,7 +134,7 @@ auto main(int argc, char **argv) -> int { BUSTUB_ASSERT(bpm->DeletePage(root_pid), "Unable to delete root page for some reason"); delete bpm; - delete transaction; + delete disk_manager; remove("test.bustub"); remove("test.log"); From d749a039bf2d1e08c3545253bfbdaaf49dec344a Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sun, 22 Sep 2024 00:02:31 -0400 Subject: [PATCH 02/22] sync b_plus_tree.h function param --- src/include/storage/index/b_plus_tree.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/include/storage/index/b_plus_tree.h b/src/include/storage/index/b_plus_tree.h index a2aa961d7..176fb5a28 100644 --- a/src/include/storage/index/b_plus_tree.h +++ b/src/include/storage/index/b_plus_tree.h @@ -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" @@ -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 *result, Transaction *txn = nullptr) -> bool; + auto GetValue(const KeyType &key, std::vector *result) -> bool; // Return the page id of the root node auto GetRootPageId() -> page_id_t; @@ -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 @@ -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!! */ From 7fade998d42b26341a711c1e1487d3aa0f242d0a Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sun, 22 Sep 2024 00:09:18 -0400 Subject: [PATCH 03/22] sync b plus tree function header --- src/storage/index/b_plus_tree.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/storage/index/b_plus_tree.cpp b/src/storage/index/b_plus_tree.cpp index 5da9cea98..f2b7b285b 100644 --- a/src/storage/index/b_plus_tree.cpp +++ b/src/storage/index/b_plus_tree.cpp @@ -37,7 +37,7 @@ auto BPLUSTREE_TYPE::IsEmpty() const -> bool { return true; } * @return : true means key exists */ INDEX_TEMPLATE_ARGUMENTS -auto BPLUSTREE_TYPE::GetValue(const KeyType &key, std::vector *result, Transaction *txn) -> bool { +auto BPLUSTREE_TYPE::GetValue(const KeyType &key, std::vector *result) -> bool { // Declaration of context instance. Context ctx; (void)ctx; @@ -55,7 +55,7 @@ auto BPLUSTREE_TYPE::GetValue(const KeyType &key, std::vector *result * keys return false, otherwise return true. */ INDEX_TEMPLATE_ARGUMENTS -auto BPLUSTREE_TYPE::Insert(const KeyType &key, const ValueType &value, Transaction *txn) -> bool { +auto BPLUSTREE_TYPE::Insert(const KeyType &key, const ValueType &value) -> bool { // Declaration of context instance. Context ctx; (void)ctx; @@ -73,7 +73,7 @@ auto BPLUSTREE_TYPE::Insert(const KeyType &key, const ValueType &value, Transact * necessary. */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::Remove(const KeyType &key, Transaction *txn) { +void BPLUSTREE_TYPE::Remove(const KeyType &key) { // Declaration of context instance. Context ctx; (void)ctx; @@ -121,14 +121,14 @@ auto BPLUSTREE_TYPE::GetRootPageId() -> page_id_t { return 0; } * Read data from file and insert one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name, Transaction *txn) { +void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name) { int64_t key; std::ifstream input(file_name); while (input >> key) { KeyType index_key; index_key.SetFromInteger(key); RID rid(key); - Insert(index_key, rid, txn); + Insert(index_key, rid); } } /* @@ -136,13 +136,13 @@ void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name, Tran * Read data from file and remove one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name, Transaction *txn) { +void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name) { int64_t key; std::ifstream input(file_name); while (input >> key) { KeyType index_key; index_key.SetFromInteger(key); - Remove(index_key, txn); + Remove(index_key); } } @@ -151,7 +151,7 @@ void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name, Tran * Read data from file and insert/remove one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name, Transaction *txn) { +void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name) { int64_t key; char instruction; std::ifstream input(file_name); @@ -162,10 +162,10 @@ void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name, Tr index_key.SetFromInteger(key); switch (instruction) { case 'i': - Insert(index_key, rid, txn); + Insert(index_key, rid); break; case 'd': - Remove(index_key, txn); + Remove(index_key); break; default: break; From 36e23020b23e04a4917208d509571a07154a4930 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sun, 22 Sep 2024 00:17:18 -0400 Subject: [PATCH 04/22] rm txn in btree bench --- tools/btree_bench/btree_bench.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/btree_bench/btree_bench.cpp b/tools/btree_bench/btree_bench.cpp index 1335343e8..732e5591a 100644 --- a/tools/btree_bench/btree_bench.cpp +++ b/tools/btree_bench/btree_bench.cpp @@ -153,7 +153,7 @@ auto main(int argc, char **argv) -> int { uint32_t value = key; rid.Set(value, value); index_key.SetFromInteger(key); - index.Insert(index_key, rid, nullptr); + index.Insert(index_key, rid); } fmt::print(stderr, "[info] benchmark start\n"); @@ -164,7 +164,7 @@ auto main(int argc, char **argv) -> int { std::vector threads; for (size_t thread_id = 0; thread_id < BUSTUB_READ_THREAD; thread_id++) { - threads.emplace_back(std::thread([thread_id, &index, duration_ms, &total_metrics] { + threads.emplace_back([thread_id, &index, duration_ms, &total_metrics] { BTreeMetrics metrics(fmt::format("read {:>2}", thread_id), duration_ms); metrics.Begin(); @@ -206,11 +206,11 @@ auto main(int argc, char **argv) -> int { } total_metrics.ReportRead(metrics.cnt_); - })); + }); } for (size_t thread_id = 0; thread_id < BUSTUB_WRITE_THREAD; thread_id++) { - threads.emplace_back(std::thread([thread_id, &index, duration_ms, &total_metrics] { + threads.emplace_back([thread_id, &index, duration_ms, &total_metrics] { BTreeMetrics metrics(fmt::format("write {:>2}", thread_id), duration_ms); metrics.Begin(); @@ -234,9 +234,9 @@ auto main(int argc, char **argv) -> int { rid.Set(value, value); index_key.SetFromInteger(key); if (do_insert) { - index.Insert(index_key, rid, nullptr); + index.Insert(index_key, rid); } else { - index.Remove(index_key, nullptr); + index.Remove(index_key); } metrics.Tick(); metrics.Report(); @@ -244,7 +244,7 @@ auto main(int argc, char **argv) -> int { uint32_t value = key; rid.Set(value, dis(gen)); index_key.SetFromInteger(key); - index.Insert(index_key, rid, nullptr); + index.Insert(index_key, rid); metrics.Tick(); metrics.Report(); } @@ -253,7 +253,7 @@ auto main(int argc, char **argv) -> int { } total_metrics.ReportWrite(metrics.cnt_); - })); + }); } for (auto &thread : threads) { From c6008e9ce71d040a914aab3ba66ceabac2b72cb8 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 16:43:07 -0400 Subject: [PATCH 05/22] nits --- src/container/disk/hash/disk_extendible_hash_table_utils.cpp | 2 +- src/storage/index/b_plus_tree_index.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/container/disk/hash/disk_extendible_hash_table_utils.cpp b/src/container/disk/hash/disk_extendible_hash_table_utils.cpp index 340a39c1d..7a55662b1 100644 --- a/src/container/disk/hash/disk_extendible_hash_table_utils.cpp +++ b/src/container/disk/hash/disk_extendible_hash_table_utils.cpp @@ -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 // //===----------------------------------------------------------------------===// diff --git a/src/storage/index/b_plus_tree_index.cpp b/src/storage/index/b_plus_tree_index.cpp index 20b8e4f95..4e22c124f 100644 --- a/src/storage/index/b_plus_tree_index.cpp +++ b/src/storage/index/b_plus_tree_index.cpp @@ -5,7 +5,7 @@ // // Identification: src/index/b_plus_tree_index.cpp // -// Copyright (c) 2018, Carnegie Mellon University Database Group +// Copyright (c) 2018-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// From bd0c47cf2b4974c6f8d650ae9a25568dc2336bea Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 16:45:35 -0400 Subject: [PATCH 06/22] decouple b plus tree debugging tool --- src/storage/index/b_plus_tree.cpp | 250 +---------------- src/storage/index/b_plus_tree_debug_tool.cpp | 269 +++++++++++++++++++ 2 files changed, 270 insertions(+), 249 deletions(-) create mode 100644 src/storage/index/b_plus_tree_debug_tool.cpp diff --git a/src/storage/index/b_plus_tree.cpp b/src/storage/index/b_plus_tree.cpp index f2b7b285b..42325a69b 100644 --- a/src/storage/index/b_plus_tree.cpp +++ b/src/storage/index/b_plus_tree.cpp @@ -5,6 +5,7 @@ #include "common/logger.h" #include "common/rid.h" #include "storage/index/b_plus_tree.h" +#include "storage/index/b_plus_tree_debug_tool.cpp" namespace bustub { @@ -112,255 +113,6 @@ auto BPLUSTREE_TYPE::End() -> INDEXITERATOR_TYPE { return INDEXITERATOR_TYPE(); INDEX_TEMPLATE_ARGUMENTS auto BPLUSTREE_TYPE::GetRootPageId() -> page_id_t { return 0; } -/***************************************************************************** - * 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 >> 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 >> key) { - KeyType index_key; - index_key.SetFromInteger(key); - Remove(index_key); - } -} - -/* - * 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 -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()); - } -} - -INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) { - if (page->IsLeafPage()) { - auto *leaf = reinterpret_cast(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(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); - 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()); - } - } -} - -/** - * 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(), 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(page); - // Print node name - out << leaf_prefix << page_id; - // Print node properties - out << "[shape=plain color=green "; - // Print data of the node - out << "label=<\n"; - // Print data - out << "\n"; - out << "\n"; - out << ""; - for (int i = 0; i < leaf->GetSize(); i++) { - out << "\n"; - } - out << ""; - // Print table end - out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" - << "max_size=" << leaf->GetMaxSize() << ",min_size=" << leaf->GetMinSize() << ",size=" << leaf->GetSize() - << "
" << leaf->KeyAt(i) << "
>];\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(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=<\n"; - // Print data - out << "\n"; - out << "\n"; - out << ""; - for (int i = 0; i < inner->GetSize(); i++) { - out << "\n"; - } - out << ""; - // Print table end - out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" - << "max_size=" << inner->GetMaxSize() << ",min_size=" << inner->GetMinSize() << ",size=" << inner->GetSize() - << "
ValueAt(i) << "\">"; - if (i > 0) { - out << inner->KeyAt(i); - } else { - out << " "; - } - out << "
>];\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(); - 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(); - 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(); -} - -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(); - PrintableBPlusTree proot; - - if (root_page->IsLeafPage()) { - auto leaf_page = root_page_guard.template As(); - 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(); - 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; -} - template class BPlusTree, RID, GenericComparator<4>>; template class BPlusTree, RID, GenericComparator<8>>; diff --git a/src/storage/index/b_plus_tree_debug_tool.cpp b/src/storage/index/b_plus_tree_debug_tool.cpp new file mode 100644 index 000000000..97269955d --- /dev/null +++ b/src/storage/index/b_plus_tree_debug_tool.cpp @@ -0,0 +1,269 @@ +//===----------------------------------------------------------------------===// +// +// BusTub +// +// b_plus_tree_debug_tool.cpp +// +// Identification: bustub/src/storage/index/b_plus_tree_debug_tool.cpp +// +// Copyright (c) 2024, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#include "common/logger.h" +#include "storage/index/b_plus_tree.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::string &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::string &file_name) { + int64_t key; + std::ifstream input(file_name); + while (input) { + input >> key; + KeyType index_key; + index_key.SetFromInteger(key); + Remove(index_key); + } +} + +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()); + } +} + +INDEX_TEMPLATE_ARGUMENTS +void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) { + if (page->IsLeafPage()) { + auto *leaf = reinterpret_cast(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(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); + 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()); + } + } +} + +/** + * 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(), 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(page); + // Print node name + out << leaf_prefix << page_id; + // Print node properties + out << "[shape=plain color=green "; + // Print data of the node + out << "label=<\n"; + // Print data + out << "\n"; + out << "\n"; + out << ""; + for (int i = 0; i < leaf->GetSize(); i++) { + out << "\n"; + } + out << ""; + // Print table end + out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" + << "max_size=" << leaf->GetMaxSize() << ",min_size=" << leaf->GetMinSize() << ",size=" << leaf->GetSize() + << "
" << leaf->KeyAt(i) << "
>];\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(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=<\n"; + // Print data + out << "\n"; + out << "\n"; + out << ""; + for (int i = 0; i < inner->GetSize(); i++) { + out << "\n"; + } + out << ""; + // Print table end + out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" + << "max_size=" << inner->GetMaxSize() << ",min_size=" << inner->GetMinSize() << ",size=" << inner->GetSize() + << "
ValueAt(i) << "\">"; + if (i > 0) { + out << inner->KeyAt(i); + } else { + out << " "; + } + out << "
>];\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(); + 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(); + 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::string &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(); + PrintableBPlusTree proot; + + if (root_page->IsLeafPage()) { + auto leaf_page = root_page_guard.template As(); + 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(); + 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 \ No newline at end of file From b0581b35fc0138ccd764596cd8716c2f8d533c0a Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 17:29:48 -0400 Subject: [PATCH 07/22] split array into two --- src/include/storage/index/index_iterator.h | 2 +- src/include/storage/page/b_plus_tree_internal_page.h | 8 +++++--- src/include/storage/page/b_plus_tree_leaf_page.h | 8 +++++--- src/storage/index/index_iterator.cpp | 4 +++- src/storage/page/b_plus_tree_internal_page.cpp | 12 ++++-------- src/storage/page/b_plus_tree_leaf_page.cpp | 10 +++------- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/include/storage/index/index_iterator.h b/src/include/storage/index/index_iterator.h index 7618823e1..56c04e01e 100644 --- a/src/include/storage/index/index_iterator.h +++ b/src/include/storage/index/index_iterator.h @@ -28,7 +28,7 @@ class IndexIterator { auto IsEnd() -> bool; - auto operator*() -> const MappingType &; + auto operator*() -> std::pair; auto operator++() -> IndexIterator &; diff --git a/src/include/storage/page/b_plus_tree_internal_page.h b/src/include/storage/page/b_plus_tree_internal_page.h index 29639b98b..54d4fbc4c 100644 --- a/src/include/storage/page/b_plus_tree_internal_page.h +++ b/src/include/storage/page/b_plus_tree_internal_page.h @@ -5,7 +5,7 @@ // // Identification: src/include/page/b_plus_tree_internal_page.h // -// Copyright (c) 2018, Carnegie Mellon University Database Group +// Copyright (c) 2018-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// #pragma once @@ -99,8 +99,10 @@ class BPlusTreeInternalPage : public BPlusTreePage { } private: - // Flexible array member for page data. - MappingType array_[0]; + // Flexible array members for page data. + KeyType key_array_[INTERNAL_PAGE_SIZE]; + ValueType value_array_[INTERNAL_PAGE_SIZE]; + // (Fall 2024) Feel free to add more fields and helper functions below if needed }; } // namespace bustub diff --git a/src/include/storage/page/b_plus_tree_leaf_page.h b/src/include/storage/page/b_plus_tree_leaf_page.h index d952647ac..8902687f8 100644 --- a/src/include/storage/page/b_plus_tree_leaf_page.h +++ b/src/include/storage/page/b_plus_tree_leaf_page.h @@ -5,7 +5,7 @@ // // Identification: src/include/page/b_plus_tree_leaf_page.h // -// Copyright (c) 2018, Carnegie Mellon University Database Group +// Copyright (c) 2018-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// #pragma once @@ -83,8 +83,10 @@ class BPlusTreeLeafPage : public BPlusTreePage { private: page_id_t next_page_id_; - // Flexible array member for page data. - MappingType array_[0]; + // Flexible array members for page data. + KeyType key_array_[LEAF_PAGE_SIZE]; + ValueType value_array_[LEAF_PAGE_SIZE]; + // (Fall 2024) Feel free to add more fields and helper functions below if needed }; } // namespace bustub diff --git a/src/storage/index/index_iterator.cpp b/src/storage/index/index_iterator.cpp index 3c2ee3ae6..b9ac2b71c 100644 --- a/src/storage/index/index_iterator.cpp +++ b/src/storage/index/index_iterator.cpp @@ -21,7 +21,9 @@ INDEX_TEMPLATE_ARGUMENTS auto INDEXITERATOR_TYPE::IsEnd() -> bool { throw std::runtime_error("unimplemented"); } INDEX_TEMPLATE_ARGUMENTS -auto INDEXITERATOR_TYPE::operator*() -> const MappingType & { throw std::runtime_error("unimplemented"); } +auto INDEXITERATOR_TYPE::operator*() -> std::pair { + throw std::runtime_error("unimplemented"); +} INDEX_TEMPLATE_ARGUMENTS auto INDEXITERATOR_TYPE::operator++() -> INDEXITERATOR_TYPE & { throw std::runtime_error("unimplemented"); } diff --git a/src/storage/page/b_plus_tree_internal_page.cpp b/src/storage/page/b_plus_tree_internal_page.cpp index e0ab2b33c..9be3b0b40 100644 --- a/src/storage/page/b_plus_tree_internal_page.cpp +++ b/src/storage/page/b_plus_tree_internal_page.cpp @@ -5,7 +5,7 @@ // // Identification: src/page/b_plus_tree_internal_page.cpp // -// Copyright (c) 2018, Carnegie Mellon University Database Group +// Copyright (c) 2018-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// @@ -26,21 +26,17 @@ namespace bustub { INDEX_TEMPLATE_ARGUMENTS void B_PLUS_TREE_INTERNAL_PAGE_TYPE::Init(int max_size) {} /* - * Helper method to get/set the key associated with input "index"(a.k.a + * Helper method to get/set the key associated with input "index" (a.k.a * array offset) */ INDEX_TEMPLATE_ARGUMENTS -auto B_PLUS_TREE_INTERNAL_PAGE_TYPE::KeyAt(int index) const -> KeyType { - // replace with your own code - KeyType key{}; - return key; -} +auto B_PLUS_TREE_INTERNAL_PAGE_TYPE::KeyAt(int index) const -> KeyType { return {}; } INDEX_TEMPLATE_ARGUMENTS void B_PLUS_TREE_INTERNAL_PAGE_TYPE::SetKeyAt(int index, const KeyType &key) {} /* - * Helper method to get the value associated with input "index"(a.k.a array + * Helper method to get the value associated with input "index" (a.k.a array * offset) */ INDEX_TEMPLATE_ARGUMENTS diff --git a/src/storage/page/b_plus_tree_leaf_page.cpp b/src/storage/page/b_plus_tree_leaf_page.cpp index 3b325d721..763eddb42 100644 --- a/src/storage/page/b_plus_tree_leaf_page.cpp +++ b/src/storage/page/b_plus_tree_leaf_page.cpp @@ -5,7 +5,7 @@ // // Identification: src/page/b_plus_tree_leaf_page.cpp // -// Copyright (c) 2018, Carnegie Mellon University Database Group +// Copyright (c) 2018-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// @@ -38,15 +38,11 @@ INDEX_TEMPLATE_ARGUMENTS void B_PLUS_TREE_LEAF_PAGE_TYPE::SetNextPageId(page_id_t next_page_id) {} /* - * Helper method to find and return the key associated with input "index"(a.k.a + * Helper method to find and return the key associated with input "index" (a.k.a * array offset) */ INDEX_TEMPLATE_ARGUMENTS -auto B_PLUS_TREE_LEAF_PAGE_TYPE::KeyAt(int index) const -> KeyType { - // replace with your own code - KeyType key{}; - return key; -} +auto B_PLUS_TREE_LEAF_PAGE_TYPE::KeyAt(int index) const -> KeyType { return {}; } template class BPlusTreeLeafPage, RID, GenericComparator<4>>; template class BPlusTreeLeafPage, RID, GenericComparator<8>>; From c050129721310099e72e492fffe3d05aa04ec402 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 17:32:09 -0400 Subject: [PATCH 08/22] fix make error --- src/storage/index/b_plus_tree_debug_tool.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storage/index/b_plus_tree_debug_tool.cpp b/src/storage/index/b_plus_tree_debug_tool.cpp index 97269955d..573ca89de 100644 --- a/src/storage/index/b_plus_tree_debug_tool.cpp +++ b/src/storage/index/b_plus_tree_debug_tool.cpp @@ -12,6 +12,7 @@ #include "common/logger.h" #include "storage/index/b_plus_tree.h" +#include "storage/page/b_plus_tree_page.h" namespace bustub { From eb7c06b3377e26f046ba76d3926c593d82af5008 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 17:40:35 -0400 Subject: [PATCH 09/22] fix debugging tool function param --- src/storage/index/b_plus_tree_debug_tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/index/b_plus_tree_debug_tool.cpp b/src/storage/index/b_plus_tree_debug_tool.cpp index 573ca89de..553edcbec 100644 --- a/src/storage/index/b_plus_tree_debug_tool.cpp +++ b/src/storage/index/b_plus_tree_debug_tool.cpp @@ -25,7 +25,7 @@ namespace bustub { * Read data from file and insert one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::InsertFromFile(const std::string &file_name) { +void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name) { int64_t key; std::ifstream input(file_name); while (input) { @@ -42,7 +42,7 @@ void BPLUSTREE_TYPE::InsertFromFile(const std::string &file_name) { * Read data from file and remove one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::RemoveFromFile(const std::string &file_name) { +void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name) { int64_t key; std::ifstream input(file_name); while (input) { From 298977bce20ca6578333dc45b225a94e9097dd0c Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 17:46:23 -0400 Subject: [PATCH 10/22] nits --- src/storage/index/b_plus_tree_debug_tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/index/b_plus_tree_debug_tool.cpp b/src/storage/index/b_plus_tree_debug_tool.cpp index 553edcbec..35b827cc8 100644 --- a/src/storage/index/b_plus_tree_debug_tool.cpp +++ b/src/storage/index/b_plus_tree_debug_tool.cpp @@ -218,7 +218,7 @@ auto BPLUSTREE_TYPE::DrawBPlusTree() -> std::string { * Read data from file and insert/remove one by one */ INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::BatchOpsFromFile(const std::string &file_name) { +void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name) { int64_t key; char instruction; std::ifstream input(file_name); From 39b18a2173a33834b3b9b02a41a4e6ca9c88c042 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 18:01:58 -0400 Subject: [PATCH 11/22] fix linting --- src/include/storage/index/index_iterator.h | 1 + src/storage/index/b_plus_tree.cpp | 2 +- src/storage/index/b_plus_tree_debug_tool.cpp | 270 ------------------- 3 files changed, 2 insertions(+), 271 deletions(-) delete mode 100644 src/storage/index/b_plus_tree_debug_tool.cpp diff --git a/src/include/storage/index/index_iterator.h b/src/include/storage/index/index_iterator.h index 56c04e01e..df0884aef 100644 --- a/src/include/storage/index/index_iterator.h +++ b/src/include/storage/index/index_iterator.h @@ -13,6 +13,7 @@ * For range scan of b+ tree */ #pragma once +#include #include "storage/page/b_plus_tree_leaf_page.h" namespace bustub { diff --git a/src/storage/index/b_plus_tree.cpp b/src/storage/index/b_plus_tree.cpp index 42325a69b..5ce2713ee 100644 --- a/src/storage/index/b_plus_tree.cpp +++ b/src/storage/index/b_plus_tree.cpp @@ -5,7 +5,7 @@ #include "common/logger.h" #include "common/rid.h" #include "storage/index/b_plus_tree.h" -#include "storage/index/b_plus_tree_debug_tool.cpp" +#include "storage/index/b_plus_tree_utils.h" namespace bustub { diff --git a/src/storage/index/b_plus_tree_debug_tool.cpp b/src/storage/index/b_plus_tree_debug_tool.cpp deleted file mode 100644 index 35b827cc8..000000000 --- a/src/storage/index/b_plus_tree_debug_tool.cpp +++ /dev/null @@ -1,270 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// BusTub -// -// b_plus_tree_debug_tool.cpp -// -// Identification: bustub/src/storage/index/b_plus_tree_debug_tool.cpp -// -// Copyright (c) 2024, Carnegie Mellon University Database Group -// -//===----------------------------------------------------------------------===// - -#include "common/logger.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); - } -} - -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()); - } -} - -INDEX_TEMPLATE_ARGUMENTS -void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) { - if (page->IsLeafPage()) { - auto *leaf = reinterpret_cast(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(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); - 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()); - } - } -} - -/** - * 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(), 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(page); - // Print node name - out << leaf_prefix << page_id; - // Print node properties - out << "[shape=plain color=green "; - // Print data of the node - out << "label=<\n"; - // Print data - out << "\n"; - out << "\n"; - out << ""; - for (int i = 0; i < leaf->GetSize(); i++) { - out << "\n"; - } - out << ""; - // Print table end - out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" - << "max_size=" << leaf->GetMaxSize() << ",min_size=" << leaf->GetMinSize() << ",size=" << leaf->GetSize() - << "
" << leaf->KeyAt(i) << "
>];\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(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=<\n"; - // Print data - out << "\n"; - out << "\n"; - out << ""; - for (int i = 0; i < inner->GetSize(); i++) { - out << "\n"; - } - out << ""; - // Print table end - out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" - << "max_size=" << inner->GetMaxSize() << ",min_size=" << inner->GetMinSize() << ",size=" << inner->GetSize() - << "
ValueAt(i) << "\">"; - if (i > 0) { - out << inner->KeyAt(i); - } else { - out << " "; - } - out << "
>];\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(); - 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(); - 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(); - PrintableBPlusTree proot; - - if (root_page->IsLeafPage()) { - auto leaf_page = root_page_guard.template As(); - 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(); - 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 \ No newline at end of file From 83ca9a01c6de401df63adba5b0965e6cad28fabb Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 18:02:18 -0400 Subject: [PATCH 12/22] fix linting --- src/include/storage/index/b_plus_tree_debug.h | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 src/include/storage/index/b_plus_tree_debug.h diff --git a/src/include/storage/index/b_plus_tree_debug.h b/src/include/storage/index/b_plus_tree_debug.h new file mode 100644 index 000000000..2165a0500 --- /dev/null +++ b/src/include/storage/index/b_plus_tree_debug.h @@ -0,0 +1,270 @@ +//===----------------------------------------------------------------------===// +// +// 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 "common/logger.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); + } +} + +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()); + } +} + +INDEX_TEMPLATE_ARGUMENTS +void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) { + if (page->IsLeafPage()) { + auto *leaf = reinterpret_cast(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(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); + 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()); + } + } +} + +/** + * 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(), 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(page); + // Print node name + out << leaf_prefix << page_id; + // Print node properties + out << "[shape=plain color=green "; + // Print data of the node + out << "label=<\n"; + // Print data + out << "\n"; + out << "\n"; + out << ""; + for (int i = 0; i < leaf->GetSize(); i++) { + out << "\n"; + } + out << ""; + // Print table end + out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" + << "max_size=" << leaf->GetMaxSize() << ",min_size=" << leaf->GetMinSize() << ",size=" << leaf->GetSize() + << "
" << leaf->KeyAt(i) << "
>];\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(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=<\n"; + // Print data + out << "\n"; + out << "\n"; + out << ""; + for (int i = 0; i < inner->GetSize(); i++) { + out << "\n"; + } + out << ""; + // Print table end + out << "
GetSize() << "\">P=" << page_id << "
GetSize() << "\">" + << "max_size=" << inner->GetMaxSize() << ",min_size=" << inner->GetMinSize() << ",size=" << inner->GetSize() + << "
ValueAt(i) << "\">"; + if (i > 0) { + out << inner->KeyAt(i); + } else { + out << " "; + } + out << "
>];\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(); + 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(); + 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(); + PrintableBPlusTree proot; + + if (root_page->IsLeafPage()) { + auto leaf_page = root_page_guard.template As(); + 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(); + 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 From d06f81e011ba2208beed78dba20df6bf7b304d4f Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 18:06:37 -0400 Subject: [PATCH 13/22] fix file path --- src/storage/index/b_plus_tree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/index/b_plus_tree.cpp b/src/storage/index/b_plus_tree.cpp index 5ce2713ee..78bdc75d1 100644 --- a/src/storage/index/b_plus_tree.cpp +++ b/src/storage/index/b_plus_tree.cpp @@ -5,7 +5,7 @@ #include "common/logger.h" #include "common/rid.h" #include "storage/index/b_plus_tree.h" -#include "storage/index/b_plus_tree_utils.h" +#include "storage/index/b_plus_tree_debug.h" namespace bustub { From e5cb76b0914669b7750bada819603cbca066f345 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 18:17:10 -0400 Subject: [PATCH 14/22] linting --- src/storage/index/b_plus_tree.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/storage/index/b_plus_tree.cpp b/src/storage/index/b_plus_tree.cpp index 78bdc75d1..f52603e06 100644 --- a/src/storage/index/b_plus_tree.cpp +++ b/src/storage/index/b_plus_tree.cpp @@ -1,9 +1,3 @@ -#include -#include - -#include "common/exception.h" -#include "common/logger.h" -#include "common/rid.h" #include "storage/index/b_plus_tree.h" #include "storage/index/b_plus_tree_debug.h" From 4b39ebea84b53b06e83a1acb69eef4241521dc4a Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Thu, 26 Sep 2024 18:17:28 -0400 Subject: [PATCH 15/22] linting --- src/include/storage/index/b_plus_tree_debug.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/include/storage/index/b_plus_tree_debug.h b/src/include/storage/index/b_plus_tree_debug.h index 2165a0500..2c4a0bd18 100644 --- a/src/include/storage/index/b_plus_tree_debug.h +++ b/src/include/storage/index/b_plus_tree_debug.h @@ -10,7 +10,12 @@ // //===----------------------------------------------------------------------===// +#include +#include + +#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" From e236e2c3b5dc8fb76f1e07b556bb3710abce6f47 Mon Sep 17 00:00:00 2001 From: Lan Lou Date: Sat, 28 Sep 2024 15:43:14 -0400 Subject: [PATCH 16/22] Modify P2 tests --- CMakeLists.txt | 21 +- test/include/storage/b_plus_tree_utils.h | 46 ++ test/storage/b_plus_tree_concurrent_test.cpp | 541 ++++++++++-------- test/storage/b_plus_tree_delete_test.cpp | 61 +- test/storage/b_plus_tree_insert_test.cpp | 2 +- .../b_plus_tree_sequential_scale_test.cpp | 2 +- 6 files changed, 432 insertions(+), 241 deletions(-) create mode 100644 test/include/storage/b_plus_tree_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ba563b77..87e7bc3c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/test/include/storage/b_plus_tree_utils.h b/test/include/storage/b_plus_tree_utils.h new file mode 100644 index 000000000..d85ae2985 --- /dev/null +++ b/test/include/storage/b_plus_tree_utils.h @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// BusTub +// +// b_plus_tree_utils.h +// +// Identification: test/include/storage/b_plus_tree_utils.h +// +// Copyright (c) 2015-2024, Carnegie Mellon University Database Group +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include + +#include "buffer/buffer_pool_manager.h" +#include "storage/index/b_plus_tree.h" + +namespace bustub { + +template +bool TreeValuesMatch(BPlusTree &tree, std::vector &inserted, + std::vector &deleted) { + std::vector rids; + KeyType index_key; + for (auto &key : inserted) { + rids.clear(); + index_key.SetFromInteger(key); + tree.GetValue(index_key, &rids); + if (rids.size() != 1) { + return false; + } + } + for (auto &key : deleted) { + rids.clear(); + index_key.SetFromInteger(key); + tree.GetValue(index_key, &rids); + if (rids.size() != 0) { + return false; + } + } + return true; +} + +} // namespace bustub diff --git a/test/storage/b_plus_tree_concurrent_test.cpp b/test/storage/b_plus_tree_concurrent_test.cpp index e36bc3701..3ac721c34 100644 --- a/test/storage/b_plus_tree_concurrent_test.cpp +++ b/test/storage/b_plus_tree_concurrent_test.cpp @@ -6,7 +6,7 @@ // // Identification: test/storage/b_plus_tree_concurrent_test.cpp // -// Copyright (c) 2015-2021, Carnegie Mellon University Database Group +// Copyright (c) 2015-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// @@ -108,271 +108,356 @@ void LookupHelper(BPlusTree, RID, GenericComparator<8>> *tree, con } } -TEST(BPlusTreeConcurrentTest, DISABLED_InsertTest1) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); - - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - // keys to Insert - std::vector keys; - int64_t scale_factor = 100; - for (int64_t key = 1; key < scale_factor; key++) { - keys.push_back(key); - } - LaunchParallelTest(2, InsertHelper, &tree, keys); +const size_t NUM_ITERS = 50; +const size_t MIXTEST_NUM_ITERS = 20; +static const size_t BPM_SIZE = 50; - std::vector rids; - GenericKey<8> index_key; - for (auto key : keys) { - rids.clear(); - index_key.SetFromInteger(key); - tree.GetValue(index_key, &rids); - EXPECT_EQ(rids.size(), 1); +void InsertTest1Call() { + for (size_t iter = 0; iter < NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); - int64_t value = key & 0xFFFFFFFF; - EXPECT_EQ(rids[0].GetSlotNum(), value); - } + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); - int64_t start_key = 1; - int64_t current_key = start_key; - index_key.SetFromInteger(start_key); - for (auto iterator = tree.Begin(index_key); iterator != tree.End(); ++iterator) { - auto location = (*iterator).second; - EXPECT_EQ(location.GetPageId(), 0); - EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; - } + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); - EXPECT_EQ(current_key, keys.size() + 1); + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 3, 5); - delete bpm; -} + // keys to Insert + std::vector keys; + int64_t scale_factor = 100; + for (int64_t key = 1; key < scale_factor; key++) { + keys.push_back(key); + } + LaunchParallelTest(2, 0, InsertHelper, &tree, keys); -TEST(BPlusTreeConcurrentTest, DISABLED_InsertTest2) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - // keys to Insert - std::vector keys; - int64_t scale_factor = 100; - for (int64_t key = 1; key < scale_factor; key++) { - keys.push_back(key); - } - LaunchParallelTest(2, InsertHelperSplit, &tree, keys, 2); + std::vector rids; + GenericKey<8> index_key; + for (auto key : keys) { + rids.clear(); + index_key.SetFromInteger(key); + tree.GetValue(index_key, &rids); + ASSERT_EQ(rids.size(), 1); - std::vector rids; - GenericKey<8> index_key; - for (auto key : keys) { - rids.clear(); - index_key.SetFromInteger(key); - tree.GetValue(index_key, &rids); - EXPECT_EQ(rids.size(), 1); + int64_t value = key & 0xFFFFFFFF; + ASSERT_EQ(rids[0].GetSlotNum(), value); + } - int64_t value = key & 0xFFFFFFFF; - EXPECT_EQ(rids[0].GetSlotNum(), value); - } + int64_t start_key = 1; + int64_t current_key = start_key; - int64_t start_key = 1; - int64_t current_key = start_key; - index_key.SetFromInteger(start_key); - for (auto iterator = tree.Begin(index_key); iterator != tree.End(); ++iterator) { - auto location = (*iterator).second; - EXPECT_EQ(location.GetPageId(), 0); - EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; - } + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + auto location = pair.second; + ASSERT_EQ(location.GetPageId(), 0); + ASSERT_EQ(location.GetSlotNum(), current_key); + current_key = current_key + 1; + } - EXPECT_EQ(current_key, keys.size() + 1); + ASSERT_EQ(current_key, keys.size() + 1); - delete bpm; + delete disk_manager; + delete bpm; + remove("test.db"); + remove("test.log"); + } } -TEST(BPlusTreeConcurrentTest, DISABLED_DeleteTest1) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); +void InsertTest2Call() { + for (size_t iter = 0; iter < NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); - GenericKey<8> index_key; - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - // sequential insert - std::vector keys = {1, 2, 3, 4, 5}; - InsertHelper(&tree, keys); - - std::vector remove_keys = {1, 5, 3, 4}; - LaunchParallelTest(2, DeleteHelper, &tree, remove_keys); - - int64_t start_key = 2; - int64_t current_key = start_key; - int64_t size = 0; - index_key.SetFromInteger(start_key); - for (auto iterator = tree.Begin(index_key); iterator != tree.End(); ++iterator) { - auto location = (*iterator).second; - EXPECT_EQ(location.GetPageId(), 0); - EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; - size = size + 1; - } + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); - EXPECT_EQ(size, 1); + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 3, 5); - delete bpm; -} + // keys to Insert + std::vector keys; + int64_t scale_factor = 1000; + for (int64_t key = 1; key < scale_factor; key++) { + keys.push_back(key); + } + LaunchParallelTest(2, 0, InsertHelperSplit, &tree, keys, 2); + + std::vector rids; + GenericKey<8> index_key; + for (auto key : keys) { + rids.clear(); + index_key.SetFromInteger(key); + tree.GetValue(index_key, &rids); + ASSERT_EQ(rids.size(), 1); -TEST(BPlusTreeConcurrentTest, DISABLED_DeleteTest2) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); + int64_t value = key & 0xFFFFFFFF; + ASSERT_EQ(rids[0].GetSlotNum(), value); + } - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); - GenericKey<8> index_key; - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - - // sequential insert - std::vector keys = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - InsertHelper(&tree, keys); - - std::vector remove_keys = {1, 4, 3, 2, 5, 6}; - LaunchParallelTest(2, DeleteHelperSplit, &tree, remove_keys, 2); - - int64_t start_key = 7; - int64_t current_key = start_key; - int64_t size = 0; - index_key.SetFromInteger(start_key); - for (auto iterator = tree.Begin(index_key); iterator != tree.End(); ++iterator) { - auto location = (*iterator).second; - EXPECT_EQ(location.GetPageId(), 0); - EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; - size = size + 1; - } + int64_t start_key = 1; + int64_t current_key = start_key; - EXPECT_EQ(size, 4); + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + auto location = pair.second; + ASSERT_EQ(location.GetPageId(), 0); + ASSERT_EQ(location.GetSlotNum(), current_key); + current_key = current_key + 1; + } + + ASSERT_EQ(current_key, keys.size() + 1); - delete bpm; + delete disk_manager; + delete bpm; + remove("test.db"); + remove("test.log"); + } } -TEST(BPlusTreeConcurrentTest, DISABLED_MixTest1) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); +void DeleteTest1Call() { + for (size_t iter = 0; iter < NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - GenericKey<8> index_key; - // first, populate index - std::vector keys = {1, 2, 3, 4, 5}; - InsertHelper(&tree, keys); - - // concurrent insert - keys.clear(); - for (int i = 6; i <= 10; i++) { - keys.push_back(i); - } - LaunchParallelTest(1, InsertHelper, &tree, keys); - // concurrent delete - std::vector remove_keys = {1, 4, 3, 5, 6}; - LaunchParallelTest(1, DeleteHelper, &tree, remove_keys); - - int64_t start_key = 2; - int64_t size = 0; - index_key.SetFromInteger(start_key); - for (auto iterator = tree.Begin(index_key); iterator != tree.End(); ++iterator) { - size = size + 1; - } + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); - EXPECT_EQ(size, 5); + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 3, 5); - delete bpm; -} + // sequential insert + std::vector keys = {1, 2, 3, 4, 5}; + InsertHelper(&tree, keys, 1); + + std::vector remove_keys = {1, 5, 3, 4}; + LaunchParallelTest(2, 1, DeleteHelper, &tree, remove_keys); -TEST(BPlusTreeConcurrentTest, DISABLED_MixTest2) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); - - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); - - // allocate header_page - page_id_t page_id = bpm->NewPage(); - - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - - // Add perserved_keys - std::vector perserved_keys; - std::vector dynamic_keys; - int64_t total_keys = 50; - int64_t sieve = 5; - for (int64_t i = 1; i <= total_keys; i++) { - if (i % sieve == 0) { - perserved_keys.push_back(i); - } else { - dynamic_keys.push_back(i); + int64_t start_key = 2; + int64_t current_key = start_key; + int64_t size = 0; + + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + auto location = pair.second; + ASSERT_EQ(location.GetPageId(), 0); + ASSERT_EQ(location.GetSlotNum(), current_key); + current_key = current_key + 1; + size = size + 1; } + + ASSERT_EQ(size, 1); + + delete disk_manager; + delete bpm; + remove("test.db"); + remove("test.log"); } - InsertHelper(&tree, perserved_keys, 1); - // Check there are 1000 keys in there - size_t size; - - auto insert_task = [&](int tid) { InsertHelper(&tree, dynamic_keys, tid); }; - auto delete_task = [&](int tid) { DeleteHelper(&tree, dynamic_keys, tid); }; - auto lookup_task = [&](int tid) { LookupHelper(&tree, perserved_keys, tid); }; - - std::vector threads; - std::vector> tasks; - tasks.emplace_back(insert_task); - tasks.emplace_back(delete_task); - tasks.emplace_back(lookup_task); - - size_t num_threads = 6; - for (size_t i = 0; i < num_threads; i++) { - threads.emplace_back(tasks[i % tasks.size()], i); - } - for (size_t i = 0; i < num_threads; i++) { - threads[i].join(); +} + +void DeleteTest2Call() { + for (size_t iter = 0; iter < NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); + + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); + + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); + + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 3, 5); + + // sequential insert + std::vector keys = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + InsertHelper(&tree, keys, 1); + + std::vector remove_keys = {1, 4, 3, 2, 5, 6}; + LaunchParallelTest(2, 1, DeleteHelperSplit, &tree, remove_keys, 2); + + int64_t start_key = 7; + int64_t current_key = start_key; + int64_t size = 0; + + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + auto location = pair.second; + ASSERT_EQ(location.GetPageId(), 0); + ASSERT_EQ(location.GetSlotNum(), current_key); + current_key = current_key + 1; + size = size + 1; + } + + ASSERT_EQ(size, 4); + + delete disk_manager; + delete bpm; + remove("test.db"); + remove("test.log"); } +} + +void MixTest1Call() { + for (size_t iter = 0; iter < MIXTEST_NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); + + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); + + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); + + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, 3, 5); + + // first, populate index + std::vector for_insert; + std::vector for_delete; + int64_t sieve = 2; // divide evenly + int64_t total_keys = 1000; + for (int64_t i = 1; i <= total_keys; i++) { + if (i % sieve == 0) { + for_insert.push_back(i); + } else { + for_delete.push_back(i); + } + } + // Insert all the keys to delete + InsertHelper(&tree, for_delete, 1); + + auto insert_task = [&](int tid) { InsertHelper(&tree, for_insert, tid); }; + auto delete_task = [&](int tid) { DeleteHelper(&tree, for_delete, tid); }; + std::vector> tasks; + tasks.emplace_back(insert_task); + tasks.emplace_back(delete_task); + std::vector threads; + size_t num_threads = 10; + for (size_t i = 0; i < num_threads; i++) { + threads.emplace_back(tasks[i % tasks.size()], i); + } + for (size_t i = 0; i < num_threads; i++) { + threads[i].join(); + } - // Check all reserved keys exist - size = 0; + int64_t size = 0; - for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { - const auto &pair = *iter; - if ((pair.first).ToString() % sieve == 0) { + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + ASSERT_EQ((pair.first).ToString(), for_insert[size]); size++; } + + ASSERT_EQ(size, for_insert.size()); + + delete disk_manager; + delete bpm; + remove("test.db"); + remove("test.log"); } +} + +void MixTest2Call() { + for (size_t iter = 0; iter < MIXTEST_NUM_ITERS; iter++) { + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); + + auto *disk_manager = new DiskManagerUnlimitedMemory(); + auto *bpm = new BufferPoolManager(BPM_SIZE, disk_manager); + + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); + + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); + + // Add perserved_keys + std::vector perserved_keys; + std::vector dynamic_keys; + int64_t total_keys = 1000; + int64_t sieve = 5; + for (int64_t i = 1; i <= total_keys; i++) { + if (i % sieve == 0) { + perserved_keys.push_back(i); + } else { + dynamic_keys.push_back(i); + } + } + InsertHelper(&tree, perserved_keys, 1); + // Check there are 1000 keys in there + size_t size; + + auto insert_task = [&](int tid) { InsertHelper(&tree, dynamic_keys, tid); }; + auto delete_task = [&](int tid) { DeleteHelper(&tree, dynamic_keys, tid); }; + auto lookup_task = [&](int tid) { LookupHelper(&tree, perserved_keys, tid); }; + + std::vector threads; + std::vector> tasks; + tasks.emplace_back(insert_task); + tasks.emplace_back(delete_task); + tasks.emplace_back(lookup_task); + + size_t num_threads = 6; + for (size_t i = 0; i < num_threads; i++) { + threads.emplace_back(tasks[i % tasks.size()], i); + } + for (size_t i = 0; i < num_threads; i++) { + threads[i].join(); + } + + // Check all reserved keys exist + size = 0; + + for (auto iter = tree.Begin(); iter != tree.End(); ++iter) { + const auto &pair = *iter; + if ((pair.first).ToString() % sieve == 0) { + size++; + } + } + + ASSERT_EQ(size, perserved_keys.size()); + + delete disk_manager; + delete bpm; + } +} + +TEST(BPlusTreeConcurrentTest, DISABLED_InsertTest1) { // NOLINT + InsertTest1Call(); +} + +TEST(BPlusTreeConcurrentTest, DISABLED_InsertTest2) { // NOLINT + InsertTest2Call(); +} - ASSERT_EQ(size, perserved_keys.size()); +TEST(BPlusTreeConcurrentTest, DISABLED_DeleteTest1) { // NOLINT + DeleteTest1Call(); +} - delete bpm; +TEST(BPlusTreeConcurrentTest, DISABLED_DeleteTest2) { // NOLINT + DeleteTest2Call(); } +TEST(BPlusTreeConcurrentTest, DISABLED_MixTest1) { // NOLINT + MixTest1Call(); +} + +TEST(BPlusTreeConcurrentTest, DISABLED_MixTest2) { // NOLINT + MixTest2Call(); +} } // namespace bustub diff --git a/test/storage/b_plus_tree_delete_test.cpp b/test/storage/b_plus_tree_delete_test.cpp index 31c9d08ef..6c03da985 100644 --- a/test/storage/b_plus_tree_delete_test.cpp +++ b/test/storage/b_plus_tree_delete_test.cpp @@ -6,7 +6,7 @@ // // Identification: test/storage/b_plus_tree_delete_test.cpp // -// Copyright (c) 2015-2021, Carnegie Mellon University Database Group +// Copyright (c) 2015-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// @@ -15,6 +15,7 @@ #include "buffer/buffer_pool_manager.h" #include "gtest/gtest.h" +#include "storage/b_plus_tree_utils.h" #include "storage/disk/disk_manager_memory.h" #include "storage/index/b_plus_tree.h" #include "test_util.h" // NOLINT @@ -142,4 +143,62 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest2) { EXPECT_EQ(size, 1); delete bpm; } + +TEST(BPlusTreeTests, DISABLED_SequentialEdgeMixTest) { // NOLINT + // create KeyComparator and index schema + auto key_schema = ParseCreateStatement("a bigint"); + GenericComparator<8> comparator(key_schema.get()); + + auto disk_manager = std::make_unique(); + auto *bpm = new BufferPoolManager(50, disk_manager.get()); + + for (int leaf_max_size = 2; leaf_max_size <= 5; leaf_max_size++) { + // create and fetch header_page + page_id_t page_id = bpm->NewPage(); + + // create b+ tree + BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator, leaf_max_size, 3); + GenericKey<8> index_key; + RID rid; + + std::vector keys = {1, 5, 15, 20, 25, 2, -1, -2, 6, 14, 4}; + std::vector inserted = {}; + std::vector deleted = {}; + for (auto key : keys) { + int64_t value = key & 0xFFFFFFFF; + rid.Set(static_cast(key >> 32), value); + index_key.SetFromInteger(key); + tree.Insert(index_key, rid); + inserted.push_back(key); + auto res = TreeValuesMatch, RID, GenericComparator<8>>(tree, inserted, deleted); + ASSERT_TRUE(res); + } + + index_key.SetFromInteger(1); + tree.Remove(index_key); + deleted.push_back(1); + inserted.erase(std::find(inserted.begin(), inserted.end(), 1)); + auto res = TreeValuesMatch, RID, GenericComparator<8>>(tree, inserted, deleted); + ASSERT_TRUE(res); + + index_key.SetFromInteger(3); + rid.Set(3, 3); + tree.Insert(index_key, rid); + inserted.push_back(3); + res = TreeValuesMatch, RID, GenericComparator<8>>(tree, inserted, deleted); + ASSERT_TRUE(res); + + keys = {4, 14, 6, 2, 15, -2, -1, 3, 5, 25, 20}; + for (auto key : keys) { + index_key.SetFromInteger(key); + tree.Remove(index_key); + deleted.push_back(key); + inserted.erase(std::find(inserted.begin(), inserted.end(), key)); + res = TreeValuesMatch, RID, GenericComparator<8>>(tree, inserted, deleted); + ASSERT_TRUE(res); + } + } + + delete bpm; +} } // namespace bustub diff --git a/test/storage/b_plus_tree_insert_test.cpp b/test/storage/b_plus_tree_insert_test.cpp index 1413c79ac..f3b06efac 100644 --- a/test/storage/b_plus_tree_insert_test.cpp +++ b/test/storage/b_plus_tree_insert_test.cpp @@ -6,7 +6,7 @@ // // Identification: test/storage/b_plus_tree_insert_test.cpp // -// Copyright (c) 2015-2021, Carnegie Mellon University Database Group +// Copyright (c) 2015-2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// diff --git a/test/storage/b_plus_tree_sequential_scale_test.cpp b/test/storage/b_plus_tree_sequential_scale_test.cpp index 32c9cde9c..6957be5ad 100644 --- a/test/storage/b_plus_tree_sequential_scale_test.cpp +++ b/test/storage/b_plus_tree_sequential_scale_test.cpp @@ -6,7 +6,7 @@ // // Identification: test/storage/b_plus_tree_sequential_scale_test.cpp // -// Copyright (c) 2023, Carnegie Mellon University Database Group +// Copyright (c) 2024, Carnegie Mellon University Database Group // //===----------------------------------------------------------------------===// From d3591ba20eefd5ae5a1c317d8ac0f4340b15c79e Mon Sep 17 00:00:00 2001 From: Lan Lou Date: Sat, 28 Sep 2024 16:29:46 -0400 Subject: [PATCH 17/22] fix concurrent test --- test/storage/b_plus_tree_concurrent_test.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/storage/b_plus_tree_concurrent_test.cpp b/test/storage/b_plus_tree_concurrent_test.cpp index 3ac721c34..dcc812f85 100644 --- a/test/storage/b_plus_tree_concurrent_test.cpp +++ b/test/storage/b_plus_tree_concurrent_test.cpp @@ -12,7 +12,9 @@ #include // NOLINT #include +#include #include +#include // NOLINT #include // NOLINT #include "buffer/buffer_pool_manager.h" @@ -27,12 +29,12 @@ using bustub::DiskManagerUnlimitedMemory; // helper function to launch multiple threads template -void LaunchParallelTest(uint64_t num_threads, Args &&...args) { +void LaunchParallelTest(uint64_t num_threads, uint64_t txn_id_start, Args &&...args) { std::vector thread_group; // Launch a group of threads for (uint64_t thread_itr = 0; thread_itr < num_threads; ++thread_itr) { - thread_group.push_back(std::thread(args..., thread_itr)); + thread_group.push_back(std::thread(args..., txn_id_start + thread_itr, thread_itr)); } // Join the threads with the main thread @@ -43,9 +45,10 @@ void LaunchParallelTest(uint64_t num_threads, Args &&...args) { // helper function to insert void InsertHelper(BPlusTree, RID, GenericComparator<8>> *tree, const std::vector &keys, - __attribute__((unused)) uint64_t thread_itr = 0) { + uint64_t tid, __attribute__((unused)) uint64_t thread_itr = 0) { GenericKey<8> index_key; RID rid; + for (auto key : keys) { int64_t value = key & 0xFFFFFFFF; rid.Set(static_cast(key >> 32), value); @@ -56,9 +59,10 @@ void InsertHelper(BPlusTree, RID, GenericComparator<8>> *tree, con // helper function to seperate insert void InsertHelperSplit(BPlusTree, RID, GenericComparator<8>> *tree, const std::vector &keys, - int total_threads, __attribute__((unused)) uint64_t thread_itr) { + int total_threads, uint64_t tid, __attribute__((unused)) uint64_t thread_itr) { GenericKey<8> index_key; RID rid; + for (auto key : keys) { if (static_cast(key) % total_threads == thread_itr) { int64_t value = key & 0xFFFFFFFF; @@ -71,8 +75,9 @@ void InsertHelperSplit(BPlusTree, RID, GenericComparator<8>> *tree // helper function to delete void DeleteHelper(BPlusTree, RID, GenericComparator<8>> *tree, const std::vector &remove_keys, - __attribute__((unused)) uint64_t thread_itr = 0) { + uint64_t tid, __attribute__((unused)) uint64_t thread_itr = 0) { GenericKey<8> index_key; + for (auto key : remove_keys) { index_key.SetFromInteger(key); tree->Remove(index_key); @@ -81,9 +86,10 @@ void DeleteHelper(BPlusTree, RID, GenericComparator<8>> *tree, con // helper function to seperate delete void DeleteHelperSplit(BPlusTree, RID, GenericComparator<8>> *tree, - const std::vector &remove_keys, int total_threads, + const std::vector &remove_keys, int total_threads, uint64_t tid, __attribute__((unused)) uint64_t thread_itr) { GenericKey<8> index_key; + for (auto key : remove_keys) { if (static_cast(key) % total_threads == thread_itr) { index_key.SetFromInteger(key); From 770d896cb63ca48d41864d0ee9adb3ee02c0db8f Mon Sep 17 00:00:00 2001 From: Lan Lou Date: Sat, 28 Sep 2024 16:51:18 -0400 Subject: [PATCH 18/22] fix clang-tidy --- test/include/storage/b_plus_tree_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/include/storage/b_plus_tree_utils.h b/test/include/storage/b_plus_tree_utils.h index d85ae2985..25506135c 100644 --- a/test/include/storage/b_plus_tree_utils.h +++ b/test/include/storage/b_plus_tree_utils.h @@ -36,7 +36,7 @@ bool TreeValuesMatch(BPlusTree &tree, std::vec rids.clear(); index_key.SetFromInteger(key); tree.GetValue(index_key, &rids); - if (rids.size() != 0) { + if (!rids.empty()) { return false; } } From cd984b04c0ffb27fda55470b8f57717f830a4a03 Mon Sep 17 00:00:00 2001 From: Lan Lou Date: Sat, 28 Sep 2024 17:52:14 -0400 Subject: [PATCH 19/22] Modify header size --- .../storage/page/b_plus_tree_internal_page.h | 14 ++++++++--- .../storage/page/b_plus_tree_leaf_page.h | 25 +++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/include/storage/page/b_plus_tree_internal_page.h b/src/include/storage/page/b_plus_tree_internal_page.h index 54d4fbc4c..8dd8ea46a 100644 --- a/src/include/storage/page/b_plus_tree_internal_page.h +++ b/src/include/storage/page/b_plus_tree_internal_page.h @@ -19,7 +19,7 @@ namespace bustub { #define B_PLUS_TREE_INTERNAL_PAGE_TYPE BPlusTreeInternalPage #define INTERNAL_PAGE_HEADER_SIZE 12 -#define INTERNAL_PAGE_SIZE ((BUSTUB_PAGE_SIZE - INTERNAL_PAGE_HEADER_SIZE) / (sizeof(MappingType))) +#define INTERNAL_PAGE_SIZE ((BUSTUB_PAGE_SIZE - INTERNAL_PAGE_HEADER_SIZE) / ((int)(sizeof(KeyType) + sizeof(ValueType)))) // NOLINT /** * Store `n` indexed keys and `n + 1` child pointers (page_id) within internal page. @@ -30,9 +30,15 @@ namespace bustub { * should ignore the first key. * * Internal page format (keys are stored in increasing order): - * ---------------------------------------------------------------------------------- - * | HEADER | KEY(1) + PAGE_ID(1) | KEY(2) + PAGE_ID(2) | ... | KEY(n) + PAGE_ID(n) | - * ---------------------------------------------------------------------------------- + * --------- + * | HEADER | + * --------- + * --------------------------------- + * | KEY(1) | KEY(2) | ... | KEY(n) | + * --------------------------------- + * --------------------------------------------- + * | PAGE_ID(1) | PAGE_ID(2) | ... | PAGE_ID(n) | + * --------------------------------------------- */ INDEX_TEMPLATE_ARGUMENTS class BPlusTreeInternalPage : public BPlusTreePage { diff --git a/src/include/storage/page/b_plus_tree_leaf_page.h b/src/include/storage/page/b_plus_tree_leaf_page.h index 8902687f8..0f8e9d217 100644 --- a/src/include/storage/page/b_plus_tree_leaf_page.h +++ b/src/include/storage/page/b_plus_tree_leaf_page.h @@ -20,7 +20,7 @@ namespace bustub { #define B_PLUS_TREE_LEAF_PAGE_TYPE BPlusTreeLeafPage #define LEAF_PAGE_HEADER_SIZE 16 -#define LEAF_PAGE_SIZE ((BUSTUB_PAGE_SIZE - LEAF_PAGE_HEADER_SIZE) / sizeof(MappingType)) +#define LEAF_PAGE_SIZE ((BUSTUB_PAGE_SIZE - LEAF_PAGE_HEADER_SIZE) / (sizeof(KeyType) + sizeof(ValueType))) /** * Store indexed key and record id (record id = page id combined with slot id, @@ -28,14 +28,23 @@ namespace bustub { * page. Only support unique key. * * Leaf page format (keys are stored in order): - * ----------------------------------------------------------------------- - * | HEADER | KEY(1) + RID(1) | KEY(2) + RID(2) | ... | KEY(n) + RID(n) | - * ----------------------------------------------------------------------- + * --------- + * | HEADER | + * --------- + * --------------------------------- + * | KEY(1) | KEY(2) | ... | KEY(n) | + * --------------------------------- + * --------------------------------- + * | RID(1) | RID(2) | ... | RID(n) | + * --------------------------------- * - * Header format (size in byte, 16 bytes in total): - * ----------------------------------------------------------------------- - * | PageType (4) | CurrentSize (4) | MaxSize (4) | NextPageId (4) | ... | - * ----------------------------------------------------------------------- + * Header format (size in byte, 16 bytes in total): + * ----------------------------------------------- + * | PageType (4) | CurrentSize (4) | MaxSize (4) | + * ----------------------------------------------- + * ----------------- + * | NextPageId (4) | + * ----------------- */ INDEX_TEMPLATE_ARGUMENTS class BPlusTreeLeafPage : public BPlusTreePage { From a9c460cd6166aae39839d3f56b09cf4a5540da57 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sat, 28 Sep 2024 17:58:21 -0400 Subject: [PATCH 20/22] Update comments --- src/include/storage/page/b_plus_tree_internal_page.h | 7 ++++--- src/include/storage/page/b_plus_tree_leaf_page.h | 2 +- src/include/storage/page/b_plus_tree_page.h | 4 +++- src/storage/page/b_plus_tree_page.cpp | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/include/storage/page/b_plus_tree_internal_page.h b/src/include/storage/page/b_plus_tree_internal_page.h index 8dd8ea46a..bf3036bbd 100644 --- a/src/include/storage/page/b_plus_tree_internal_page.h +++ b/src/include/storage/page/b_plus_tree_internal_page.h @@ -19,14 +19,15 @@ namespace bustub { #define B_PLUS_TREE_INTERNAL_PAGE_TYPE BPlusTreeInternalPage #define INTERNAL_PAGE_HEADER_SIZE 12 -#define INTERNAL_PAGE_SIZE ((BUSTUB_PAGE_SIZE - INTERNAL_PAGE_HEADER_SIZE) / ((int)(sizeof(KeyType) + sizeof(ValueType)))) // NOLINT +#define INTERNAL_PAGE_SIZE \ + ((BUSTUB_PAGE_SIZE - INTERNAL_PAGE_HEADER_SIZE) / ((int)(sizeof(KeyType) + sizeof(ValueType)))) // NOLINT /** * Store `n` indexed keys and `n + 1` child pointers (page_id) within internal page. * Pointer PAGE_ID(i) points to a subtree in which all keys K satisfy: * K(i) <= K < K(i+1). * NOTE: Since the number of keys does not equal to number of child pointers, - * the first key always remains invalid. That is to say, any search / lookup + * the first key in key_array_ always remains invalid. That is to say, any search / lookup * should ignore the first key. * * Internal page format (keys are stored in increasing order): @@ -105,7 +106,7 @@ class BPlusTreeInternalPage : public BPlusTreePage { } private: - // Flexible array members for page data. + // Array members for page data. KeyType key_array_[INTERNAL_PAGE_SIZE]; ValueType value_array_[INTERNAL_PAGE_SIZE]; // (Fall 2024) Feel free to add more fields and helper functions below if needed diff --git a/src/include/storage/page/b_plus_tree_leaf_page.h b/src/include/storage/page/b_plus_tree_leaf_page.h index 0f8e9d217..1ef099c07 100644 --- a/src/include/storage/page/b_plus_tree_leaf_page.h +++ b/src/include/storage/page/b_plus_tree_leaf_page.h @@ -92,7 +92,7 @@ class BPlusTreeLeafPage : public BPlusTreePage { private: page_id_t next_page_id_; - // Flexible array members for page data. + // Array members for page data. KeyType key_array_[LEAF_PAGE_SIZE]; ValueType value_array_[LEAF_PAGE_SIZE]; // (Fall 2024) Feel free to add more fields and helper functions below if needed diff --git a/src/include/storage/page/b_plus_tree_page.h b/src/include/storage/page/b_plus_tree_page.h index 884e2e6cc..a8588dbb8 100644 --- a/src/include/storage/page/b_plus_tree_page.h +++ b/src/include/storage/page/b_plus_tree_page.h @@ -50,7 +50,7 @@ class BPlusTreePage { auto GetSize() const -> int; void SetSize(int size); - void IncreaseSize(int amount); + void ChangeSizeBy(int amount); auto GetMaxSize() const -> int; void SetMaxSize(int max_size); @@ -59,7 +59,9 @@ class BPlusTreePage { private: // Member variables, attributes that both internal and leaf page share IndexPageType page_type_ __attribute__((__unused__)); + // Number of key & value pairs in a page int size_ __attribute__((__unused__)); + // Max number of key & value pairs in a page int max_size_ __attribute__((__unused__)); }; diff --git a/src/storage/page/b_plus_tree_page.cpp b/src/storage/page/b_plus_tree_page.cpp index 0339069ad..ea26571fb 100644 --- a/src/storage/page/b_plus_tree_page.cpp +++ b/src/storage/page/b_plus_tree_page.cpp @@ -26,7 +26,7 @@ void BPlusTreePage::SetPageType(IndexPageType page_type) {} */ auto BPlusTreePage::GetSize() const -> int { return 0; } void BPlusTreePage::SetSize(int size) {} -void BPlusTreePage::IncreaseSize(int amount) {} +void BPlusTreePage::ChangeSizeBy(int amount) {} /* * Helper methods to get/set max size (capacity) of the page @@ -37,6 +37,7 @@ void BPlusTreePage::SetMaxSize(int size) {} /* * Helper method to get min page size * Generally, min page size == max page size / 2 + * But whether you will take ceil() or floor() depends on your implementation */ auto BPlusTreePage::GetMinSize() const -> int { return 0; } From 6df0c57e5422943d1a74ca641e0ac1a58098e484 Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sat, 28 Sep 2024 17:58:59 -0400 Subject: [PATCH 21/22] sync with private repo --- test/storage/b_plus_tree_delete_test.cpp | 64 +------------------ test/storage/b_plus_tree_insert_test.cpp | 22 ++----- .../b_plus_tree_sequential_scale_test.cpp | 9 +-- 3 files changed, 10 insertions(+), 85 deletions(-) diff --git a/test/storage/b_plus_tree_delete_test.cpp b/test/storage/b_plus_tree_delete_test.cpp index 6c03da985..80bd118e9 100644 --- a/test/storage/b_plus_tree_delete_test.cpp +++ b/test/storage/b_plus_tree_delete_test.cpp @@ -24,67 +24,7 @@ namespace bustub { using bustub::DiskManagerUnlimitedMemory; -TEST(BPlusTreeTests, DISABLED_DeleteTest1) { - // create KeyComparator and index schema - auto key_schema = ParseCreateStatement("a bigint"); - GenericComparator<8> comparator(key_schema.get()); - - auto disk_manager = std::make_unique(); - auto *bpm = new BufferPoolManager(50, disk_manager.get()); - // allocate header_page - page_id_t page_id = bpm->NewPage(); - // create b+ tree - BPlusTree, RID, GenericComparator<8>> tree("foo_pk", page_id, bpm, comparator); - GenericKey<8> index_key; - RID rid; - - std::vector keys = {1, 2, 3, 4, 5}; - for (auto key : keys) { - int64_t value = key & 0xFFFFFFFF; - rid.Set(static_cast(key >> 32), value); - index_key.SetFromInteger(key); - tree.Insert(index_key, rid); - } - - std::vector rids; - for (auto key : keys) { - rids.clear(); - index_key.SetFromInteger(key); - tree.GetValue(index_key, &rids); - EXPECT_EQ(rids.size(), 1); - - int64_t value = key & 0xFFFFFFFF; - EXPECT_EQ(rids[0].GetSlotNum(), value); - } - - std::vector remove_keys = {1, 5}; - for (auto key : remove_keys) { - index_key.SetFromInteger(key); - tree.Remove(index_key); - } - - int64_t size = 0; - bool is_present; - - for (auto key : keys) { - rids.clear(); - index_key.SetFromInteger(key); - is_present = tree.GetValue(index_key, &rids); - - if (!is_present) { - EXPECT_NE(std::find(remove_keys.begin(), remove_keys.end(), key), remove_keys.end()); - } else { - EXPECT_EQ(rids.size(), 1); - EXPECT_EQ(rids[0].GetPageId(), 0); - EXPECT_EQ(rids[0].GetSlotNum(), key); - size = size + 1; - } - } - EXPECT_EQ(size, 3); - delete bpm; -} - -TEST(BPlusTreeTests, DISABLED_DeleteTest2) { +TEST(BPlusTreeTests, DISABLED_DeleteTest) { // create KeyComparator and index schema auto key_schema = ParseCreateStatement("a bigint"); GenericComparator<8> comparator(key_schema.get()); @@ -137,7 +77,7 @@ TEST(BPlusTreeTests, DISABLED_DeleteTest2) { EXPECT_EQ(rids.size(), 1); EXPECT_EQ(rids[0].GetPageId(), 0); EXPECT_EQ(rids[0].GetSlotNum(), key); - size = size + 1; + ++size; } } EXPECT_EQ(size, 1); diff --git a/test/storage/b_plus_tree_insert_test.cpp b/test/storage/b_plus_tree_insert_test.cpp index f3b06efac..1c7fb817d 100644 --- a/test/storage/b_plus_tree_insert_test.cpp +++ b/test/storage/b_plus_tree_insert_test.cpp @@ -78,19 +78,8 @@ TEST(BPlusTreeTests, DISABLED_InsertTest2) { tree.Insert(index_key, rid); } - std::vector rids; - for (auto key : keys) { - rids.clear(); - index_key.SetFromInteger(key); - tree.GetValue(index_key, &rids); - EXPECT_EQ(rids.size(), 1); - - int64_t value = key & 0xFFFFFFFF; - EXPECT_EQ(rids[0].GetSlotNum(), value); - } - - int64_t size = 0; bool is_present; + std::vector rids; for (auto key : keys) { rids.clear(); @@ -100,10 +89,9 @@ TEST(BPlusTreeTests, DISABLED_InsertTest2) { EXPECT_EQ(is_present, true); EXPECT_EQ(rids.size(), 1); EXPECT_EQ(rids[0].GetPageId(), 0); - EXPECT_EQ(rids[0].GetSlotNum(), key); - size = size + 1; + int64_t value = key & 0xFFFFFFFF; + EXPECT_EQ(rids[0].GetSlotNum(), value); } - EXPECT_EQ(size, keys.size()); delete bpm; } @@ -147,7 +135,7 @@ TEST(BPlusTreeTests, DISABLED_InsertTest3) { auto location = (*iterator).second; EXPECT_EQ(location.GetPageId(), 0); EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; + ++current_key; } EXPECT_EQ(current_key, keys.size() + 1); @@ -159,7 +147,7 @@ TEST(BPlusTreeTests, DISABLED_InsertTest3) { auto location = (*iterator).second; EXPECT_EQ(location.GetPageId(), 0); EXPECT_EQ(location.GetSlotNum(), current_key); - current_key = current_key + 1; + ++current_key; } delete bpm; } diff --git a/test/storage/b_plus_tree_sequential_scale_test.cpp b/test/storage/b_plus_tree_sequential_scale_test.cpp index 6957be5ad..ffabb4a0e 100644 --- a/test/storage/b_plus_tree_sequential_scale_test.cpp +++ b/test/storage/b_plus_tree_sequential_scale_test.cpp @@ -25,7 +25,7 @@ namespace bustub { using bustub::DiskManagerUnlimitedMemory; /** - * This test should be passing with your Checkpoint 1 submission. + * (Fall 2024) You should pass this test after finishing Task 1 and 2.a in P2. */ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT // create KeyComparator and index schema @@ -44,10 +44,8 @@ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT RID rid; int64_t scale = 5000; - std::vector keys; - for (int64_t key = 1; key < scale; key++) { - keys.push_back(key); - } + std::vector keys(scale); + std::iota(keys.begin(), keys.end(), 1); // randomized the insertion order auto rng = std::default_random_engine{}; @@ -68,7 +66,6 @@ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT int64_t value = key & 0xFFFFFFFF; ASSERT_EQ(rids[0].GetSlotNum(), value); } - delete bpm; } } // namespace bustub From d1c9d0fe390f4e5bc4c3d2eca0e7fd496a14727a Mon Sep 17 00:00:00 2001 From: unw9527 <1041593558@qq.com> Date: Sat, 28 Sep 2024 18:01:14 -0400 Subject: [PATCH 22/22] rm comments for task 2.a --- test/storage/b_plus_tree_sequential_scale_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/storage/b_plus_tree_sequential_scale_test.cpp b/test/storage/b_plus_tree_sequential_scale_test.cpp index ffabb4a0e..b0069e5ea 100644 --- a/test/storage/b_plus_tree_sequential_scale_test.cpp +++ b/test/storage/b_plus_tree_sequential_scale_test.cpp @@ -25,7 +25,7 @@ namespace bustub { using bustub::DiskManagerUnlimitedMemory; /** - * (Fall 2024) You should pass this test after finishing Task 1 and 2.a in P2. + * (Fall 2024) You should pass this test after finishing insertion and point search. */ TEST(BPlusTreeTests, DISABLED_ScaleTest) { // NOLINT // create KeyComparator and index schema