Skip to content

Commit 3e93325

Browse files
authored
p1 (bpm) flush api changes (#800)
* p1 flush changes * Note why disk scheduler is shared ptr
1 parent 5dfb864 commit 3e93325

File tree

4 files changed

+97
-11
lines changed

4 files changed

+97
-11
lines changed

src/buffer/buffer_pool_manager.cpp

+43-3
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ BufferPoolManager::BufferPoolManager(size_t num_frames, DiskManager *disk_manage
7272
next_page_id_(0),
7373
bpm_latch_(std::make_shared<std::mutex>()),
7474
replacer_(std::make_shared<LRUKReplacer>(num_frames, k_dist)),
75-
disk_scheduler_(std::make_unique<DiskScheduler>(disk_manager)),
75+
disk_scheduler_(std::make_shared<DiskScheduler>(disk_manager)),
7676
log_manager_(log_manager) {
7777
// Not strictly necessary...
7878
std::scoped_lock latch(*bpm_latch_);
@@ -274,11 +274,14 @@ auto BufferPoolManager::ReadPage(page_id_t page_id, AccessType access_type) -> R
274274
}
275275

276276
/**
277-
* @brief Flushes a page's data out to disk.
277+
* @brief Flushes a page's data out to disk unsafely.
278278
*
279279
* This function will write out a page's data to disk if it has been modified. If the given page is not in memory, this
280280
* function will return `false`.
281281
*
282+
* You should not take a lock on the page in this function.
283+
* This means that you should carefully consider when to toggle the `is_dirty_` bit.
284+
*
282285
* ### Implementation
283286
*
284287
* You should probably leave implementing this function until after you have completed `CheckedReadPage` and
@@ -289,10 +292,47 @@ auto BufferPoolManager::ReadPage(page_id_t page_id, AccessType access_type) -> R
289292
* @param page_id The page ID of the page to be flushed.
290293
* @return `false` if the page could not be found in the page table, otherwise `true`.
291294
*/
295+
auto BufferPoolManager::FlushPageUnsafe(page_id_t page_id) -> bool { UNIMPLEMENTED("TODO(P1): Add implementation."); }
296+
297+
/**
298+
* @brief Flushes a page's data out to disk safely.
299+
*
300+
* This function will write out a page's data to disk if it has been modified. If the given page is not in memory, this
301+
* function will return `false`.
302+
*
303+
* You should take a lock on the page in this function to ensure that a consistent state is flushed to disk.
304+
*
305+
* ### Implementation
306+
*
307+
* You should probably leave implementing this function until after you have completed `CheckedReadPage`,
308+
* `CheckedWritePage`, and `Flush` in the page guards, as it will likely be much easier to understand what to do.
309+
*
310+
* TODO(P1): Add implementation
311+
*
312+
* @param page_id The page ID of the page to be flushed.
313+
* @return `false` if the page could not be found in the page table, otherwise `true`.
314+
*/
292315
auto BufferPoolManager::FlushPage(page_id_t page_id) -> bool { UNIMPLEMENTED("TODO(P1): Add implementation."); }
293316

294317
/**
295-
* @brief Flushes all page data that is in memory to disk.
318+
* @brief Flushes all page data that is in memory to disk unsafely.
319+
*
320+
* You should not take locks on the pages in this function.
321+
* This means that you should carefully consider when to toggle the `is_dirty_` bit.
322+
*
323+
* ### Implementation
324+
*
325+
* You should probably leave implementing this function until after you have completed `CheckedReadPage`,
326+
* `CheckedWritePage`, and `FlushPage`, as it will likely be much easier to understand what to do.
327+
*
328+
* TODO(P1): Add implementation
329+
*/
330+
void BufferPoolManager::FlushAllPagesUnsafe() { UNIMPLEMENTED("TODO(P1): Add implementation."); }
331+
332+
/**
333+
* @brief Flushes all page data that is in memory to disk safely.
334+
*
335+
* You should take locks on the pages in this function to ensure that a consistent state is flushed to disk.
296336
*
297337
* ### Implementation
298338
*

src/include/buffer/buffer_pool_manager.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ class BufferPoolManager {
121121
auto CheckedReadPage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> std::optional<ReadPageGuard>;
122122
auto WritePage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> WritePageGuard;
123123
auto ReadPage(page_id_t page_id, AccessType access_type = AccessType::Unknown) -> ReadPageGuard;
124+
auto FlushPageUnsafe(page_id_t page_id) -> bool;
124125
auto FlushPage(page_id_t page_id) -> bool;
126+
void FlushAllPagesUnsafe();
125127
void FlushAllPages();
126128
auto GetPinCount(page_id_t page_id) -> std::optional<size_t>;
127129

@@ -151,8 +153,8 @@ class BufferPoolManager {
151153
/** @brief The replacer to find unpinned / candidate pages for eviction. */
152154
std::shared_ptr<LRUKReplacer> replacer_;
153155

154-
/** @brief A pointer to the disk scheduler. */
155-
std::unique_ptr<DiskScheduler> disk_scheduler_;
156+
/** @brief A pointer to the disk scheduler. Shared with the page guards for flushing. */
157+
std::shared_ptr<DiskScheduler> disk_scheduler_;
156158

157159
/**
158160
* @brief A pointer to the log manager.

src/include/storage/page/page_guard.h

+19-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <memory>
1616

1717
#include "buffer/buffer_pool_manager.h"
18+
#include "storage/disk/disk_scheduler.h"
1819
#include "storage/page/page.h"
1920

2021
namespace bustub {
@@ -60,13 +61,14 @@ class ReadPageGuard {
6061
return reinterpret_cast<const T *>(GetData());
6162
}
6263
auto IsDirty() const -> bool;
64+
void Flush();
6365
void Drop();
6466
~ReadPageGuard();
6567

6668
private:
6769
/** @brief Only the buffer pool manager is allowed to construct a valid `ReadPageGuard.` */
6870
explicit ReadPageGuard(page_id_t page_id, std::shared_ptr<FrameHeader> frame, std::shared_ptr<LRUKReplacer> replacer,
69-
std::shared_ptr<std::mutex> bpm_latch);
71+
std::shared_ptr<std::mutex> bpm_latch, std::shared_ptr<DiskScheduler> disk_scheduler);
7072

7173
/** @brief The page ID of the page we are guarding. */
7274
page_id_t page_id_;
@@ -94,6 +96,13 @@ class ReadPageGuard {
9496
*/
9597
std::shared_ptr<std::mutex> bpm_latch_;
9698

99+
/**
100+
* @brief A shared pointer to the buffer pool's disk scheduler.
101+
*
102+
* Used when flushing pages to disk.
103+
*/
104+
std::shared_ptr<DiskScheduler> disk_scheduler_;
105+
97106
/**
98107
* @brief The validity flag for this `ReadPageGuard`.
99108
*
@@ -159,13 +168,14 @@ class WritePageGuard {
159168
return reinterpret_cast<T *>(GetDataMut());
160169
}
161170
auto IsDirty() const -> bool;
171+
void Flush();
162172
void Drop();
163173
~WritePageGuard();
164174

165175
private:
166176
/** @brief Only the buffer pool manager is allowed to construct a valid `WritePageGuard.` */
167177
explicit WritePageGuard(page_id_t page_id, std::shared_ptr<FrameHeader> frame, std::shared_ptr<LRUKReplacer> replacer,
168-
std::shared_ptr<std::mutex> bpm_latch);
178+
std::shared_ptr<std::mutex> bpm_latch, std::shared_ptr<DiskScheduler> disk_scheduler);
169179

170180
/** @brief The page ID of the page we are guarding. */
171181
page_id_t page_id_;
@@ -193,6 +203,13 @@ class WritePageGuard {
193203
*/
194204
std::shared_ptr<std::mutex> bpm_latch_;
195205

206+
/**
207+
* @brief A shared pointer to the buffer pool's disk scheduler.
208+
*
209+
* Used when flushing pages to disk.
210+
*/
211+
std::shared_ptr<DiskScheduler> disk_scheduler_;
212+
196213
/**
197214
* @brief The validity flag for this `WritePageGuard`.
198215
*

src/storage/page/page_guard.cpp

+31-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "storage/page/page_guard.h"
14+
#include <memory>
1415

1516
namespace bustub {
1617

@@ -25,10 +26,16 @@ namespace bustub {
2526
* @param frame A shared pointer to the frame that holds the page we want to protect.
2627
* @param replacer A shared pointer to the buffer pool manager's replacer.
2728
* @param bpm_latch A shared pointer to the buffer pool manager's latch.
29+
* @param disk_scheduler A shared pointer to the buffer pool manager's disk scheduler.
2830
*/
2931
ReadPageGuard::ReadPageGuard(page_id_t page_id, std::shared_ptr<FrameHeader> frame,
30-
std::shared_ptr<LRUKReplacer> replacer, std::shared_ptr<std::mutex> bpm_latch)
31-
: page_id_(page_id), frame_(std::move(frame)), replacer_(std::move(replacer)), bpm_latch_(std::move(bpm_latch)) {
32+
std::shared_ptr<LRUKReplacer> replacer, std::shared_ptr<std::mutex> bpm_latch,
33+
std::shared_ptr<DiskScheduler> disk_scheduler)
34+
: page_id_(page_id),
35+
frame_(std::move(frame)),
36+
replacer_(std::move(replacer)),
37+
bpm_latch_(std::move(bpm_latch)),
38+
disk_scheduler_(std::move(disk_scheduler)) {
3239
UNIMPLEMENTED("TODO(P1): Add implementation.");
3340
}
3441

@@ -92,6 +99,13 @@ auto ReadPageGuard::IsDirty() const -> bool {
9299
return frame_->is_dirty_;
93100
}
94101

102+
/**
103+
* @brief Flushes this page's data safely to disk.
104+
*
105+
* TODO(P1): Add implementation.
106+
*/
107+
void ReadPageGuard::Flush() { UNIMPLEMENTED("TODO(P1): Add implementation."); }
108+
95109
/**
96110
* @brief Manually drops a valid `ReadPageGuard`'s data. If this guard is invalid, this function does nothing.
97111
*
@@ -123,10 +137,16 @@ ReadPageGuard::~ReadPageGuard() { Drop(); }
123137
* @param frame A shared pointer to the frame that holds the page we want to protect.
124138
* @param replacer A shared pointer to the buffer pool manager's replacer.
125139
* @param bpm_latch A shared pointer to the buffer pool manager's latch.
140+
* @param disk_scheduler A shared pointer to the buffer pool manager's disk scheduler.
126141
*/
127142
WritePageGuard::WritePageGuard(page_id_t page_id, std::shared_ptr<FrameHeader> frame,
128-
std::shared_ptr<LRUKReplacer> replacer, std::shared_ptr<std::mutex> bpm_latch)
129-
: page_id_(page_id), frame_(std::move(frame)), replacer_(std::move(replacer)), bpm_latch_(std::move(bpm_latch)) {
143+
std::shared_ptr<LRUKReplacer> replacer, std::shared_ptr<std::mutex> bpm_latch,
144+
std::shared_ptr<DiskScheduler> disk_scheduler)
145+
: page_id_(page_id),
146+
frame_(std::move(frame)),
147+
replacer_(std::move(replacer)),
148+
bpm_latch_(std::move(bpm_latch)),
149+
disk_scheduler_(std::move(disk_scheduler)) {
130150
UNIMPLEMENTED("TODO(P1): Add implementation.");
131151
}
132152

@@ -198,6 +218,13 @@ auto WritePageGuard::IsDirty() const -> bool {
198218
return frame_->is_dirty_;
199219
}
200220

221+
/**
222+
* @brief Flushes this page's data safely to disk.
223+
*
224+
* TODO(P1): Add implementation.
225+
*/
226+
void WritePageGuard::Flush() { UNIMPLEMENTED("TODO(P1): Add implementation."); }
227+
201228
/**
202229
* @brief Manually drops a valid `WritePageGuard`'s data. If this guard is invalid, this function does nothing.
203230
*

0 commit comments

Comments
 (0)