Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

p1: update cmake to include more submission files #691

Merged
merged 11 commits into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ set(P1_FILES
"src/buffer/buffer_pool_manager.cpp"
"src/include/storage/disk/disk_scheduler.h"
"src/storage/disk/disk_scheduler.cpp"
"src/storage/page/page_guard.cpp"
"src/include/storage/page/page_guard.h"
)
add_custom_target(check-clang-tidy-p1
${BUSTUB_BUILD_SUPPORT_DIR}/run_clang_tidy.py # run LLVM's clang-tidy script
Expand Down
8 changes: 4 additions & 4 deletions src/include/buffer/buffer_pool_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include "buffer/lru_k_replacer.h"
#include "common/config.h"
#include "recovery/log_manager.h"
#include "storage/disk/cow_buffer.h"
#include "storage/disk/disk_scheduler.h"
#include "storage/disk/write_back_cache.h"
#include "storage/page/page.h"
#include "storage/page/page_guard.h"

Expand Down Expand Up @@ -73,7 +73,7 @@ class BufferPoolManager {
auto NewPage(page_id_t *page_id) -> Page *;

/**
* TODO(P2): Add implementation
* TODO(P1): Add implementation
*
* @brief PageGuard wrapper for NewPage
*
Expand Down Expand Up @@ -106,7 +106,7 @@ class BufferPoolManager {
auto FetchPage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> Page *;

/**
* TODO(P2): Add implementation
* TODO(P1): Add implementation
*
* @brief PageGuard wrappers for FetchPage
*
Expand Down Expand Up @@ -194,7 +194,7 @@ class BufferPoolManager {
/** This latch protects shared data structures. We recommend updating this comment to describe what it protects. */
std::mutex latch_;
/** This buffer is for the leaderboard task. You may want to use it to optimize the write requests. */
CoWBuffer cow_buffer_ __attribute__((__unused__));
WriteBackCache write_back_cache_ __attribute__((__unused__));

/**
* @brief Allocate a page on disk. Caller should acquire the latch before calling this function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
namespace bustub {

/**
* CoWBuffer provides extra memory space other than the buffer pool to store the copy-on-write pages.
* WriteBackCache provides extra memory space other than the buffer pool to store the copy-on-write pages.
* It's purpose is to gather the copy of pages that are about to be written back to disk, so that the bpm
* doesn't have to incur IO penality and wait for the write to be completed when evicting.
* Spring 24: The buffer is limited to store a constant number of pages in total (8).
* !! ANY ATTEMPTS TO ADD ANOTHER IN-MEMORY CACHE WILL BE REVIEWED MANUALLY AS PER LEADERBOARD POLICY !!
*/
class CoWBuffer {
class WriteBackCache {
public:
CoWBuffer() : cow_pages_{new Page[8]} {}
~CoWBuffer() { delete[] cow_pages_; }
DISALLOW_COPY_AND_MOVE(CoWBuffer);
WriteBackCache() : write_back_pages_{new Page[8]} {}
~WriteBackCache() { delete[] write_back_pages_; }
DISALLOW_COPY_AND_MOVE(WriteBackCache);

/**
* @brief Adds a new page to the CoW buffer.
* @brief Adds a new page to the write back cache.
* @param page the page pointer from the bpm that is about to be evicted.
* @return pointer to the copied page in the buffer, or nullptr if the buffer is full.
*/
Expand All @@ -44,19 +44,19 @@ class CoWBuffer {
}

uint32_t slot = FindFreeSlot();
memcpy(cow_pages_[slot].GetData(), page->GetData(), BUSTUB_PAGE_SIZE);
memcpy(write_back_pages_[slot].GetData(), page->GetData(), BUSTUB_PAGE_SIZE);
MarkSlotUsed(slot);

return cow_pages_ + slot;
return write_back_pages_ + slot;
}

/**
* @brief Removes a page from the CoW buffer.
* @brief Removes a page from the write back cache.
* @param page the pointer previously returned by Add.
*/
auto Remove(Page *page) -> void {
if (page != nullptr) {
MarkSlotFree(page - cow_pages_);
MarkSlotFree(page - write_back_pages_);
}
}

Expand All @@ -66,7 +66,7 @@ class CoWBuffer {

/** @brief Finds a free slot in the buffer, if not full. */
auto FindFreeSlot() -> uint32_t {
BUSTUB_ASSERT(!IsFull(), "no free slot in cow buffer");
BUSTUB_ASSERT(!IsFull(), "no free slot in write back cache");
uint32_t i = 0;
uint8_t bitmap = free_slot_bitmap_;
while ((bitmap & 1U) != 0) {
Expand All @@ -88,8 +88,8 @@ class CoWBuffer {
free_slot_bitmap_ &= ~(1U << slot);
}

/** The array of CoW buffer pages. */
Page *cow_pages_;
/** The array of write back cache pages. */
Page *write_back_pages_;
/** The bitmap that records which slots are free. */
uint8_t free_slot_bitmap_{0};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,46 @@
//
//===----------------------------------------------------------------------===//

#include "storage/disk/cow_buffer.h"
#include "storage/disk/write_back_cache.h"
#include "gtest/gtest.h"

namespace bustub {

// NOLINTNEXTLINE
TEST(CoWBufferTest, ScheduleWriteReadPageTest) {
CoWBuffer cow{};
std::vector<Page *> cow_pages{};
TEST(WriteBackCacheTest, ScheduleWriteReadPageTest) {
WriteBackCache wbc{};
std::vector<Page *> wbc_pages{};
for (size_t i{0}; i < 8; i++) {
Page bpm_page{};
auto content{"Meuh!: " + std::to_string(i) + " 🐄🐄🐄🐄"};
std::strncpy(bpm_page.GetData(), content.data(), BUSTUB_PAGE_SIZE);

Page *cow_page{cow.Add(&bpm_page)};
EXPECT_NE(cow_page, nullptr);
EXPECT_NE(cow_page, &bpm_page);
cow_pages.push_back(cow_page);
EXPECT_EQ(std::memcmp(cow_page->GetData(), bpm_page.GetData(), BUSTUB_PAGE_SIZE), 0);
Page *wbc_page{wbc.Add(&bpm_page)};
EXPECT_NE(wbc_page, nullptr);
EXPECT_NE(wbc_page, &bpm_page);
wbc_pages.push_back(wbc_page);
EXPECT_EQ(std::memcmp(wbc_page->GetData(), bpm_page.GetData(), BUSTUB_PAGE_SIZE), 0);
}

Page extra_page{};
Page *cow_extra_page{cow.Add(&extra_page)};
EXPECT_EQ(cow_extra_page, nullptr);
Page *wbc_extra_page{wbc.Add(&extra_page)};
EXPECT_EQ(wbc_extra_page, nullptr);

for (size_t i{0}; i < 8; i++) {
auto check{"Meuh!: " + std::to_string(i) + " 🐄🐄🐄🐄"};
EXPECT_EQ(std::memcmp(cow_pages[i]->GetData(), check.data(), check.size()), 0);
EXPECT_EQ(std::memcmp(wbc_pages[i]->GetData(), check.data(), check.size()), 0);
}

cow.Remove(cow_pages[5]);
wbc.Remove(wbc_pages[5]);
Page replace_page{};
cow_pages[5] = cow.Add(&replace_page);
EXPECT_NE(cow_pages[5], nullptr);
wbc_pages[5] = wbc.Add(&replace_page);
EXPECT_NE(wbc_pages[5], nullptr);

for (size_t i{0}; i < 8; i++) {
cow.Remove(cow_pages[i]); // Shouldn't crash.
wbc.Remove(wbc_pages[i]); // Shouldn't crash.
}

cow.Remove(nullptr); // Shouldn't crash.
wbc.Remove(nullptr); // Shouldn't crash.
}

} // namespace bustub
Loading