Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/include/buffer/traced_buffer_pool_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "./buffer_pool_manager.h"

namespace bustub {

class TracedBufferPoolManager {
private:
size_t reads_ = 0;
size_t writes_ = 0;
BufferPoolManager *bpm_;

public:
explicit TracedBufferPoolManager(BufferPoolManager *bpm) : bpm_{bpm} {}

auto WritePage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> WritePageGuard {
writes_++;
return bpm_->WritePage(page_id, access_type);
}

auto ReadPage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> ReadPageGuard {
reads_++;
return bpm_->ReadPage(page_id, access_type);
}

auto NewPage() -> page_id_t { return bpm_->NewPage(); }
auto DeletePage(page_id_t page) -> bool { return bpm_->DeletePage(page); }

auto GetReads() -> size_t { return reads_; }
auto GetWrites() -> size_t { return writes_; }
};

}; // namespace bustub
10 changes: 7 additions & 3 deletions src/include/storage/index/b_plus_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ class Context {
auto IsRootPage(page_id_t page_id) -> bool { return page_id == root_page_id_; }
};

#define BPLUSTREE_TYPE BPlusTree<KeyType, ValueType, KeyComparator>
#define BPLUSTREE_TYPE BPlusTree<KeyType, ValueType, KeyComparator, NumTombs>

