// create pages 100 with content "Page X" and perform 10000 random reads of these pages and check that the correct pages are read void testCreatingAndRandomReadingDummyPages (void) { int i; BM_BufferPool *bm = MAKE_POOL(); testName = "Creating and Dummy Pages and reading them in random order"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 10, RS_FIFO, NULL)); srand(time(0)); for(i = 0; i < 10000; i++) { int page = rand() % NUM_DUMMY_PAGES; readAndCheckDummyPage(bm, page); } CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); TEST_DONE(); }
void testReadPage () { BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Reading a page"; CHECK(createPageFile("testbuffer.bin")); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); CHECK(pinPage(bm, h, 0)); CHECK(pinPage(bm, h, 0)); CHECK(markDirty(bm, h)); CHECK(unpinPage(bm,h)); CHECK(unpinPage(bm,h)); CHECK(forcePage(bm, h)); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
RC openTable (RM_TableData *rel, char *name){ page=(BM_PageHandle *)calloc(PAGE_SIZE,sizeof(BM_PageHandle)); Schema *schema; bm=MAKE_POOL(); initBufferPool(bm,name, 3, RS_FIFO, NULL); pinPage(bm, page,0); schema=stringToSchema(page->data); rel->name=name; rel->schema=schema; rel->mgmtData=bm; return RC_OK; }
void testClock(void) { // expected results const char *poolContents[]= { "[3x0],[-1 0],[-1 0],[-1 0]", "[3x0],[2 0],[-1 0],[-1 0]", "[3x0],[2 0],[0 0],[-1 0]", "[3x0],[2 0],[0 0],[8 0]", "[4 0],[2 0],[0 0],[8 0]", "[4 0],[2 0],[0 0],[8 0]", "[4 0],[2 0],[5 0],[8 0]", "[4 0],[2 0],[5 0],[0 0]", "[9 0],[2 0],[5 0],[0 0]", "[9 0],[8 0],[5 0],[0 0]", "[9 0],[8 0],[3x0],[0 0]", "[9 0],[8 0],[3x0],[2 0]" }; const int orderRequests[]= {3,2,0,8,4,2,5,0,9,8,3,2}; int i; int snapshot = 0; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing CLOCK page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 4, RS_CLOCK, NULL)); for (i=0;i<11;i++) { pinPage(bm,h,orderRequests[i]); if(orderRequests[i] == 3) markDirty(bm,h); unpinPage(bm,h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content using pages"); } forceFlushPool(bm); // check number of write IOs ASSERT_EQUALS_INT(2, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(10, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
/* * This function is used to Open a Created Table, * for any operation to be performed, the table has to be opened first * Also store the Schema related info by deserializing the schema, * in the Table Data */ RC openTable (RM_TableData *rel, char *name) { //Record Management to store record attributes RM_RecordMgmt *rm_mgmt = (RM_RecordMgmt*)malloc(sizeof(RM_RecordMgmt)); FILE *fptr; //FILE pointer fptr = fopen(name, "r+"); //Open the PageFile (Table) //Get the total Number of Pages in the page File char* readHeader; readHeader = (char*)calloc(PAGE_SIZE,sizeof(char)); fgets(readHeader,PAGE_SIZE,fptr); char* totalPage; totalPage = readHeader; totalPages = atoi(totalPage); //convert to integer //Make a Buffer Pool rm_mgmt->bm = MAKE_POOL(); //Make a Page Handle BM_PageHandle *page = MAKE_PAGE_HANDLE(); //Initialize the BufferPool initBufferPool(rm_mgmt->bm,name,6,RS_FIFO,NULL); //Pin the Page = 0, which has the Schema Information pinPage(rm_mgmt->bm,page,0); //FreePages are stored in an array rm_mgmt->freePages = (int*)malloc(sizeof(int)); rm_mgmt->freePages[0] = totalPages; //initialize the table data attributes //Deserialzing the Schema gives us the Relation information (i.e. Schema info) rel->schema = deserializeSchema(page->data); //store the name of the schema rel->name = name; //store the record management details rel->mgmtData = rm_mgmt; //Free the temp. memory allocations free(readHeader); free(page); return RC_OK; }
// test error cases void testError (void) { BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "ERROR TEST"; CHECK(createPageFile("testbuffer.bin")); // pinpage until buffer pool is full and then request additional page. CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); CHECK(pinPage(bm, h, 0)); CHECK(pinPage(bm, h, 1)); CHECK(pinPage(bm, h, 2)); ASSERT_ERROR(pinPage(bm, h, 3), "try to pin page when pool is full of pinned pages with fix-count > 0"); CHECK(shutdownBufferPool(bm)); // try to pin page with negative page number. CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); ASSERT_ERROR(pinPage(bm, h, -10), "try to pin page with negative page number"); CHECK(shutdownBufferPool(bm)); // try to use uninitialized buffer pool ASSERT_ERROR(initBufferPool(bm, "unavailable.bin", 3, RS_FIFO, NULL), "try to init buffer pool for non existing page file"); ASSERT_ERROR(shutdownBufferPool(bm), "shutdown buffer pool that is not open"); ASSERT_ERROR(forceFlushPool(bm), "flush buffer pool that is not open"); ASSERT_ERROR(pinPage(bm, h, 1), "pin page in buffer pool that is not open"); // try to unpin, mark, or force page that is not in pool CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); ASSERT_ERROR(unpinPage(bm, h), "Try to unpin a page which is not available in framelist."); ASSERT_ERROR(forcePage(bm, h), "Try to forceflush a page which is not available in framelist."); ASSERT_ERROR(markDirty(bm, h), "Try to markdirty a page which is not available in framelist."); CHECK(shutdownBufferPool(bm)); // done remove page file CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
// create n pages with content "Page X" and read them back to check whether the content is right void testCreatingAndReadingDummyPages(void) { BM_BufferPool *bm = MAKE_POOL(); testName = "Creating and Reading Back Dummy Pages"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 22); checkDummyPages(bm, 20); createDummyPages(bm, 10000); checkDummyPages(bm, 10000); CHECK(destroyPageFile("testbuffer.bin")); free(bm); TEST_DONE() ; }
// test error cases void testError (void) { int i; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing LRU page replacement"; CHECK(createPageFile("testbuffer.bin")); // pin until buffer pool is full and request additional page CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); CHECK(pinPage(bm, h, 0)); CHECK(pinPage(bm, h, 1)); CHECK(pinPage(bm, h, 2)); ASSERT_ERROR(pinPage(bm, h, 3), "try to pin page when pool is full of pinned pages"); CHECK(shutdownBufferPool(bm)); // try to ready page with negative page number CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); ASSERT_ERROR(pinPage(bm, h, -1), "try to pin page with negative page number"); CHECK(shutdownBufferPool(bm)); // try to use uninitialized buffer pool ASSERT_ERROR(shutdownBufferPool(bm), "shutdown buffer pool that is not open"); ASSERT_ERROR(forceFlushPool(bm), "flush buffer pool that is not open"); ASSERT_ERROR(pinPage(bm, h, 1), "pin page in buffer pool that is not open"); ASSERT_ERROR(initBufferPool(bm, "xxx.bin", 3, RS_FIFO, NULL), "try to init buffer pool for non existing page file"); // try to unpin, mark, or force page that is not in pool CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); ASSERT_ERROR(unpinPage(bm, h), "unpin page not in buffer pool"); ASSERT_ERROR(forcePage(bm, h), "unpin page not in buffer pool"); ASSERT_ERROR(markDirty(bm, h), "mark page dirty that is not in buffer pool"); CHECK(shutdownBufferPool(bm)); // done remove page file CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
void testsimpleFIFO () { printf("FIFO Execution in new thread : \n " ); // expected results const char *poolContents[] = { "[0 0],[-1 0],[-1 0]" , "[0 0],[1 0],[-1 0]", "[0 0],[1 0],[2 0]", "[3 0],[1 0],[2 0]" }; const int requests[] = {0,1,2,3,4,4,5,6,0}; const int numLinRequests = 4; int i; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing FIFO page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); // reading some pages linearly with direct unpin and no modifications for(i = 0; i < numLinRequests; i++) { pinPage(bm, h, requests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i], bm, "check pool content"); } CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
RC openBtree (BTreeHandle **tree, char *idxId){ DataType keyType; int rootPage; int nodeNum; int entryNum; int n; BM_BufferPool *bufferPool = MAKE_POOL(); SM_FileHandle *fHandle = (SM_FileHandle *)calloc(1, sizeof(SM_FileHandle)); char * metadata = (char *)calloc(PAGE_SIZE, sizeof(char)); openPageFile(idxId, fHandle); initBufferPool(bufferPool, idxId, 10, RS_LRU, NULL); readBlock(0, fHandle, metadata); memcpy(&rootPage, metadata,sizeof(int)); memcpy(&nodeNum, metadata+sizeof(int),sizeof(int)); memcpy(&entryNum, metadata+2*sizeof(int),sizeof(int)); memcpy(&n, metadata+3*sizeof(int),sizeof(int)); memcpy(&keyType, metadata + 4*sizeof(int),sizeof(DataType)); *tree = (BTreeHandle *)calloc(1, sizeof(BTreeHandle)); (*tree)->keyType = keyType; (*tree)->rootPage = rootPage; (*tree)->nodeNum = nodeNum; (*tree)->entryNum = entryNum; (*tree)->n = n; (*tree)->bufferPool = bufferPool; (*tree)->fileHandle = fHandle; (*tree)->idxId = idxId; free(metadata); return RC_OK; }
// test the LRU page replacement strategy void testLRU (void) { // expected results const char *poolContents[] = { // read first five pages and directly unpin them "[0 0],[-1 0],[-1 0],[-1 0],[-1 0]" , "[0 0],[1 0],[-1 0],[-1 0],[-1 0]", "[0 0],[1 0],[2 0],[-1 0],[-1 0]", "[0 0],[1 0],[2 0],[3 0],[-1 0]", "[0 0],[1 0],[2 0],[3 0],[4 0]", // use some of the page to create a fixed LRU order without changing pool content "[0 0],[1 0],[2 0],[3 0],[4 0]", "[0 0],[1 0],[2 0],[3 0],[4 0]", "[0 0],[1 0],[2 0],[3 0],[4 0]", "[0 0],[1 0],[2 0],[3 0],[4 0]", "[0 0],[1 0],[2 0],[3 0],[4 0]", // check that pages get evicted in LRU order "[0 0],[1 0],[2 0],[5 0],[4 0]", "[0 0],[1 0],[2 0],[5 0],[6 0]", "[7 0],[1 0],[2 0],[5 0],[6 0]", "[7 0],[1 0],[8 0],[5 0],[6 0]", "[7 0],[9 0],[8 0],[5 0],[6 0]" }; const int orderRequests[] = {3,4,0,2,1}; const int numLRUOrderChange = 5; int i; int snapshot = 0; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing LRU page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 5, RS_LRU, NULL)); // reading first five pages linearly with direct unpin and no modifications for(i = 0; i < 5; i++) { pinPage(bm, h, i); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content reading in pages"); } // read pages to change LRU order for(i = 0; i < numLRUOrderChange; i++) { pinPage(bm, h, orderRequests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content using pages"); } // replace pages and check that it happens in LRU order for(i = 0; i < 5; i++) { pinPage(bm, h, 5 + i); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content using pages"); } // check number of write IOs ASSERT_EQUALS_INT(0, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(10, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
void testFIFO () { // expected results const char *poolContents[] = { "[0 0],[-1 0],[-1 0]" , "[0 0],[1 0],[-1 0]", "[0 0],[1 0],[2 0]", "[3 0],[1 0],[2 0]", "[3 0],[4 0],[2 0]", "[3 0],[4 1],[2 0]", "[3 0],[4 1],[5x0]", "[6x0],[4 1],[5x0]", "[6x0],[4 1],[0x0]", "[6x0],[4 0],[0x0]", "[6 0],[4 0],[0 0]" }; const int requests[] = {0,1,2,3,4,4,5,6,0}; const int numLinRequests = 5; const int numChangeRequests = 3; int i; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing FIFO page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); // reading some pages linearly with direct unpin and no modifications for(i = 0; i < numLinRequests; i++) { pinPage(bm, h, requests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i], bm, "check pool content"); } // pin one page and test remainder i = numLinRequests; pinPage(bm, h, requests[i]); ASSERT_EQUALS_POOL(poolContents[i],bm,"pool content after pin page"); // read pages and mark them as dirty for(i = numLinRequests + 1; i < numLinRequests + numChangeRequests + 1; i++) { pinPage(bm, h, requests[i]); markDirty(bm, h); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i], bm, "check pool content"); } // flush buffer pool to disk i = numLinRequests + numChangeRequests + 1; h->pageNum = 4; unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i],bm,"unpin last page"); i++; forceFlushPool(bm); ASSERT_EQUALS_POOL(poolContents[i],bm,"pool content after flush"); // check number of write IOs ASSERT_EQUALS_INT(3, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(8, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
// test the CLOCK page replacement strategy void testClock (void) { // expected results const char *poolContents[] = { // read first five pages and directly unpin them "[0 0],[-1 0],[-1 0]" , "[0 0],[1 0],[-1 0]" , "[2 0],[1 0],[-1 0]" , "[2 0],[1 0],[3 0]" , // pin the page 2 again "[2 0],[1 0],[3 0]" , // read other pages use pin_CLOCK "[2 0],[4 0],[3 0]" , "[5 0],[4 0],[3 0]" , "[6 0],[4 0],[3 0]", "[6 0],[7 0],[3 0]" }; const int orderRequests[] = {2}; const int numrfChange = 1; int i; int snapshot = 0; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing CLOCK page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_CLOCK, NULL)); // reading first five pages linearly with direct unpin and no modifications for(i = 0; i <4; i++) { pinPage(bm, h, i); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content reading in pages"); } // read pages to rf of the frames for(i = 0; i < numrfChange; i++) { pinPage(bm, h, orderRequests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content using pages"); } // replace pages and check that it happens in LRU_K order for(i = 0; i < 4; i++) { pinPage(bm, h, 4 + i); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[snapshot++], bm, "check pool content using pages"); } // check number of write IOs ASSERT_EQUALS_INT(0, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(8, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
//Clock[START] void testClock() { // expected results const char *poolContents[] = { "[0 0],[-1 0],[-1 0]", "[0 0],[4 0],[-1 0]", "[0 0],[4 0],[1 0]", "[0 0],[4 0],[1 0]", "[2 0],[4 0],[1 0]", "[2 0],[4 0],[1 0]", "[2 0],[4 0],[3 0]", "[2 0],[4 0],[3 0]", "[2 0],[4 0],[3 0]", "[2 0],[4 0],[3 0]", "[2 0],[4 0],[0 0]", "[2 0],[4 0],[0 0]", "[1 0],[4 0],[0 0]", "[1 0],[4 0],[0 0]", "[1 0],[4 0],[2 0]", "[1 0],[4 0],[2 0]", "[3 0],[4 0],[2 0]", "[3 0],[4 0],[2 0]", "[3 0],[4 0],[2 0]", }; const int requests[] = {0,4,1,4,2,4,3,4,2,4,0,4,1,4,2,4,3,4}; int i; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing CLOCK page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_CLOCK, NULL)); // reading some pages linearly with direct unpin and no modifications for(i = 0; i < 18; i++) { pinPage(bm, h, requests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i], bm, "check pool content"); } forceFlushPool(bm); ASSERT_EQUALS_POOL(poolContents[i],bm,"pool content after flush"); // check number of write IOs //0 writes because no dirty pages were present ASSERT_EQUALS_INT(0, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(9, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }
void testLFU() { // expected results const char *poolContents[] = { //Pin and Unpin 3 pages "[0 0],[-1 0],[-1 0]" , "[0 0],[1 0],[-1 0]", "[0 0],[1 0],[2 0]", //Pin the 0th page thrice,1st page twice "[0 3],[1 2],[2 0]", //Now pin a new page say 4. 4 should replace page 2 as page 2 has been Least Freq Used. "[0 3],[1 2],[4 1]", //Pin the 4th page thrice "[0 3],[1 2],[4 4]", //Now pin a new page 5. 5 should replace page 1 as page 1 has been Least Freq Used. "[0 3],[5 1],[4 4]", //Unpin page 0 thrice, page 5 once and page 4 four times. "[0 0],[5 0],[4 0]", }; const int requests[] = {0,1,2,3,4,5,6}; const int numLinRequests = 3; int i; BM_BufferPool *bm = MAKE_POOL(); BM_PageHandle *h = MAKE_PAGE_HANDLE(); testName = "Testing LFU page replacement"; CHECK(createPageFile("testbuffer.bin")); createDummyPages(bm, 100); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_LFU, NULL)); // reading some pages linearly with direct unpin and no modifications for(i = 0; i < numLinRequests; i++) { pinPage(bm, h, requests[i]); unpinPage(bm, h); ASSERT_EQUALS_POOL(poolContents[i], bm, "check pool content"); } pinPage(bm, h, 0); pinPage(bm, h, 0); pinPage(bm, h, 0); pinPage(bm, h, 1); pinPage(bm, h, 1); ASSERT_EQUALS_POOL(poolContents[i++],bm,"pool content after pin page"); pinPage(bm, h, 4); ASSERT_EQUALS_POOL(poolContents[i++],bm,"pool content after pin page"); pinPage(bm,h,4); pinPage(bm,h,4); pinPage(bm,h,4); ASSERT_EQUALS_POOL(poolContents[i++],bm,"pool content after pin page"); pinPage(bm,h,5); ASSERT_EQUALS_POOL(poolContents[i++],bm,"pool content after pin page"); h->data = "Page-0"; h->pageNum = 0; unpinPage(bm,h); unpinPage(bm,h); unpinPage(bm,h); h->data = "Page-5"; h->pageNum = 5; unpinPage(bm,h); h->data = "Page-4"; h->pageNum = 4; unpinPage(bm,h); unpinPage(bm,h); unpinPage(bm,h); unpinPage(bm,h); forceFlushPool(bm); ASSERT_EQUALS_POOL(poolContents[i],bm,"pool content after flush"); // check number of write IOs //0 writes because no dirty pages were present ASSERT_EQUALS_INT(0, getNumWriteIO(bm), "check number of write I/Os"); ASSERT_EQUALS_INT(5, getNumReadIO(bm), "check number of read I/Os"); CHECK(shutdownBufferPool(bm)); CHECK(destroyPageFile("testbuffer.bin")); free(bm); free(h); TEST_DONE(); }