BadgerDB
/afs/cs.wisc.edu/p/course/cs564-jignesh/public/html/projects/BadgerDB/bufmgr/src/main.cpp
00001 #include <iostream>
00002 #include <stdlib.h>
00003 //#include <stdio.h>
00004 #include <cstring>
00005 #include <memory>
00006 #include "page.h"
00007 #include "buffer.h"
00008 #include "file_iterator.h"
00009 #include "page_iterator.h"
00010 #include "exceptions/file_not_found_exception.h"
00011 #include "exceptions/invalid_page_exception.h"
00012 #include "exceptions/page_not_pinned_exception.h"
00013 #include "exceptions/page_pinned_exception.h"
00014 #include "exceptions/buffer_exceeded_exception.h"
00015 
00016 #define PRINT_ERROR(str) \
00017 { \
00018   std::cerr << "On Line No:" << __LINE__ << "\n"; \
00019   std::cerr << str << "\n"; \
00020   exit(1); \
00021 }
00022 
00023 using namespace badgerdb;
00024 
00025 const PageId num = 100;
00026 PageId pid[num], pageno1, pageno2, pageno3, i;
00027 RecordId rid[num], rid2, rid3;
00028 Page *page, *page2, *page3;
00029 char tmpbuf[100];
00030 BufMgr* bufMgr;
00031 File *file1ptr, *file2ptr, *file3ptr, *file4ptr, *file5ptr;
00032 
00033 void test1();
00034 void test2();
00035 void test3();
00036 void test4();
00037 void test5();
00038 void test6();
00039 void testBufMgr();
00040 
00041 int main() 
00042 {
00043   //Following code shows how to you File and Page classes
00044 
00045   const std::string& filename = "test.db";
00046   // Clean up from any previous runs that crashed.
00047   try
00048   {
00049     File::remove(filename);
00050   }
00051   catch(FileNotFoundException)
00052   {
00053   }
00054 
00055   {
00056     // Create a new database file.
00057     File new_file = File::create(filename);
00058     
00059     // Allocate some pages and put data on them.
00060     PageId third_page_number;
00061     for (int i = 0; i < 5; ++i) {
00062       Page new_page = new_file.allocatePage();
00063       if (i == 3) {
00064         // Keep track of the identifier for the third page so we can read it
00065         // later.
00066         third_page_number = new_page.page_number();
00067       }
00068       new_page.insertRecord("hello!");
00069       // Write the page back to the file (with the new data).
00070       new_file.writePage(new_page);
00071     }
00072 
00073     // Iterate through all pages in the file.
00074     for (FileIterator iter = new_file.begin();
00075          iter != new_file.end();
00076          ++iter) {
00077       // Iterate through all records on the page.
00078       for (PageIterator page_iter = (*iter).begin();
00079            page_iter != (*iter).end();
00080            ++page_iter) {
00081         std::cout << "Found record: " << *page_iter
00082             << " on page " << (*iter).page_number() << "\n";
00083       }
00084     }
00085 
00086     // Retrieve the third page and add another record to it.
00087     Page third_page = new_file.readPage(third_page_number);
00088     const RecordId& rid = third_page.insertRecord("world!");
00089     new_file.writePage(third_page);
00090 
00091     // Retrieve the record we just added to the third page.
00092     std::cout << "Third page has a new record: "
00093         << third_page.getRecord(rid) << "\n\n";
00094   }
00095   // new_file goes out of scope here, so file is automatically closed.
00096 
00097   // Delete the file since we're done with it.
00098   File::remove(filename);
00099 
00100   //This function tests buffer manager, comment this line if you don't wish to test buffer manager
00101   testBufMgr();
00102 }
00103 
00104 void testBufMgr()
00105 {
00106   // create buffer manager
00107   bufMgr = new BufMgr(num);
00108 
00109   // create dummy files
00110   const std::string& filename1 = "test.1";
00111   const std::string& filename2 = "test.2";
00112   const std::string& filename3 = "test.3";
00113   const std::string& filename4 = "test.4";
00114   const std::string& filename5 = "test.5";
00115 
00116   try
00117   {
00118     File::remove(filename1);
00119     File::remove(filename2);
00120     File::remove(filename3);
00121     File::remove(filename4);
00122     File::remove(filename5);
00123   }
00124   catch(FileNotFoundException e)
00125   {
00126   }
00127 
00128   File file1 = File::create(filename1);
00129   File file2 = File::create(filename2);
00130   File file3 = File::create(filename3);
00131   File file4 = File::create(filename4);
00132   File file5 = File::create(filename5);
00133 
00134   file1ptr = &file1;
00135   file2ptr = &file2;
00136   file3ptr = &file3;
00137   file4ptr = &file4;
00138   file5ptr = &file5;
00139 
00140   //Test buffer manager
00141   //Comment tests which you do not wish to run now. Tests are dependent on their preceding tests. So, they have to be run in the following order. 
00142   //Commenting  a particular test requires commenting all tests that follow it else those tests would fail.
00143   test1();
00144   test2();
00145   test3();
00146   test4();
00147   test5();
00148   test6();
00149 
00150   //Close files before deleting them
00151   file1.~File();
00152   file2.~File();
00153   file3.~File();
00154   file4.~File();
00155   file5.~File();
00156 
00157   //Delete files
00158   File::remove(filename1);
00159   File::remove(filename2);
00160   File::remove(filename3);
00161   File::remove(filename4);
00162   File::remove(filename5);
00163 
00164   delete bufMgr;
00165 
00166   std::cout << "\n" << "Passed all tests." << "\n";
00167 }
00168 
00169 void test1()
00170 {
00171   //Allocating pages in a file...
00172   for (i = 0; i < num; i++)
00173   {
00174     bufMgr->allocPage(file1ptr, pid[i], page);
00175     sprintf((char*)tmpbuf, "test.1 Page %d %7.1f", pid[i], (float)pid[i]);
00176     rid[i] = page->insertRecord(tmpbuf);
00177     bufMgr->unPinPage(file1ptr, pid[i], true);
00178   }
00179 
00180   //Reading pages back...
00181   for (i = 0; i < num; i++)
00182   {
00183     bufMgr->readPage(file1ptr, pid[i], page);
00184     sprintf((char*)&tmpbuf, "test.1 Page %d %7.1f", pid[i], (float)pid[i]);
00185     if(strncmp(page->getRecord(rid[i]).c_str(), tmpbuf, strlen(tmpbuf)) != 0)
00186     {
00187       PRINT_ERROR("ERROR :: CONTENTS DID NOT MATCH");
00188     }
00189     bufMgr->unPinPage(file1ptr, pid[i], false);
00190   }
00191   std::cout<< "Test 1 passed" << "\n";
00192 }
00193 
00194 void test2()
00195 {
00196   //Writing and reading back multiple files
00197   //The page number and the value should match
00198 
00199   for (i = 0; i < num/3; i++) 
00200   {
00201     bufMgr->allocPage(file2ptr, pageno2, page2);
00202     sprintf((char*)tmpbuf, "test.2 Page %d %7.1f", pageno2, (float)pageno2);
00203     rid2 = page2->insertRecord(tmpbuf);
00204 
00205     int index = random() % num;
00206     pageno1 = pid[index];
00207     bufMgr->readPage(file1ptr, pageno1, page);
00208     sprintf((char*)tmpbuf, "test.1 Page %d %7.1f", pageno1, (float)pageno1);
00209     if(strncmp(page->getRecord(rid[index]).c_str(), tmpbuf, strlen(tmpbuf)) != 0)
00210     {
00211       PRINT_ERROR("ERROR :: CONTENTS DID NOT MATCH");
00212     }
00213 
00214     bufMgr->allocPage(file3ptr, pageno3, page3);
00215     sprintf((char*)tmpbuf, "test.3 Page %d %7.1f", pageno3, (float)pageno3);
00216     rid3 = page3->insertRecord(tmpbuf);
00217 
00218     bufMgr->readPage(file2ptr, pageno2, page2);
00219     sprintf((char*)&tmpbuf, "test.2 Page %d %7.1f", pageno2, (float)pageno2);
00220     if(strncmp(page2->getRecord(rid2).c_str(), tmpbuf, strlen(tmpbuf)) != 0)
00221     {
00222       PRINT_ERROR("ERROR :: CONTENTS DID NOT MATCH");
00223     }
00224 
00225     bufMgr->readPage(file3ptr, pageno3, page3);
00226     sprintf((char*)&tmpbuf, "test.3 Page %d %7.1f", pageno3, (float)pageno3);
00227     if(strncmp(page3->getRecord(rid3).c_str(), tmpbuf, strlen(tmpbuf)) != 0)
00228     {
00229       PRINT_ERROR("ERROR :: CONTENTS DID NOT MATCH");
00230     }
00231 
00232     bufMgr->unPinPage(file1ptr, pageno1, false);
00233   }
00234 
00235   for (i = 0; i < num/3; i++) {
00236     bufMgr->unPinPage(file2ptr, i+1, true);
00237     bufMgr->unPinPage(file2ptr, i+1, true);
00238     bufMgr->unPinPage(file3ptr, i+1, true);
00239     bufMgr->unPinPage(file3ptr, i+1, true);
00240   }
00241 
00242   std::cout << "Test 2 passed" << "\n";
00243 }
00244 
00245 void test3()
00246 {
00247   try
00248   {
00249     bufMgr->readPage(file4ptr, 1, page);
00250     PRINT_ERROR("ERROR :: File4 should not exist. Exception should have been thrown before execution reaches this point.");
00251   }
00252   catch(InvalidPageException e)
00253   {
00254   }
00255 
00256   std::cout << "Test 3 passed" << "\n";
00257 }
00258 
00259 void test4()
00260 {
00261   bufMgr->allocPage(file4ptr, i, page);
00262   bufMgr->unPinPage(file4ptr, i, true);
00263   try
00264   {
00265     bufMgr->unPinPage(file4ptr, i, false);
00266     PRINT_ERROR("ERROR :: Page is already unpinned. Exception should have been thrown before execution reaches this point.");
00267   }
00268   catch(PageNotPinnedException e)
00269   {
00270   }
00271 
00272   std::cout << "Test 4 passed" << "\n";
00273 }
00274 
00275 void test5()
00276 {
00277   for (i = 0; i < num; i++) {
00278     bufMgr->allocPage(file5ptr, pid[i], page);
00279     sprintf((char*)tmpbuf, "test.5 Page %d %7.1f", pid[i], (float)pid[i]);
00280     rid[i] = page->insertRecord(tmpbuf);
00281   }
00282 
00283   PageId tmp;
00284   try
00285   {
00286     bufMgr->allocPage(file5ptr, tmp, page);
00287     PRINT_ERROR("ERROR :: No more frames left for allocation. Exception should have been thrown before execution reaches this point.");
00288   }
00289   catch(BufferExceededException e)
00290   {
00291   }
00292 
00293   std::cout << "Test 5 passed" << "\n";
00294 
00295   for (i = 1; i <= num; i++)
00296     bufMgr->unPinPage(file5ptr, i, true);
00297 }
00298 
00299 void test6()
00300 {
00301   //flushing file with pages still pinned. Should generate an error
00302   for (i = 1; i <= num; i++) {
00303     bufMgr->readPage(file1ptr, i, page);
00304   }
00305 
00306   try
00307   {
00308     bufMgr->flushFile(file1ptr);
00309     PRINT_ERROR("ERROR :: Pages pinned for file being flushed. Exception should have been thrown before execution reaches this point.");
00310   }
00311   catch(PagePinnedException e)
00312   {
00313   }
00314 
00315   std::cout << "Test 6 passed" << "\n";
00316 
00317   for (i = 1; i <= num; i++) 
00318     bufMgr->unPinPage(file1ptr, i, true);
00319 
00320   bufMgr->flushFile(file1ptr);
00321 }
 All Classes Namespaces Functions Variables Typedefs Friends