BadgerDB
 All Classes Namespaces Functions Variables Typedefs Enumerations 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 //----------------------------------------
20 // Constructor of the class BufMgr
21 //----------------------------------------
22 
23 BufMgr::BufMgr(std::uint32_t bufs)
24  : numBufs(bufs) {
25  bufDescTable = new BufDesc[bufs];
26 
27  for (FrameId i = 0; i < bufs; i++)
28  {
29  bufDescTable[i].frameNo = i;
30  bufDescTable[i].valid = false;
31  }
32 
33  bufPool = new Page[bufs];
34 
35  int htsize = ((((int) (bufs * 1.2))*2)/2)+1;
36  hashTable = new BufHashTbl (htsize); // allocate the buffer hash table
37 
38  clockHand = bufs - 1;
39 }
40 
41 
43  //Flush out all unwritten pages
44  for (std::uint32_t i = 0; i < numBufs; i++)
45  {
46  BufDesc* tmpbuf = &bufDescTable[i];
47  if (tmpbuf->valid == true && tmpbuf->dirty == true)
48  {
49  tmpbuf->file->writePage(tmpbuf->pageNo, bufPool[i]);
50  }
51  }
52 
53  delete [] bufDescTable;
54  delete [] bufPool;
55 }
56 
57 void BufMgr::allocBuf(FrameId & frame)
58 {
59  // perform first part of clock algorithm to search for
60  // open buffer frame
61  // Assumes non-concurrent access to buffer manager
62  std::uint32_t numScanned = 0;
63  bool found = 0;
64 
65  while (numScanned < 2*numBufs) //Need to scn twice
66  {
67  // advance the clock
68  advanceClock();
69  numScanned++;
70 
71  // if invalid, use frame
72  if (! bufDescTable[clockHand].valid)
73  {
74  break;
75  }
76 
77  // is valid, check referenced bit
78  if (! bufDescTable[clockHand].refbit)
79  {
80  // check to see if someone has it pinned
81  if (bufDescTable[clockHand].pinCnt == 0)
82  {
83  // hasn't been referenced and is not pinned, use it
84  // remove previous entry from hash table
85  hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo);
86  found = true;
87  break;
88  }
89  }
90  else
91  {
92  // has been referenced, clear the bit
93  bufStats.accesses++;
94  bufDescTable[clockHand].refbit = false;
95  }
96  }
97 
98  // check for full buffer pool
99  if (!found && numScanned >= 2*numBufs)
100  {
101  throw BufferExceededException();
102  }
103 
104  // flush any existing changes to disk if necessary
105  if (bufDescTable[clockHand].dirty)
106  {
107  bufStats.diskwrites++;
108  //status = bufDescTable[clockHand].file->writePage(bufDescTable[clockHand].pageNo,
109  bufDescTable[clockHand].file->writePage(bufDescTable[clockHand].pageNo, bufPool[clockHand]);
110  }
111 
112  //Reset all the BufDesc entry for the frame before returning the frame
113  bufDescTable[clockHand].Clear();
114 
115  // return new frame number
116  frame = clockHand;
117 } // end allocBuf
118 
119 
120 void BufMgr::readPage(File* file, const PageId pageNo, Page*& page)
121 {
122  // check to see if it is already in the buffer pool
123  // std::cout << "readPage called on file.page " << file << "." << pageNo << endl;
124  FrameId frameNo = 0;
125  try
126  {
127  hashTable->lookup(file, pageNo, frameNo);
128 
129  // set the referenced bit
130  bufDescTable[frameNo].refbit = true;
131  bufDescTable[frameNo].pinCnt++;
132  page = &bufPool[frameNo];
133  }
134  catch(HashNotFoundException e) //not in the buffer pool, must allocate a new page
135  {
136  // alloc a new frame
137  allocBuf(frameNo);
138 
139  // read the page into the new frame
140  bufStats.diskreads++;
141  //status = file->readPage(pageNo, &bufPool[frameNo]);
142  bufPool[frameNo] = file->readPage(pageNo);
143 
144  // set up the entry properly
145  bufDescTable[frameNo].Set(file, pageNo);
146  page = &bufPool[frameNo];
147 
148  // insert in the hash table
149  hashTable->insert(file, pageNo, frameNo);
150  }
151 }
152 
153 
154 void BufMgr::unPinPage(File* file, const PageId pageNo,
155  const bool dirty)
156 {
157  // lookup in hashtable
158  FrameId frameNo = 0;
159  hashTable->lookup(file, pageNo, frameNo);
160 
161  if (dirty == true) bufDescTable[frameNo].dirty = dirty;
162 
163  // make sure the page is actually pinned
164  if (bufDescTable[frameNo].pinCnt == 0)
165  {
166  throw PageNotPinnedException(file->filename(), pageNo, frameNo);
167  }
168  else bufDescTable[frameNo].pinCnt--;
169 }
170 
171 void BufMgr::flushFile(const File* file)
172 {
173  for (std::uint32_t i = 0; i < numBufs; i++)
174  {
175  BufDesc* tmpbuf = &(bufDescTable[i]);
176  if(tmpbuf->valid == true && tmpbuf->file == file)
177  {
178  if (tmpbuf->pinCnt > 0)
179  throw PagePinnedException(file->filename(), tmpbuf->pageNo, tmpbuf->frameNo);
180 
181  if (tmpbuf->dirty == true)
182  {
183  //if ((status = tmpbuf->file->writePage(tmpbuf->pageNo, &(bufPool[i]))) != OK)
184  tmpbuf->file->writePage(tmpbuf->pageNo, bufPool[i]);
185  tmpbuf->dirty = false;
186  }
187 
188  hashTable->remove(file,tmpbuf->pageNo);
189  tmpbuf->Clear();
190  }
191  else if (tmpbuf->valid == false && tmpbuf->file == file)
192  throw BadBufferException(tmpbuf->frameNo, tmpbuf->dirty, tmpbuf->valid, tmpbuf->refbit);
193  }
194 }
195 
196 void BufMgr::disposePage(File* file, const PageId pageNo)
197 {
198  //Deallocate from file altogether
199  //See if it is in the buffer pool
200  FrameId frameNo = 0;
201  hashTable->lookup(file, pageNo, frameNo);
202 
203  // clear the page
204  bufDescTable[frameNo].Clear();
205 
206  hashTable->remove(file, pageNo);
207 
208  // deallocate it in the file
209  file->deletePage(pageNo);
210 }
211 
212 
213 void BufMgr::allocPage(File* file, PageId &pageNo, Page*& page)
214 {
215  FrameId frameNo;
216 
217  // alloc a new frame
218  allocBuf(frameNo);
219 
220  // allocate a new page in the file
221  //std::cerr << "buffer data size:" << bufPool[frameNo].data_.length() << "\n";
222  bufPool[frameNo] = file->allocatePage(pageNo);
223  page = &bufPool[frameNo];
224 
225  // set up the entry properly
226  bufDescTable[frameNo].Set(file, pageNo);
227 
228  // insert in the hash table
229  hashTable->insert(file, pageNo, frameNo);
230 }
231 
232 void BufMgr::printSelf(void)
233 {
234  BufDesc* tmpbuf;
235  int validFrames = 0;
236 
237  for (std::uint32_t i = 0; i < numBufs; i++)
238  {
239  tmpbuf = &(bufDescTable[i]);
240  std::cout << "FrameNo:" << i << " ";
241  tmpbuf->Print();
242 
243  if (tmpbuf->valid == true)
244  validFrames++;
245  }
246 
247  std::cout << "Total Number of Valid Frames:" << validFrames << "\n";
248 }
249 
250 }
An exception that is thrown when a page which is expected to be pinned in the buffer pool is found to...
virtual void writePage(const PageId page_number, const Page &new_page)=0
const std::string & filename() const
Definition: file.h:158
void readPage(File *file, const PageId PageNo, Page *&page)
Definition: buffer.cpp:120
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:75
virtual void deletePage(const PageId page_number)=0
void unPinPage(File *file, const PageId PageNo, const bool dirty)
Definition: buffer.cpp:154
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:108
Class for maintaining information about buffer pool frames.
Definition: buffer.h:24
BufMgr(std::uint32_t bufs)
Definition: buffer.cpp:23
void flushFile(const File *file)
Definition: buffer.cpp:171
void lookup(const File *file, const PageId pageNo, FrameId &frameNo)
Definition: bufHashTbl.cpp:70
An exception that is thrown when a buffer is found whose valid is false but other variables in BufDes...
Page * bufPool
Definition: buffer.h:210
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:232
virtual Page readPage(const PageId page_number) const =0
void disposePage(File *file, const PageId PageNo)
Definition: buffer.cpp:196
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:86
void insert(const File *file, const PageId pageNo, const FrameId frameNo)
Definition: bufHashTbl.cpp:48
virtual Page allocatePage(PageId &new_page_number)=0
void allocPage(File *file, PageId &PageNo, Page *&page)
Definition: buffer.cpp:213
An exception that is thrown when an entry being looked up in the hash table is not present in it...