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