Skip to content

Commit e257384

Browse files
authored
refactor(p2): use page guard in B+ tree (#502)
* one change * root page and page guard * clang tidy doesn't work * wip * test * base code changes mostly done * chi changes * whoops * kill newline * changed tests * check lint * change * test * test timeout * timeout * changing timeout * mirror commit * changes * changes
1 parent 0a1dbca commit e257384

14 files changed

+426
-259
lines changed

build_support/run_clang_tidy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ def make_absolute(f, directory):
7979
def supports_color():
8080
"""
8181
Modified from https://github.com/django/django/blob/main/django/core/management/color.py
82-
8382
Return True if the running system's terminal supports color,
8483
and False otherwise.
8584
"""
@@ -425,3 +424,4 @@ def update_progress(current_file, num_files):
425424

426425
if __name__ == '__main__':
427426
main()
427+

src/include/storage/index/b_plus_tree.h

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,87 +8,118 @@
88
// Copyright (c) 2018, Carnegie Mellon University Database Group
99
//
1010
//===----------------------------------------------------------------------===//
11+
/**
12+
* b_plus_tree.h
13+
*
14+
* Implementation of simple b+ tree data structure where internal pages direct
15+
* the search and leaf pages contain actual data.
16+
* (1) We only support unique key
17+
* (2) support insert & remove
18+
* (3) The structure should shrink and grow dynamically
19+
* (4) Implement index iterator for range scan
20+
*/
1121
#pragma once
1222

23+
#include <algorithm>
24+
#include <deque>
25+
#include <optional>
1326
#include <queue>
14-
#include <string>
27+
#include <shared_mutex>
1528
#include <vector>
1629

30+
#include "common/config.h"
31+
#include "common/macros.h"
1732
#include "concurrency/transaction.h"
1833
#include "storage/index/index_iterator.h"
1934
#include "storage/page/b_plus_tree_internal_page.h"
2035
#include "storage/page/b_plus_tree_leaf_page.h"
36+
#include "storage/page/b_plus_tree_root_page.h"
37+
#include "storage/page/page_guard.h"
2138

2239
namespace bustub {
2340

24-
#define BPLUSTREE_TYPE BPlusTree<KeyType, ValueType, KeyComparator>
25-
2641
/**
27-
* Main class providing the API for the Interactive B+ Tree.
42+
* @brief Definition of the Context class.
2843
*
29-
* Implementation of simple b+ tree data structure where internal pages direct
30-
* the search and leaf pages contain actual data.
31-
* (1) We only support unique key
32-
* (2) support insert & remove
33-
* (3) The structure should shrink and grow dynamically
34-
* (4) Implement index iterator for range scan
44+
* Hint: This class is designed to help you keep track of the pages
45+
* that you're modifying or accessing.
3546
*/
47+
class Context {
48+
public:
49+
std::optional<WritePageGuard> header_page_{std::nullopt};
50+
page_id_t root_page_id_{INVALID_PAGE_ID};
51+
std::deque<WritePageGuard> write_set_;
52+
std::deque<ReadPageGuard> read_set_;
53+
54+
auto IsRootPage(page_id_t page_id) -> bool { return page_id == root_page_id_; }
55+
};
56+
57+
#define BPLUSTREE_TYPE BPlusTree<KeyType, ValueType, KeyComparator>
58+
// Main class providing the API for the Interactive B+ Tree.
3659
INDEX_TEMPLATE_ARGUMENTS
3760
class BPlusTree {
3861
using InternalPage = BPlusTreeInternalPage<KeyType, page_id_t, KeyComparator>;
3962
using LeafPage = BPlusTreeLeafPage<KeyType, ValueType, KeyComparator>;
4063

4164
public:
42-
explicit BPlusTree(std::string name, BufferPoolManager *buffer_pool_manager, const KeyComparator &comparator,
43-
int leaf_max_size = LEAF_PAGE_SIZE, int internal_max_size = INTERNAL_PAGE_SIZE);
65+
explicit BPlusTree(std::string name, page_id_t header_page_id, BufferPoolManager *buffer_pool_manager,
66+
const KeyComparator &comparator, int leaf_max_size = LEAF_PAGE_SIZE,
67+
int internal_max_size = INTERNAL_PAGE_SIZE);
4468

4569
// Returns true if this B+ tree has no keys and values.
4670
auto IsEmpty() const -> bool;
4771

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

5175
// Remove a key and its value from this B+ tree.
52-
void Remove(const KeyType &key, Transaction *transaction = nullptr);
76+
void Remove(const KeyType &key, Transaction *txn);
5377

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

57-
// return the page id of the root node
81+
// Return the page id of the root node
5882
auto GetRootPageId() -> page_id_t;
5983

60-
// index iterator
84+
// Index iterator
6185
auto Begin() -> INDEXITERATOR_TYPE;
62-
auto Begin(const KeyType &key) -> INDEXITERATOR_TYPE;
86+
6387
auto End() -> INDEXITERATOR_TYPE;
6488

65-
// print the B+ tree
89+
auto Begin(const KeyType &key) -> INDEXITERATOR_TYPE;
90+
91+
// Print the B+ tree
6692
void Print(BufferPoolManager *bpm);
6793

68-
// draw the B+ tree
94+
// Draw the B+ tree
6995
void Draw(BufferPoolManager *bpm, const std::string &outf);
7096

7197
// read data from file and insert one by one
72-
void InsertFromFile(const std::string &file_name, Transaction *transaction = nullptr);
98+
void InsertFromFile(const std::string &file_name, Transaction *txn = nullptr);
7399

74100
// read data from file and remove one by one
75-
void RemoveFromFile(const std::string &file_name, Transaction *transaction = nullptr);
101+
void RemoveFromFile(const std::string &file_name, Transaction *txn = nullptr);
76102

77103
private:
78-
void UpdateRootPageId(int insert_record = 0);
79-
80104
/* Debug Routines for FREE!! */
81-
void ToGraph(BPlusTreePage *page, BufferPoolManager *bpm, std::ofstream &out) const;
105+
void ToGraph(page_id_t page_id, const BPlusTreePage *page, std::ofstream &out);
106+
107+
void PrintTree(page_id_t page_id, const BPlusTreePage *page);
82108

83-
void ToString(BPlusTreePage *page, BufferPoolManager *bpm) const;
109+
void Dump() {
110+
for (auto &f : log) {
111+
std::cout << f << std::endl;
112+
}
113+
}
84114

85115
// member variable
86116
std::string index_name_;
87-
page_id_t root_page_id_;
88-
BufferPoolManager *buffer_pool_manager_;
117+
BufferPoolManager *bpm_;
89118
KeyComparator comparator_;
119+
std::vector<std::string> log; // NOLINT
90120
int leaf_max_size_;
91121
int internal_max_size_;
122+
page_id_t header_page_id_;
92123
};
93124

94125
} // namespace bustub

src/include/storage/index/b_plus_tree_index.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class BPlusTreeIndex : public Index {
4545
// comparator for key
4646
KeyComparator comparator_;
4747
// container
48-
BPlusTree<KeyType, ValueType, KeyComparator> container_;
48+
std::shared_ptr<BPlusTree<KeyType, ValueType, KeyComparator>> container_;
4949
};
5050

5151
/** We only support index table with one integer key for now in BusTub. Hardcode everything here. */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include "common/config.h"
4+
namespace bustub {
5+
6+
class BPlusTreeRootPage {
7+
public:
8+
// Delete all constructor / destructor to ensure memory safety
9+
BPlusTreeRootPage() = delete;
10+
BPlusTreeRootPage(const BPlusTreeRootPage &other) = delete;
11+
12+
page_id_t root_page_id_;
13+
};
14+
15+
} // namespace bustub

src/include/storage/table/table_iterator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class TableIterator {
3737
~TableIterator() { delete tuple_; }
3838

3939
inline auto operator==(const TableIterator &itr) const -> bool {
40-
return tuple_->rid_.Get() == itr.tuple_->rid_.Get();
40+
return tuple_->GetRid().Get() == itr.tuple_->GetRid().Get();
4141
}
4242

4343
inline auto operator!=(const TableIterator &itr) const -> bool { return !(*this == itr); }

0 commit comments

Comments
 (0)