// Main class providing the API for the Interactive B+ Tree.
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS_DEFN
class BPlusTree {
using InternalPage = BPlusTreeInternalPage<KeyType, page_id_t, KeyComparator>;
using LeafPage = BPlusTreeLeafPage<KeyType, ValueType, KeyComparator>;
Expand Down Expand Up @@ -99,6 +99,8 @@ class BPlusTree {
// Index iterator
auto Begin() -> INDEXITERATOR_TYPE;

auto FindLeftmostPage() -> ReadPageGuard;

auto End() -> INDEXITERATOR_TYPE;

auto Begin(const KeyType &key) -> INDEXITERATOR_TYPE;
Expand All @@ -117,6 +119,9 @@ class BPlusTree {

void BatchOpsFromFile(const std::filesystem::path &file_name);

// Do not change this type to a BufferPoolManager!
TracedBufferPoolManager bpm_;

private:
void ToGraph(page_id_t page_id, const BPlusTreePage *page, std::ofstream &out);

Expand All @@ -126,7 +131,6 @@ class BPlusTree {

// member variable
std::string index_name_;
BufferPoolManager *bpm_;
KeyComparator comparator_;
std::vector<std::string> log; // NOLINT
int leaf_max_size_;
Expand Down
26 changes: 13 additions & 13 deletions src/include/storage/index/b_plus_tree_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace bustub {
* This method is used for test only
* Read data from file and insert one by one
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name) {
int64_t key;
std::ifstream input(file_name);
Expand All @@ -52,7 +52,7 @@ void BPLUSTREE_TYPE::InsertFromFile(const std::filesystem::path &file_name) {
* This method is used for test only
* Read data from file and remove one by one
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name) {
int64_t key;
std::ifstream input(file_name);
Expand All @@ -64,7 +64,7 @@ void BPLUSTREE_TYPE::RemoveFromFile(const std::filesystem::path &file_name) {
}
}

INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::Print(BufferPoolManager *bpm) {
auto root_page_id = GetRootPageId();
if (root_page_id != INVALID_PAGE_ID) {
Expand All @@ -73,7 +73,7 @@ void BPLUSTREE_TYPE::Print(BufferPoolManager *bpm) {
}
}

INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) {
if (page->IsLeafPage()) {
auto *leaf = reinterpret_cast<const LeafPage *>(page);
Expand Down Expand Up @@ -109,14 +109,14 @@ void BPLUSTREE_TYPE::PrintTree(page_id_t page_id, const BPlusTreePage *page) {
std::cout << std::endl;
std::cout << std::endl;
for (int i = 0; i < internal->GetSize(); i++) {
auto guard = bpm_->ReadPage(internal->ValueAt(i));
auto guard = bpm_.ReadPage(internal->ValueAt(i));
PrintTree(guard.GetPageId(), guard.template As<BPlusTreePage>());
}
}
}

/** @brief draw the B+ tree */
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::Draw(BufferPoolManager *bpm, const std::filesystem::path &outf) {
if (IsEmpty()) {
LOG_WARN("Drawing an empty tree");
Expand All @@ -133,7 +133,7 @@ void BPLUSTREE_TYPE::Draw(BufferPoolManager *bpm, const std::filesystem::path &o
}

/** @brief Debug Routines for FREE!! */
INDEX_TEMPLATE_ARGUMENTS
FULL_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_");
Expand Down Expand Up @@ -190,11 +190,11 @@ void BPLUSTREE_TYPE::ToGraph(page_id_t page_id, const BPlusTreePage *page, std::
out << "</TABLE>>];\n";
// Print leaves
for (int i = 0; i < inner->GetSize(); i++) {
auto child_guard = bpm_->ReadPage(inner->ValueAt(i));
auto child_guard = bpm_.ReadPage(inner->ValueAt(i));
auto child_page = child_guard.template As<BPlusTreePage>();
ToGraph(child_guard.GetPageId(), child_page, out);
if (i > 0) {
auto sibling_guard = bpm_->ReadPage(inner->ValueAt(i - 1));
auto sibling_guard = bpm_.ReadPage(inner->ValueAt(i - 1));
auto sibling_page = sibling_guard.template As<BPlusTreePage>();
if (!sibling_page->IsLeafPage() && !child_page->IsLeafPage()) {
out << "{rank=same " << internal_prefix << sibling_guard.GetPageId() << " " << internal_prefix
Expand Down Expand Up @@ -222,7 +222,7 @@ void BPLUSTREE_TYPE::ToGraph(page_id_t page_id, const BPlusTreePage *page, std::
*
* @return std::string
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
auto BPLUSTREE_TYPE::DrawBPlusTree() -> std::string {
if (IsEmpty()) {
return "()";
Expand All @@ -245,7 +245,7 @@ auto BPLUSTREE_TYPE::DrawBPlusTree() -> std::string {
* (1,2) (3,4) (5,6) (7,10,30) // The output tree example
* @note This method is used for test only. Read data from file and insert/remove one by one.
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name) {
int64_t key;
char instruction;
Expand Down Expand Up @@ -282,9 +282,9 @@ void BPLUSTREE_TYPE::BatchOpsFromFile(const std::filesystem::path &file_name) {
* @param root_id
* @return PrintableNode
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS
auto BPLUSTREE_TYPE::ToPrintableBPlusTree(page_id_t root_id) -> PrintableBPlusTree {
auto root_page_guard = bpm_->ReadPage(root_id);
auto root_page_guard = bpm_.ReadPage(root_id);
auto root_page = root_page_guard.template As<BPlusTreePage>();
PrintableBPlusTree proot;

Expand Down
8 changes: 5 additions & 3 deletions src/include/storage/index/b_plus_tree_index.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "container/hash/hash_function.h"
#include "storage/index/b_plus_tree.h"
#include "storage/index/index.h"
#include "storage/index/index_iterator.h"
#include "storage/page/b_plus_tree_page.h"

namespace bustub {

Expand All @@ -36,11 +38,11 @@ class BPlusTreeIndex : public Index {

void ScanKey(const Tuple &key, std::vector<RID> *result, Transaction *transaction) override;

auto GetBeginIterator() -> INDEXITERATOR_TYPE;
auto GetBeginIterator() -> SHORT_INDEXITERATOR_TYPE;

auto GetBeginIterator(const KeyType &key) -> INDEXITERATOR_TYPE;
auto GetBeginIterator(const KeyType &key) -> SHORT_INDEXITERATOR_TYPE;

auto GetEndIterator() -> INDEXITERATOR_TYPE;
auto GetEndIterator() -> SHORT_INDEXITERATOR_TYPE;

protected:
// comparator for key
Expand Down
7 changes: 7 additions & 0 deletions src/include/storage/index/generic_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ class GenericKey {
memcpy(data_, &key, sizeof(int64_t));
}

// NOTE: for test purpose only
inline auto GetAsInteger() const -> int64_t {
int64_t out;
memcpy(&out, data_, sizeof(int64_t));
return out;
}

inline auto ToValue(Schema *schema, uint32_t column_idx) const -> Value {
const char *data_ptr;
const auto &col = schema->GetColumn(column_idx);
Expand Down
8 changes: 6 additions & 2 deletions src/include/storage/index/index_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
*/
#pragma once
#include <utility>
#include "buffer/traced_buffer_pool_manager.h"
#include "common/config.h"
#include "common/macros.h"
#include "storage/page/b_plus_tree_leaf_page.h"

namespace bustub {

#define INDEXITERATOR_TYPE IndexIterator<KeyType, ValueType, KeyComparator>
#define INDEXITERATOR_TYPE IndexIterator<KeyType, ValueType, KeyComparator, NumTombs>
#define SHORT_INDEXITERATOR_TYPE IndexIterator<KeyType, ValueType, KeyComparator>

INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS_DEFN
class IndexIterator {
public:
// you may define your own constructor based on your member variables
Expand Down
31 changes: 22 additions & 9 deletions src/include/storage/page/b_plus_tree_leaf_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,27 @@

namespace bustub {

#define B_PLUS_TREE_LEAF_PAGE_TYPE BPlusTreeLeafPage<KeyType, ValueType, KeyComparator>
#define B_PLUS_TREE_LEAF_PAGE_TYPE BPlusTreeLeafPage<KeyType, ValueType, KeyComparator, NumTombs>
#define LEAF_PAGE_HEADER_SIZE 16
#define LEAF_PAGE_SLOT_CNT ((BUSTUB_PAGE_SIZE - LEAF_PAGE_HEADER_SIZE) / (sizeof(KeyType) + sizeof(ValueType)))
#define LEAF_PAGE_SLOT_CNT \
((BUSTUB_PAGE_SIZE - LEAF_PAGE_HEADER_SIZE - sizeof(size_t) - (NumTombs * sizeof(size_t))) / \
(sizeof(KeyType) + sizeof(ValueType))) // NOLINT

/**
* Store indexed key and record id (record id = page id combined with slot id,
* see `include/common/rid.h` for detailed implementation) together within leaf
* Store indexed key and record id(record id = page id combined with slot id,
* see include/common/rid.h for detailed implementation) together within leaf
* page. Only support unique key.
*
* Leaf page format (keys are stored in order):
* ---------
* | HEADER |
* ---------
* Leaf pages also contain a fixed buffer of "tombstone" indexes for entries
* that have been deleted.
*
* Leaf page format (keys are stored in order, tomb order is up to you):
* --------------------
* | HEADER | TOMB_SIZE | (where TOMB_SIZE is num_tombstones_)
* --------------------
* -----------------------------------
* | TOMB(0) | TOMB(1) | ... | TOMB(k) |
* -----------------------------------
* ---------------------------------
* | KEY(1) | KEY(2) | ... | KEY(n) |
* ---------------------------------
Expand All @@ -48,7 +56,7 @@ namespace bustub {
* | NextPageId (4) |
* -----------------
*/
INDEX_TEMPLATE_ARGUMENTS
FULL_INDEX_TEMPLATE_ARGUMENTS_DEFN
class BPlusTreeLeafPage : public BPlusTreePage {
public:
// Delete all constructor / destructor to ensure memory safety
Expand All @@ -57,6 +65,8 @@ class BPlusTreeLeafPage : public BPlusTreePage {

void Init(int max_size = LEAF_PAGE_SLOT_CNT);

auto GetTombstones() const -> std::vector<KeyType>;

// Helper methods
auto GetNextPageId() const -> page_id_t;
void SetNextPageId(page_id_t next_page_id);
Expand Down Expand Up @@ -89,6 +99,9 @@ class BPlusTreeLeafPage : public BPlusTreePage {

private:
page_id_t next_page_id_;
size_t num_tombstones_;
// Fixed-size tombstone buffer (indexes into key_array_ / rid_array_).
size_t tombstones_[NumTombs];
// Array members for page data.
KeyType key_array_[LEAF_PAGE_SLOT_CNT];
ValueType rid_array_[LEAF_PAGE_SLOT_CNT];
Expand Down
4 changes: 4 additions & 0 deletions src/include/storage/page/b_plus_tree_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ namespace bustub {

#define MappingType std::pair<KeyType, ValueType>

#define FULL_INDEX_TEMPLATE_ARGUMENTS_DEFN \
template <typename KeyType, typename ValueType, typename KeyComparator, size_t NumTombs = 0>
#define FULL_INDEX_TEMPLATE_ARGUMENTS \
template <typename KeyType, typename ValueType, typename KeyComparator, size_t NumTombs>
#define INDEX_TEMPLATE_ARGUMENTS template <typename KeyType, typename ValueType, typename KeyComparator>

// define page type enum
Expand Down
Loading
Loading