// 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 checkDummyPages(BM_BufferPool *bm, int num) { int i; BM_PageHandle *h = MAKE_PAGE_HANDLE(); char *expected = malloc(sizeof(char) * 512); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); for (i = 0; i < num; i++) { CHECK(pinPage(bm, h, i)); sprintf(expected, "%s-%i", "Page", h->pageNum); ASSERT_EQUALS_STRING(expected, h->data, "reading back dummy page content"); CHECK(unpinPage(bm,h)); } CHECK(shutdownBufferPool(bm)); free(expected); free(h); }
void createDummyPages(BM_BufferPool *bm, int num) { int i; BM_PageHandle *h = MAKE_PAGE_HANDLE(); CHECK(initBufferPool(bm, "testbuffer.bin", 3, RS_FIFO, NULL)); for (i = 0; i < num; i++) { CHECK(pinPage(bm, h, i)); sprintf(h->data, "%s-%i", "Page", h->pageNum); CHECK(markDirty(bm, h)); CHECK(unpinPage(bm,h)); } CHECK(shutdownBufferPool(bm)); free(h); }
/************************************************************************************** * Function Name: initInfexManager * * Description: * Create an index manager with given buffer manager entry * * Parameters: * void * mgmtData: buffer manager entry * * Return: * RC: return code * * Author: * Xiaolang Wang <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------------- ------------------------ * 2015-04-27 Xiaolang Wang <*****@*****.**> Initialization. **************************************************************************************/ RC initIndexManager(void *mgmtData) { RC rc; // init BUffer Manager // init parameters for Buffer Manager BM = (BM_BufferPool *) malloc(sizeof(BM_BufferPool)); ReplacementStrategy strategy = RS_LRU; int numPages = 10; // Call initBufferPool() to init Buffer Manager (10, LRU) // Shutdown it in shutdownRrecordManager() rc = -99; rc = initBufferPool(BM, "", numPages, strategy, NULL); if (rc != RC_OK) { return rc; } // Allocate memory for global tree handle and scan handle BTREE_HANDLE = (BTreeHandle *) malloc(sizeof(BTreeHandle)); // SCAN_HANDLE = (BT_ScanHandle *) malloc(sizeof(BT_ScanHandle)); return RC_OK; }
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(); }
// 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(); }
recordTableInfo *initBufferManagerForRecDetails(char *name, struct BM_BufferPool *bManager, struct BM_PageHandle *pageHandle) { recordTableInfo *recordTable = NULL; initBufferPool(bManager, name, 3, RS_FIFO, NULL); if(pinPage(bManager, pageHandle, 0)==RC_OK) recordTable = TranslateStringRecordTabDetails(pageHandle->data); if (PAGE_SIZE > recordTable->sizeOfSchema) pinPage(bManager, pageHandle, 1); return recordTable; }
// 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(); }
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; }
void ucos_re_init(void) { int i,j; for (i=0;i<SYSCFG_UCOS_OBJECT_PRIO_NUM_LEVELS;i++) { ucos_msg_fifo_entry_t * f_entry; #ifndef SMALL_UCOS initBufferPool(); #endif ucos_msg_queue[i].empty = TRUE; f_entry = &ucos_msg_fifo[i][0]; ucos_msg_queue[i].next_in = ucos_msg_queue[i].next_out = f_entry; for(j=0;j<(SYSCFG_UCOS_MSGFIFO_SIZE-1);j++,f_entry++) { f_entry->next = &f_entry[1]; } f_entry->next = &ucos_msg_fifo[i][0]; } }
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(); }
ucos_rc_t ucos_init(void) { int i,j; #ifndef SMALL_UCOS initBufferPool(); #endif for (i=0; i<NR_UCOS_OBJECTS; i++) { object_info[i].name = NULL; object_info[i].ucos_msg_queue = &ucos_msg_queue[SYSCFG_UCOS_OBJECT_PRIO_NUM_LEVELS-1]; object_info[i].obj_entry = invalid_msg_destination; } for (i=0;i<SYSCFG_UCOS_OBJECT_PRIO_NUM_LEVELS;i++) { ucos_msg_fifo_entry_t * f_entry; ucos_msg_queue[i].empty = TRUE; f_entry = &ucos_msg_fifo[i][0]; ucos_msg_queue[i].next_in = ucos_msg_queue[i].next_out = f_entry; for(j=0;j<(SYSCFG_UCOS_MSGFIFO_SIZE-1);j++,f_entry++) { f_entry->next = &f_entry[1]; } f_entry->next = &ucos_msg_fifo[i][0]; } ucos_init_timer(); MEMSET(&ucos_statistics, 0x00, sizeof(ucos_statistics)); #ifdef POWER_MEASUREMENT idle_enabled = TRUE; #else idle_enabled = FALSE; #endif return UCOS_RC_OK; } /* End ucos_init */
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(); }
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(); }
//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(); }
RC openTable(RM_TableData *rel, char *name) { // Allocate table resources RM_TableMgmtData *tableMgmtData = (RM_TableMgmtData*)malloc(sizeof(RM_TableMgmtData)); rel->mgmtData = tableMgmtData; rel->name = (char *)malloc(strlen(name) + 1); strcpy(rel->name, name); // Setup buffer pool for table initBufferPool(&tableMgmtData->bufferPool, rel->name, 200, RS_LRU, NULL); // Read table from page RC pinPageResult; if ((pinPageResult = pinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle, 0)) != RC_OK) { return pinPageResult; } // Setup schema for table int numAttrs; int keySize; char *offset; offset = (char*)tableMgmtData->pageHandle.data; tableMgmtData->numTuples = *(int*)offset; offset += sizeof(int); tableMgmtData->nextFreeSlot = *(int*)offset; offset += sizeof(int); numAttrs = *(int*)offset; offset += sizeof(int); keySize = *(int*)offset; offset += sizeof(int); rel->schema = MAKE_SCHEMA(); rel->schema->numAttr = numAttrs; rel->schema->keySize = keySize; rel->schema->attrNames = MAKE_ATTRNAMES(numAttrs); rel->schema->dataTypes = MAKE_DATATYPES(numAttrs); rel->schema->typeLength = MAKE_TYPELENGTH(numAttrs); rel->schema->keyAttrs = MAKE_KEYATTRS(keySize); int i; for (i = 0; i < numAttrs; i++) { rel->schema->attrNames[i] = (char*)malloc(NAME_SIZE); } // Read and store schema in memory from page for (i = 0; i < rel->schema->numAttr; i++) { strncpy(rel->schema->attrNames[i], offset, NAME_SIZE); offset = offset + NAME_SIZE; rel->schema->dataTypes[i] = *(int*)offset; offset = offset + 4; rel->schema->typeLength[i] = *(int*)offset; offset = offset + 4; if (i < keySize) rel->schema->keyAttrs[i] = *(int*)offset; offset = offset + 4; } // Finished reading and dispose of page RC unpinPageResult; if (unpinPageResult = unpinPage(&tableMgmtData->bufferPool, &tableMgmtData->pageHandle) != RC_OK) { return unpinPageResult; } return RC_OK; }
// 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(); }