BadgerDB
 All Classes Namespaces Functions Variables Typedefs Friends Pages
buffer.cpp
1 
8 #include <memory>
9 #include <iostream>
10 #include "buffer.h"
11 #include "exceptions/buffer_exceeded_exception.h"
12 #include "exceptions/page_not_pinned_exception.h"
13 #include "exceptions/page_pinned_exception.h"
14 #include "exceptions/bad_buffer_exception.h"
15 #include "exceptions/hash_not_found_exception.h"
16 
17 namespace badgerdb {
18 
19 BufMgr::BufMgr(std::uint32_t bufs)
20  : numBufs(bufs) {
21  bufDescTable = new BufDesc[bufs];
22 
23  for (FrameId i = 0; i < bufs; i++)
24  {
25  bufDescTable[i].frameNo = i;
26  bufDescTable[i].valid = false;
27  }
28 
29  bufPool = new Page[bufs];
30 
31  int htsize = ((((int) (bufs * 1.2))*2)/2)+1;
32  hashTable = new BufHashTbl (htsize); // allocate the buffer hash table
33 
34  clockHand = bufs - 1;
35 }
36 
37 
39 
40  // 1. Flush all dirty pages to disk
41  for ( std::uint32_t i = 0 ; i < numBufs; ++i ) {
42  if (bufDescTable[i].dirty) {
43  bufDescTable[i].file->writePage(bufPool[i]);
44  }
45  }
46  // 2. deallocate buffer pool
47  delete hashTable; // ?? not mentioned in the pdf
48  delete [] bufPool;
49  // 3. deallocate BufDesc table
50  delete [] bufDescTable;
51 
52 
53 }
54 
55 void BufMgr::advanceClock()
56 { // advance the clock hand to the next frame in the buffer pool
57  clockHand = (clockHand+1)%numBufs;
58 }
59 
60 // TOBETEST BufMgr::allocBuf
61 void BufMgr::allocBuf(FrameId & frame)
62 {
63  // |------->Advance clock
64  // | |
65  // | v
66  // | check valid bit --------------------------------------|
67  // | | Yes No |
68  // |clear,Y v |
69  // |------<- check refbit |
70  // | | No |
71  // | Yes v |
72  // ----- < page pinned? |
73  // | No |
74  // v |
75  // dirty bit set? --> if yes, flush to disk |
76  // | No | |
77  // v v |
78  // call set() <----------------J---------------------------J
79  // |
80  // v
81  // Use it.
85  BufDesc* tmpbuf;
86  std::uint32_t i = 0 ;
87 
88  // Scan two rounds for replacable buffer
89  for ( i = 0 ; i < numBufs*2; ++i ) {
90  advanceClock();
91  tmpbuf = &bufDescTable[clockHand];
92  if ( ! tmpbuf->valid )
93  goto found;
94  if ( tmpbuf->refbit ) {
95  tmpbuf->refbit = false; // clear the refbit
96  continue;
97  }
98  if ( tmpbuf->pinCnt > 0 )
99  continue;
100 
101  if ( tmpbuf->dirty ) // flush into disk
102  tmpbuf->file->writePage(bufPool[clockHand]);
103 
104  // remove the entry if the frame is valid before
105  hashTable->remove(tmpbuf->file, tmpbuf->pageNo);
106  goto found;
107  }
108 
109  throw BufferExceededException();
110 
111 found:
112  frame = tmpbuf->frameNo; // Id == No ?? YES
113  tmpbuf->Clear();
114 }
115 
116 // TOBETEST BufMgr::readPage
117 void BufMgr::readPage(File* file, const PageId pageNo, Page*& page)
118 {
119  FrameId frameNo;
120  if ( hashTable->lookup(file, pageNo, frameNo) ) { // found
121  bufDescTable[frameNo].refbit = true;
122  bufDescTable[frameNo].pinCnt++;
123  } else { // not found
124  allocBuf(frameNo);
125  bufPool[frameNo] = file->readPage(pageNo);
126  hashTable->insert(file, pageNo, frameNo);
127  bufDescTable[frameNo].Set(file, pageNo);
128  }
129  page = &bufPool[frameNo];
130 }
131 
132 // TOBETEST BufMgr::unPinPage
133 void BufMgr::unPinPage(File* file, const PageId pageNo, const bool dirty)
134 {
135  FrameId frameNo;
136  if ( hashTable->lookup(file, pageNo, frameNo)) { // found
137  if ( dirty ) bufDescTable[frameNo].dirty = true;
138  if ( bufDescTable[frameNo].pinCnt > 0 ) {
139  bufDescTable[frameNo].pinCnt--;
140  } else {
141  throw PageNotPinnedException(file->filename(), pageNo, frameNo);
142  }
143  }
144 
145 }
146 
147 // TOBETEST BufMgr::flushFile
148 void BufMgr::flushFile(const File* file)
149 {
150 
151  BufDesc* tmpbuf;
152  for (std::uint32_t i = 0 ; i < numBufs ; ++i ) {
153  tmpbuf = &bufDescTable[i];
154  if ( tmpbuf->file == file ) { //Is this the way to check if belong to same file?
155  if ( tmpbuf->pinCnt > 0 ) {
156  throw PagePinnedException(file->filename(),
157  tmpbuf->pageNo,
158  tmpbuf->frameNo);
159  }
160  if ( ! tmpbuf->valid ) {
161  throw BadBufferException(tmpbuf->frameNo,
162  tmpbuf->dirty,
163  tmpbuf->valid,
164  tmpbuf->refbit);
165  }
166  if ( tmpbuf->dirty )
167  tmpbuf->file->writePage(bufPool[i]);
168  hashTable->remove(tmpbuf->file, tmpbuf->pageNo);
169  tmpbuf->Clear();
170 
171  }
172  }
173 
174 }
175 
176 // TOBETEST BufMgr::allocPage
177 void BufMgr::allocPage(File* file, PageId &pageNo, Page*& page)
178 {
179  FrameId frameNo;
180  allocBuf(frameNo);
181  bufPool[frameNo] = file->allocatePage();
182  pageNo = bufPool[frameNo].page_number();
183 // fprintf(stderr, "info: %s +%d %s\n", __FILE__, __LINE__, __func__);
184 
185  hashTable->insert(file, pageNo, frameNo);
186  bufDescTable[frameNo].Set(file, pageNo);
187  page = &bufPool[frameNo];
188 }
189 
190 // TOBETEST BufMgr::disposePage
191 void BufMgr::disposePage(File* file, const PageId PageNo)
192 {
193  FrameId frameNo;
194  if ( hashTable->lookup(file, PageNo, frameNo) ) {
195  BufDesc* tmpbuf = &bufDescTable[frameNo];
196  hashTable->remove(tmpbuf->file, tmpbuf->pageNo);
197  tmpbuf->Clear();
198  }
199  file->deletePage(PageNo);
200 
201 }
202 
203 // TOBETEST BufMgr::printSelf
204 void BufMgr::printSelf(void)
205 {
206  BufDesc* tmpbuf;
207  int validFrames = 0;
208 
209  for (std::uint32_t i = 0; i < numBufs; i++)
210  {
211  tmpbuf = &(bufDescTable[i]);
212  std::cout << "FrameNo:" << i << " ";
213  tmpbuf->Print();
214 
215  if (tmpbuf->valid == true)
216  validFrames++;
217  }
218 
219  std::cout << "Total Number of Valid Frames:" << validFrames << "\n";
220 }
221 
222 }
An exception that is thrown when a page which is expected to be pinned in the buffer pool is found to...
const std::string & filename() const
Definition: file.h:179
void readPage(File *file, const PageId PageNo, Page *&page)
Definition: buffer.cpp:117
std::uint32_t FrameId
Identifier for a frame in buffer pool.
Definition: types.h:25
Class which represents a file in the filesystem containing database pages.
Definition: file.h:73
void unPinPage(File *file, const PageId PageNo, const bool dirty)
Definition: buffer.cpp:133
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
Class which represents a fixed-size database page containing records.
Definition: page.h:107
Class for maintaining information about buffer pool frames.
Definition: buffer.h:23
void writePage(const Page &new_page)
Definition: file.cpp:169
BufMgr(std::uint32_t bufs)
Definition: buffer.cpp:19
void flushFile(const File *file)
Definition: buffer.cpp:148
An exception that is thrown when a buffer is found whose valid is false but other variables in BufDes...
PageId page_number() const
Definition: page.h:193
Page * bufPool
Definition: buffer.h:205
bool lookup(const File *file, const PageId pageNo, FrameId &frameNo)
Definition: bufHashTbl.cpp:70
An exception that is thrown when a page which is not expected to be pinned in the buffer pool is foun...
void printSelf()
Definition: buffer.cpp:204
Page readPage(const PageId page_number) const
Definition: file.cpp:149
Page allocatePage()
Definition: file.cpp:84
void disposePage(File *file, const PageId PageNo)
Definition: buffer.cpp:191
Hash table class to keep track of pages in the buffer pool.
Definition: bufHashTbl.h:45
void remove(const File *file, const PageId pageNo)
Definition: bufHashTbl.cpp:85
void insert(const File *file, const PageId pageNo, const FrameId frameNo)
Definition: bufHashTbl.cpp:48
void allocPage(File *file, PageId &PageNo, Page *&page)
Definition: buffer.cpp:177
void deletePage(const PageId page_number)
Definition: file.cpp:184