Skip to content

Commit

Permalink
P2: page guard
Browse files Browse the repository at this point in the history
  • Loading branch information
YinshiSanchez committed Jun 2, 2024
1 parent a6ecc72 commit dab864e
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 17 deletions.
20 changes: 16 additions & 4 deletions src/buffer/buffer_pool_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,25 @@ auto BufferPoolManager::DeletePage(page_id_t page_id) -> bool {

auto BufferPoolManager::AllocatePage() -> page_id_t { return next_page_id_++; }

auto BufferPoolManager::FetchPageBasic(page_id_t page_id) -> BasicPageGuard { return {this, nullptr}; }
auto BufferPoolManager::FetchPageBasic(page_id_t page_id) -> BasicPageGuard { return {this, FetchPage(page_id)}; }

auto BufferPoolManager::FetchPageRead(page_id_t page_id) -> ReadPageGuard { return {this, nullptr}; }
auto BufferPoolManager::FetchPageRead(page_id_t page_id) -> ReadPageGuard {
Page *page_ptr = FetchPage(page_id);
if (page_ptr != nullptr) {
page_ptr->RLatch();
}
return {this, page_ptr};
}

auto BufferPoolManager::FetchPageWrite(page_id_t page_id) -> WritePageGuard { return {this, nullptr}; }
auto BufferPoolManager::FetchPageWrite(page_id_t page_id) -> WritePageGuard {
Page *page_ptr = FetchPage(page_id);
if (page_ptr != nullptr) {
page_ptr->WLatch();
}
return WritePageGuard{this, page_ptr};
}

auto BufferPoolManager::NewPageGuarded(page_id_t *page_id) -> BasicPageGuard { return {this, nullptr}; }
auto BufferPoolManager::NewPageGuarded(page_id_t *page_id) -> BasicPageGuard { return {this, NewPage(page_id)}; }

void BufferPoolManager::FlushFrame(frame_id_t frame_id) {
auto promise = disk_scheduler_->CreatePromise();
Expand Down
6 changes: 5 additions & 1 deletion src/include/storage/page/page_guard.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <cstdio>
#include <utility>
#include "storage/page/page.h"

namespace bustub {
Expand Down Expand Up @@ -115,6 +117,7 @@ class ReadPageGuard {
public:
ReadPageGuard() = default;
ReadPageGuard(BufferPoolManager *bpm, Page *page) : guard_(bpm, page) {}
explicit ReadPageGuard(BasicPageGuard &&guard) : guard_(std::move(guard)) {}
ReadPageGuard(const ReadPageGuard &) = delete;
auto operator=(const ReadPageGuard &) -> ReadPageGuard & = delete;

Expand Down Expand Up @@ -174,7 +177,8 @@ class ReadPageGuard {
class WritePageGuard {
public:
WritePageGuard() = default;
WritePageGuard(BufferPoolManager *bpm, Page *page) : guard_(bpm, page) {}
WritePageGuard(BufferPoolManager *bpm, Page *page) : guard_(bpm, page) { guard_.is_dirty_ = true; }
explicit WritePageGuard(BasicPageGuard &&guard) : guard_(std::move(guard)) { guard_.is_dirty_ = true; }
WritePageGuard(const WritePageGuard &) = delete;
auto operator=(const WritePageGuard &) -> WritePageGuard & = delete;

Expand Down
101 changes: 89 additions & 12 deletions src/storage/page/page_guard.cpp
Original file line number Diff line number Diff line change
@@ -1,30 +1,107 @@
#include "storage/page/page_guard.h"
#include <cstddef>
#include <cstdio>
#include <utility>
#include "buffer/buffer_pool_manager.h"

namespace bustub {

BasicPageGuard::BasicPageGuard(BasicPageGuard &&that) noexcept {}
BasicPageGuard::BasicPageGuard(BasicPageGuard &&that) noexcept
: bpm_(that.bpm_), page_(that.page_), is_dirty_(that.is_dirty_) {
that.bpm_ = nullptr;
that.page_ = nullptr;
that.is_dirty_ = false;
}

void BasicPageGuard::Drop() {}
void BasicPageGuard::Drop() {
if (bpm_ != nullptr && page_ != nullptr) {
bpm_->UnpinPage(page_->GetPageId(), is_dirty_);
}
bpm_ = nullptr;
page_ = nullptr;
is_dirty_ = false;
}

auto BasicPageGuard::operator=(BasicPageGuard &&that) noexcept -> BasicPageGuard & { return *this; }
auto BasicPageGuard::operator=(BasicPageGuard &&that) noexcept -> BasicPageGuard & {
if (this != &that) {
Drop();
bpm_ = that.bpm_;
page_ = that.page_;
is_dirty_ = that.is_dirty_;
that.bpm_ = nullptr;
that.page_ = nullptr;
that.is_dirty_ = false;
}

BasicPageGuard::~BasicPageGuard(){}; // NOLINT
return *this;
}

ReadPageGuard::ReadPageGuard(ReadPageGuard &&that) noexcept = default;
BasicPageGuard::~BasicPageGuard() {
if (bpm_ != nullptr && page_ != nullptr) {
bpm_->UnpinPage(page_->GetPageId(), is_dirty_);
}
}; // NOLINT

auto ReadPageGuard::operator=(ReadPageGuard &&that) noexcept -> ReadPageGuard & { return *this; }
auto BasicPageGuard::UpgradeRead() -> ReadPageGuard {
page_->RLatch();
return ReadPageGuard{std::move(*this)};
}

void ReadPageGuard::Drop() {}
auto BasicPageGuard::UpgradeWrite() -> WritePageGuard {
page_->WLatch();
is_dirty_ = true;
return WritePageGuard{std::move(*this)};
}

ReadPageGuard::~ReadPageGuard() {} // NOLINT
ReadPageGuard::ReadPageGuard(ReadPageGuard &&that) noexcept {
Drop();
guard_ = std::move(that.guard_);
};

WritePageGuard::WritePageGuard(WritePageGuard &&that) noexcept = default;
auto ReadPageGuard::operator=(ReadPageGuard &&that) noexcept -> ReadPageGuard & {
if (this != &that) {
guard_ = std::move(that.guard_);
}
return *this;
}

auto WritePageGuard::operator=(WritePageGuard &&that) noexcept -> WritePageGuard & { return *this; }
void ReadPageGuard::Drop() {
if (guard_.page_ != nullptr) {
guard_.page_->RUnlatch();
}
guard_.Drop();
}

void WritePageGuard::Drop() {}
ReadPageGuard::~ReadPageGuard() {
if (guard_.page_ != nullptr) {
guard_.page_->RUnlatch();
}
} // NOLINT

WritePageGuard::~WritePageGuard() {} // NOLINT
WritePageGuard::WritePageGuard(WritePageGuard &&that) noexcept {
Drop();
guard_ = std::move(that.guard_);
}

auto WritePageGuard::operator=(WritePageGuard &&that) noexcept -> WritePageGuard & {
if (this != &that) {
Drop();
guard_ = std::move(that.guard_);
}
return *this;
}

void WritePageGuard::Drop() {
if (guard_.page_ != nullptr) {
guard_.page_->WUnlatch();
}
guard_.Drop();
}

WritePageGuard::~WritePageGuard() {
if (guard_.page_ != nullptr) {
guard_.page_->WUnlatch();
}
} // NOLINT

} // namespace bustub

0 comments on commit dab864e

Please sign in to comment.