-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBuffer.cpp
More file actions
129 lines (96 loc) · 3.39 KB
/
Buffer.cpp
File metadata and controls
129 lines (96 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "Buffer.hpp"
Buffer_Page::Buffer_Page(int id, PageType t) : pageId(id), type(t), referenceBit(true), dirtyBit(false), pinCount(0) {
std::memset(data, 0, PAGE_SIZE);
}
void Buffer_Page::writeToDisk() {
if (dirtyBit) {
std::ofstream file("page_" + std::to_string(pageId) + ".dat", std::ios::binary);
file.write(data, PAGE_SIZE);
file.close();
dirtyBit = false;
}
}
Buffer_Page* Buffer_Page::readFromDisk(int pageId, PageType type) {
Buffer_Page* page = new Buffer_Page(pageId, type);
std::ifstream file("page_" + std::to_string(pageId) + ".dat", std::ios::binary);
if (file.is_open()) {
file.read(page->data, PAGE_SIZE);
file.close();
}
return page;
}
BufferPool::BufferPool(int size) : bufferSize(size), clockHand(0) {
bufferPool.resize(bufferSize, nullptr);
}
BufferPool::~BufferPool() {
for (Buffer_Page* page : bufferPool) {
if (page) {
page->writeToDisk();
delete page;
}
}
}
int BufferPool::getNewPageId() {
std::cout << "from get page id";
return 0;
}
Buffer_Page* BufferPool::requestPage(int pageId, PageType type, bool isWrite) {
if (pageTable.find(pageId) != pageTable.end()) {
Buffer_Page* page = pageTable[pageId];
page->referenceBit = true;
page->pinCount++;
return page;
} else {
return replacePage(pageId, type, isWrite);
}
}
void BufferPool::releasePage(int pageId) {
if (pageTable.find(pageId) != pageTable.end()) {
Buffer_Page* page = pageTable[pageId];
page->pinCount = std::max(0, page->pinCount - 1);
}
}
Buffer_Page* BufferPool::replacePage(int pageId, PageType type, bool isWrite) {
while (true) {
Buffer_Page* page = bufferPool[clockHand];
if (page == nullptr || (page->pinCount == 0 && !page->referenceBit)) {
if (page != nullptr) {
if (page->dirtyBit) {
page->writeToDisk();
}
pageTable.erase(page->pageId);
delete page;
}
Buffer_Page* newPage = Buffer_Page::readFromDisk(pageId, type);
newPage->pinCount++;
if (isWrite) {
newPage->dirtyBit = true;
}
bufferPool[clockHand] = newPage;
pageTable[pageId] = newPage;
clockHand = (clockHand + 1) % bufferSize;
return newPage;
} else if (page->pinCount == 0 && page->referenceBit) {
page->referenceBit = false;
clockHand = (clockHand + 1) % bufferSize;
} else {
clockHand = (clockHand + 1) % bufferSize;
}
}
}
void BufferPool::displayBufferPool() const {
std::cout << "Buffer Pool State:\n";
for (size_t i = 0; i < bufferPool.size(); i++) {
const Buffer_Page* page = bufferPool[i];
if (page) {
std::cout << "Page ID: " << page->pageId
<< ", Type: " << (page->type == INDEX_PAGE ? "INDEX" : "DATA")
<< ", Pin Count: " << page->pinCount
<< ", Dirty: " << page->dirtyBit
<< ", Reference: " << page->referenceBit
<< "\n";
} else {
std::cout << "Empty Slot\n";
}
}
}