//Creating a table should create the underlying page file and store information about the schema, free-space, ... and so on in the Table Information pages RC createTable (char *name, Schema *schema){ createPageFile(name); SM_PageHandle ph; openPageFile(name, &fh); ensureCapacity(1, &fh); ph=schemaToString(schema); writeCurrentBlock(&fh,ph); calSlotSize(schema); calPageHeader(schema); closePageFile(&fh); return RC_OK; }
RC forcePage (BM_BufferPool *const bm, BM_PageHandle *const page) { SM_FileHandle fH; int code = openPageFile(bm->pageFile, &fH); if(code != RC_OK) return code; appendEmptyBlock(&fH); code = writeBlock(page->pageNum, &fH, page->data); if(code != RC_OK) return code; closePageFile(&fH); metaData.numWriteIO++; return RC_OK; }
//writing data and flushing pool RC forceFlushPool(BM_BufferPool *const bm) { sd = (Structure_Details *)bm->mgmtData; int i=0; while(i<buffpg_size) { if((sd[i].dirtyPage == 1) && (sd[i].fixedcount == 0)) // //checks all dirty pages (with fix count 0) { openPageFile (bm->pageFile, &fh); writeBlock (sd[i].pagenum, &fh, sd[i].data); // writing to disk from the buffer pool. sd[i].dirtyPage = 0; writeIO++; } i++; } return RC_OK; }
RC forceFlushPool(BM_BufferPool *const bm) { Data_Structure *ds = (Data_Structure *)bm->mgmtData; //printf("\nforceFlushPool"); int i; for(i=0;i<bufferSize;i++) { if(ds[i].dirtybit == 1 && ds[i].fixedcnt == 0) { SM_FileHandle fh; openPageFile (bm->pageFile, &fh); writeBlock (ds[i].pagenum, &fh, ds[i].data); ds[i].dirtybit = 0; writecnt++; } } return RC_OK; }
RC forcePage (BM_BufferPool *const bm, BM_PageHandle *const page) { Data_Structure *ds = (Data_Structure *)bm->mgmtData; //printf("\nforcePage"); int i; for(i=0;i<bufferSize;i++) { if(ds[i].pagenum == page->pageNum) { SM_FileHandle fh; openPageFile (bm->pageFile, &fh); writeBlock (ds[i].pagenum, &fh, ds[i].data); ds[i].dirtybit = 0; writecnt++; } } return RC_OK; }
// Buffer Manager Interface Pool Handling // *************************************** RC initBufferPool(BM_BufferPool *const bm, const char *const pageFileName, const int numPages, ReplacementStrategy strategy, void *stratData) { BM_Pool_MgmtData *mgmtData; int i; // Initialize Pool bm->pageFile= strdup(pageFileName); bm->numPages= numPages; bm->strategy= strategy; // Initialize Pool Mgmt Data mgmtData= MAKE_POOL_MGMTDATA(); mgmtData->io_reads= 0; mgmtData->io_writes= 0; mgmtData->stratData.fifoLastFreeFrame= -1; mgmtData->stratData.lru_head= NULL; mgmtData->stratData.lru_tail= NULL; mgmtData->stratData.clockCurrentFrame= -1; openPageFile(bm->pageFile, &mgmtData->fh); initPageTable(&mgmtData->pt_head); // Create Pool pages and initialize them mgmtData->pool = MAKE_BUFFER_POOL(numPages); for (i=0; i<numPages; i++) { mgmtData->pool[i].dirty= FALSE; mgmtData->pool[i].fixCount= 0; mgmtData->pool[i].pn= NO_PAGE; // Add all frames in LRU list // representing free frame to use. appendMRUFrame(&mgmtData->stratData, &mgmtData->pool[i]); mgmtData->pool[i].clockReplaceFlag= TRUE; } bm->mgmtData= mgmtData; // Initialize thread lock pthread_mutex_init(&mgmtData->bm_mutex, NULL); RETURN(RC_OK); }
RC initBufferPool(BM_BufferPool *const bm, const char *const pageFileName, const int numPages, ReplacementStrategy strategy, void *stratData) { // Initialize buffer pool bm->pageFile = (char *)malloc(strlen(pageFileName) + 1); strcpy(bm->pageFile, pageFileName); bm->numPages = numPages; bm->strategy = strategy; // Initialize management data for buffer pool BM_MgmtData *mgmtData; mgmtData = MAKE_MGMTDATA(); mgmtData->ioWrites = 0; mgmtData->ioReads = 0; mgmtData->head = NULL; // Open page file for buffer mgmt openPageFile(bm->pageFile, &mgmtData->fh); // Initialize frame pool mgmtData->framePool = MAKE_FRAME_POOL(numPages); int i; for (i = 0; i < numPages; i++) { mgmtData->framePool[i].frameID = i; mgmtData->framePool[i].isDirty = FALSE; mgmtData->framePool[i].fixCount = 0; mgmtData->framePool[i].pageNum = NO_PAGE; mgmtData->framePool[i].memPage = (SM_PageHandle)malloc(PAGE_SIZE); } // For LRU and FIFO BM_Node *head = newNode(&mgmtData->framePool[0]); BM_Frame *frame = NULL; for(i = 1; i < bm->numPages; i++){ frame = &mgmtData->framePool[i]; insertAtHead(&head, frame); } mgmtData->head = head; bm->mgmtData = mgmtData; return RC_OK; }
/* Try to create, open, and close a page file */ void testSinglePageContent(void) { SM_FileHandle fh; SM_PageHandle ph; int i; testName = "test single page content"; ph = (SM_PageHandle) malloc(PAGE_SIZE); // create a new page file TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); printf("created and opened file\n"); // read first page into handle TEST_CHECK(readFirstBlock (&fh, ph)); // the page should be empty (zero bytes) for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page"); printf("first block was empty\n"); // change ph to be a string and write that one to disk for (i=0; i < PAGE_SIZE; i++) ph[i] = (i % 10) + '0'; TEST_CHECK(writeBlock (0, &fh, ph)); printf("writing first block\n"); // read back the page containing the string and check that it is correct TEST_CHECK(readFirstBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); printf("reading first block\n"); // destroy new page file TEST_CHECK(destroyPageFile (TESTPF)); free(ph); ph=NULL; TEST_DONE(); }
/* Name: InitBufferPool * Behavior:Would initialize a new buffer pool and if buffer pool exists , it share with new pool handler * Version: 1.0.0 */ RC initBufferPool(BM_BufferPool *const bm, const char *const pageFileName,const int numPages, ReplacementStrategy strategy,void *stratData) { RC ret=RC_OK; Buffer_page_Dtl *bf_pg_dtl; BufferPool_Node *_buffernode; BM_BufferPool *tempPool; SM_FileHandle *sh; // pthread_mutex_lock(&work_mutex_init); //1st Incoming thread hold a lock. _buffernode=checkActiveBufferPools(BP_StNode_ptr,pageFileName); if(_buffernode==NULL) { sh=(SM_FileHandle *)malloc(sizeof(SM_FileHandle)); if(sh==NULL) { return RC_FILE_HANDLE_NOT_INIT; } openPageFile(pageFileName,sh); bm->pageFile=pageFileName; bm->numPages=numPages; bm->strategy=strategy; bm->mgmtData=sh; bf_pg_dtl=initializebufferdetails(numPages); ret=bf_pg_dtl!=NULL?RC_OK:RC_FILE_HANDLE_NOT_INIT; if(insert_node(&BP_StNode_ptr,bm,bf_pg_dtl)==FALSE) ret=RC_FILE_HANDLE_NOT_INIT; } else { tempPool=_buffernode->buffer_pool_ptr; bm->pageFile=pageFileName; bm->numPages=numPages; bm->strategy=strategy; bm->mgmtData=tempPool->mgmtData; bf_pg_dtl=_buffernode->buffer_page_dtl; if(insert_node(&BP_StNode_ptr,bm,bf_pg_dtl)==FALSE) ret=RC_FILE_HANDLE_NOT_INIT; } // pthread_mutex_unlock(&work_mutex_init);//1st Incoming thread release a lock. return ret; }
RC forcePage (BM_BufferPool *const bm, BM_PageHandle *const page) { //current frame2file buffer *bf = bm->mgmtData; SM_FileHandle fHandle; RC rt_value; rt_value = openPageFile(bm->pageFile, &fHandle); if (rt_value!=RC_OK) return RC_FILE_NOT_FOUND; rt_value = writeBlock(page->pageNum, &fHandle, page->data); if (rt_value!=RC_OK) { closePageFile(&fHandle); return RC_FILE_NOT_FOUND; } bf->numWrite++; closePageFile(&fHandle); return RC_OK; }
//called at the time of replacement of pages in page frame RC updatePage(BM_BufferPool *const bm,BM_PageHandle *const page,pageFrame *node,const PageNumber pageNum){ bufferPoolInfo *mgmtInfo = getMgmtInfo(bm); RC flag; SM_FileHandle fileHandle; if(bm!=NULL){ if ((flag = openPageFile ((char *)(bm->pageFile), &fileHandle)) == RC_OK){ //if page to be replaced is dirty then write it back to disk before replacement if(node->dirtyBit){ ensureCapacity(pageNum, &fileHandle); if((flag = writeBlock(node->pageNumber,&fileHandle, node->data)) == RC_OK){ (mgmtInfo->numWriteIO)+=1; }else{ return flag; } } //ensuing capacity of file before reading the page from file ensureCapacity(pageNum, &fileHandle); //reading the pageNum from file to data field. if((flag = readBlock(pageNum, &fileHandle, node->data)) == RC_OK){ (mgmtInfo->pagesToPageFrame)[node->pageNumber] = NO_PAGE; node->pageNumber = pageNum; (mgmtInfo->pagesToPageFrame)[node->pageNumber] = node->pageFrameNo; (mgmtInfo->pageFramesToPage)[node->pageFrameNo] = node->pageNumber; node->dirtyBit = false; node->fixedCount = 1; page->pageNum = pageNum; page->data = node->data; mgmtInfo->numReadIO+=1; }else{ return flag; } return RC_OK; }else{ return flag; } }else{ RC_message="Buffer is not initialized "; return RC_BUFFER_NOT_INITIALIZED; } }
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; }
void LRU(BM_BufferPool *const bm, Structure_Details *node) { sd=(Structure_Details *) bm->mgmtData; int i=0; int prev; int minimum; while(i<buffpg_size) { if(sd[i].fixedcount == 0) { prev= i; minimum = sd[i].freq_used; break; } i++; } i=prev+1; while(i<buffpg_size) { if(sd[i].freq_used < minimum) { prev = i; minimum = sd[i].freq_used; } i++; } if(sd[prev].dirtyPage == 1) // checks if dirty page present and writes it to disk { openPageFile (bm->pageFile, &fh); writeBlock (sd[prev].pagenum, &fh, sd[prev].data); writeIO++; } sd[prev].data = node->data; sd[prev].pagenum = node->pagenum; sd[prev].dirtyPage = node->dirtyPage; sd[prev].fixedcount = node->fixedcount; sd[prev].freq_used = node->freq_used; }
/* Try to create, open, and close a page file */ void testWrite(void) { SM_FileHandle fh; SM_PageHandle ph; int i; testName = "test single page content"; ph = (SM_PageHandle) malloc(PAGE_SIZE); // create a new page file TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); printf("created and opened file\n"); TEST_CHECK(ensureCapacity(5,&fh)); for (i=0; i < PAGE_SIZE; i++) ph[i] = (i % 10) + '0'; ASSERT_TRUE((fh.totalNumPages == 5), "expect 5 pages in new file"); TEST_CHECK(writeBlock (5, &fh, ph)); // read back the page containing the string and check that it is correct TEST_CHECK(readBlock (5,&fh, ph)); printf("\nreading :"); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // destroy new page file TEST_CHECK(destroyPageFile (TESTPF)); TEST_DONE(); }
RC forceFlushPool (BM_BufferPool *const bm) { int i = 0; resetPages(); SM_FileHandle fh; RC code = openPageFile(bm->pageFile, &fh); if (code != RC_OK) return code; for(i = 0; i < bm->numPages; i++){ if (pages->isMark && pages->pageNum > -1){ pages->isMark = false; } if(i < bm->numPages-1){ pages = pages->nextPage; } } resetPages(); closePageFile(&fh); return RC_OK; }
void lru(BM_BufferPool *const bm, Data_Structure *newnode) { //printf("\nInside lru function"); Data_Structure *ds=(Data_Structure *) bm->mgmtData; int i,front, min; for(i=0;i<bufferSize;i++) { if(ds[i].fixedcnt == 0) { front= i; min = ds[i].hitnum; break; } } for(i=front+1;i<bufferSize;i++) { if(ds[i].hitnum < min) { front = i; min = ds[i].hitnum; } } if(ds[front].dirtybit == 1) { SM_FileHandle fh; openPageFile (bm->pageFile, &fh); writeBlock (ds[front].pagenum, &fh, ds[front].data); writecnt++; } ds[front].data = newnode->data; ds[front].pagenum = newnode->pagenum; ds[front].dirtybit = newnode->dirtybit; ds[front].fixedcnt = newnode->fixedcnt; ds[front].hitnum = newnode->hitnum; }
RC createBtree (char *idxId, DataType keyType, int n){ SM_FileHandle *fHandle = (SM_FileHandle *)calloc(1, sizeof(SM_FileHandle)); char *metadata = (char *)calloc(1, PAGE_SIZE); int rootPage; int nodeNum; int entryNum; createPageFile(idxId); openPageFile(idxId, fHandle); ensureCapacity(1, fHandle); rootPage = -1; nodeNum = 0; entryNum = 0; /* * root page number * the number of node * the number of entry * n * key type */ memcpy(metadata, &rootPage, sizeof(int)); memcpy(metadata + sizeof(int), &nodeNum, sizeof(int)); memcpy(metadata + 2*sizeof(int), &entryNum, sizeof(int)); memcpy(metadata + 3*sizeof(int), &n, sizeof(int)); memcpy(metadata + 4*sizeof(int), &keyType, sizeof(DataType)); writeBlock(0, fHandle, metadata); free(fHandle); free(metadata); return RC_OK; }
stasis_page_handle_t* stasis_page_handle_deprecated_factory(stasis_log_t *log, stasis_dirty_page_table_t *dpt) { printf("\nWarning: Using old I/O routines (with known bugs).\n"); return openPageFile(log, dpt); }
/* Try to create, open, and close a multi-page file */ void testMultiPageContent(void) { SM_FileHandle fh; SM_PageHandle ph; int i; testName = "test multi-page content"; ph = (SM_PageHandle) malloc(PAGE_SIZE); // create a new page file TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); printf("created and opened file\n"); //ensure the capacity of the file with 4 pages TEST_CHECK(ensureCapacity(4,&fh)); // read the current page into handle TEST_CHECK(readCurrentBlock(&fh, ph)); // the page should be empty (zero bytes) for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in current page of freshly initialized page"); printf("current block was empty with the page number =%d\n", getBlockPos(&fh)); // read the next page into handle TEST_CHECK(readNextBlock(&fh, ph)); // the page should be empty (zero bytes) for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in next page of freshly initialized page"); printf("the next block was empty\n"); printf("the updated page number is =%d\n",getBlockPos(&fh)); // change ph to be a string and write that one to disk for (i=0; i < PAGE_SIZE; i++) ph[i] = (i % 10) + '0'; TEST_CHECK(writeCurrentBlock(&fh, ph)); printf("writing current block with the page number =%d\n", getBlockPos(&fh)); // read back the page containing the string and check that it is correct TEST_CHECK(readCurrentBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); printf("reading back current block into memory with page number =%d\n", getBlockPos(&fh)); // read the last page into handle TEST_CHECK(readLastBlock(&fh, ph)); // the page should be empty (zero bytes) for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in last page of freshly initialized page"); printf("last block was empty with the page number =%d\n", getBlockPos(&fh)); // change ph to be a string and write that one to disk for (i=0; i < PAGE_SIZE; i++) ph[i] = (i % 10) + '0'; TEST_CHECK(writeCurrentBlock(&fh, ph)); printf("writing current block with the page number =%d\n", getBlockPos(&fh)); // read back the page containing the string and check that it is correct TEST_CHECK(readCurrentBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); printf("reading back current block into memory with page number =%d\n", getBlockPos(&fh)); // destroy new page file TEST_CHECK(destroyPageFile (TESTPF)); TEST_DONE(); }
RC pinPage (BM_BufferPool *const bm, BM_PageHandle *const page, const PageNumber pageNum) { int i; resetPages(); int spotFound = -1; for(i = 0; i < bm->numPages; i++){ if(pages->pageNum == -1){ spotFound = i; break; } if(pages->pageNum == pageNum){ spotFound = i; break; } if(i < bm->numPages-1){ pages = pages->nextPage; } } int min = 999999; if (spotFound == -1) { resetPages(); for (i = 0; i < bm->numPages; i++) { if (pages->fixCount == 0 && pages->repStrat < min) { min = pages->repStrat; spotFound = i; } if(i < bm->numPages-1){ pages = pages->nextPage; } } } resetPages(); for(i = 0; i < bm->numPages; i++){ if(i == spotFound) break; if(i < bm->numPages-1){ pages = pages->nextPage; } } SM_FileHandle fH; openPageFile(bm->pageFile, &fH); if(pages->pageNum == pageNum){ if(bm->strategy == RS_LRU) pages->repStrat = ++(metaData.totalRepStrat); pages->fixCount++; page->pageNum = pageNum; strcpy(page->data, pages->pageData); }else { page->data = malloc(PAGE_SIZE); page->pageNum = pageNum; readBlock(pageNum, &fH, page->data); metaData.numReadIO++; pages->pageNum = pageNum; pages->fixCount = 1; pages->repStrat = ++(metaData.totalRepStrat); pages->isMark = false; } closePageFile(&fH); return RC_OK; }
//pinPage RC pinPage (BM_BufferPool *const bm, BM_PageHandle *const page, const PageNumber pageNum) { sd = (Structure_Details *)bm->mgmtData; if(sd[0].pagenum == -1) { openPageFile (bm->pageFile, &fh); sd[0].data = (SM_PageHandle) malloc(PAGE_SIZE); ensureCapacity(pageNum,&fh); readBlock(pageNum, &fh, sd[0].data); sd[0].pagenum = pageNum; sd[0].fixedcount++; n = 0; strike = 0; sd[0].freq_used = strike; sd[0].nr = 0; page->pageNum = pageNum; page->data = sd[0].data; return RC_OK; } else { int i=0; int buffer_check = 0; while(i<buffpg_size) { if(sd[i].pagenum != -1) { if(sd[i].pagenum == pageNum) { sd[i].fixedcount++; buffer_check = 1; strike++; if(bm->strategy == RS_LRU) sd[i].freq_used = strike; page->pageNum = pageNum; page->data = sd[i].data; break; } } else { openPageFile (bm->pageFile, &fh); sd[i].data = (SM_PageHandle) malloc(PAGE_SIZE); readBlock(pageNum, &fh, sd[i].data); sd[i].pagenum = pageNum; sd[i].fixedcount = 1; sd[i].nr = 0; n++; strike++; if(bm->strategy == RS_LRU) sd[i].freq_used = strike; page->pageNum = pageNum; page->data = sd[i].data; buffer_check = 1; break; } i++; } if(buffer_check == 0) { pin = (Structure_Details *)malloc(sizeof(Structure_Details)); openPageFile (bm->pageFile, &fh); pin->data = (SM_PageHandle) malloc(PAGE_SIZE); readBlock(pageNum, &fh, pin->data); pin->pagenum = pageNum; pin->dirtyPage = 0; pin->fixedcount = 1; pin->nr = 0; n++; strike++; if(bm->strategy == RS_LRU ) pin->freq_used = strike; page->pageNum = pageNum; page->data = pin->data; if(bm->strategy == RS_FIFO) { FIFO(bm,pin); } else if (bm->strategy == RS_LRU) { LRU(bm,pin); } else { return RC_ALGORITHM_NOT_IMPLEMENTED; } } return RC_OK; } }
/************************************************************************************** * Function Name: appendPage * * Description: * Read the requested page from the disk and append it to the tail of the PageList * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization * 2015-03-26 Xin Su <*****@*****.**> Add thread read-write lock **************************************************************************************/ RC appendPage(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { PageList *queue = (PageList *) bm->mgmtData; RC rc; // init return code // Require lock pthread_rwlock_init(&rwlock, NULL); pthread_rwlock_wrlock(&rwlock); // Open File rc = -99; rc = openPageFile(bm->pageFile, F_HANDLE); if (rc != RC_OK) { return rc; } // if the size of the PageList = 0, then the PageList is empty, add this requested page as the head // else, the PageList is neither empty nor full, add the requested page to next of the tail of the PageList if (queue->size == 0) { queue->head->fixCount = 1; queue->head->numWriteIO = 1; // if the page does not exist, then call ensureCapacity to add the requested page to the file if (F_HANDLE->totalNumPages < pageNum + 1) { int totalPages = F_HANDLE->totalNumPages; rc = -99; rc = ensureCapacity(pageNum + 1, F_HANDLE); NUM_WRITE_IOS += pageNum + 1 - totalPages; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } } queue->head->numWriteIO = 0; // After ensureCapacity, now we can read the requested page from the file queue->head->numReadIO++; rc = -99; rc = readBlock(pageNum, F_HANDLE, queue->head->page->data); NUM_READ_IOS++; queue->head->numReadIO--; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } // Now the fixCount = 1, the numReadIO = 0, and the numWriteIO = 0 queue->head->page->pageNum = pageNum; queue->head->dirtyFlag = FALSE; queue->head->clockFlag = FALSE; // Now there is only 1 page in the PageList, and all pointers , including the current pointer, are pointing to it } else { queue->tail->next->fixCount = 1; queue->tail->next->numWriteIO = 1; // if the page does not exist, then call ensureCapacity to add the requested page to the file if (F_HANDLE->totalNumPages < pageNum + 1) { int totalPages = F_HANDLE->totalNumPages; rc = -99; rc = ensureCapacity(pageNum + 1, F_HANDLE); NUM_WRITE_IOS += pageNum + 1 - totalPages; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } } queue->tail->next->numWriteIO = 0; // After ensureCapacity, now we can read the requested page from the file queue->tail->next->numReadIO++; rc = -99; rc = readBlock(pageNum, F_HANDLE, queue->tail->next->page->data); NUM_READ_IOS++; queue->tail->next->numReadIO--; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } // Now the fixCount = 1, the numReadIO = 0, and the numWriteIO = 0 queue->tail->next->page->pageNum = pageNum; queue->tail->next->dirtyFlag = FALSE; queue->tail->next->clockFlag = FALSE; queue->tail = queue->tail->next; // Set the current pointer to the requested page, that is the tail of the PageList queue->current = queue->tail; } // After appending the requested page, Increment the size of the PageList queue->size++; // Load the requested page into BM_PageHandle page->data = queue->current->page->data; page->pageNum = queue->current->page->pageNum; // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return RC_OK; } // appendPage
/**************************************************************** * Function Name: myTestAssign1 * * Description: Additional tests for Storage Manager. * * Parameter: void * * Return: void * * Author: Dhruvit Modi ([email protected]) * Monika Priyadarshani ([email protected]) ****************************************************************/ void myTestAssign1(void) { SM_FileHandle fh; SM_PageHandle ph; int i; ph = (SM_PageHandle) malloc(PAGE_SIZE); // create a new page file TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); printf("created and opened file\n"); for (i=0; i < PAGE_SIZE; i++) ph[i] = (i % 10) + '0'; // write on the first block TEST_CHECK(writeCurrentBlock (&fh, ph)); printf("writing first block\n"); // append empty block TEST_CHECK(appendEmptyBlock(&fh)); printf("append Empty block\n"); // write on the second block TEST_CHECK(writeBlock (1, &fh, ph)); printf("writing second block\n"); TEST_CHECK(appendEmptyBlock(&fh)); printf("append Empty block\n"); // write to the third block TEST_CHECK(writeBlock (2, &fh, ph)); printf("writing third block\n"); // read back the page containing the string and check that it is correct printf("reading first block\n"); TEST_CHECK(readFirstBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // read back the page containing the string and check that it is correct printf("reading last block\n"); TEST_CHECK(readLastBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // read back the page containing the string and check that it is correct printf("reading previous block\n"); TEST_CHECK(readPreviousBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // read back the page containing the string and check that it is correct printf("reading current block\n"); TEST_CHECK(readCurrentBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // read back the page containing the string and check that it is correct printf("reading next block\n"); TEST_CHECK(readNextBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected."); // append empty block TEST_CHECK(appendEmptyBlock(&fh)); printf("append Empty block\n"); // ensure capacity TEST_CHECK(ensureCapacity(6, &fh)); printf("ensure capacity\n"); // destroy new page file TEST_CHECK(destroyPageFile (TESTPF)); TEST_DONE(); }
/************************************************************************************** * Function Name: forcePage * * Description: * Write the requested page back to the page file on disk * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * * Return: * RC: return code * * Author: * Jie Zhou <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ---------------------------- * 2015-03-13 Jie Zhou <*****@*****.**> Initialization * 2015-03-20 Xin Su <*****@*****.**> Modify the logic of forcing to write the requested page back * Add comments **************************************************************************************/ RC forcePage(BM_BufferPool * const bm, BM_PageHandle * const page) { PageList *queue = (PageList *) bm->mgmtData; RC rc = -99; // Require lock pthread_rwlock_init(&rwlock, NULL); pthread_rwlock_wrlock(&rwlock); // Open file rc = -99; rc = openPageFile(bm->pageFile, F_HANDLE); if (rc != RC_OK) { return rc; } // First set numWriteIO queue->current->numWriteIO = 1; // Write the requested page back to the disk rc = -99; rc = writeBlock(page->pageNum, F_HANDLE, page->data); NUM_WRITE_IOS++; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release unlock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } // Set the page back to clean queue->current->dirtyFlag = FALSE; // The write completes without error, then set numWriteIO back queue->current->numWriteIO = 0; // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return RC_OK; } // forcePage
//adding one to the fix for the pin page in the buffer pool //And adding one to each time of mgmtDataLRU in the buffer pool RC LRU_pinPage(BM_BufferPool *const bm, BM_PageHandle *const page, PageNumber pageNum){ //printf("pin: %d\n", pageNum); int i; int ind = LRU_findByPageNumber(bm, pageNum); //get the system time at pinPage; clock_t c = clock(); mgmtDataLRU * nodes = (mgmtDataLRU *)bm->mgmtData; RC _rc; SM_FileHandle fHandle; //if the page is in buffer, return the pagehandle if (ind >= 0){ page->pageNum = pageNum; page->data = nodes[ind].pagehandle->data; nodes[ind].time = c; nodes[ind].fix++; //printf("page found in buffer: %d\n", ind); return RC_OK; } //if there are free page in the buffer for(i=0; i<bm->numPages; i++){ if ( nodes[i].pagehandle->pageNum == NO_PAGE){ //printf("%dth page is free\n", i); nodes[i].pagehandle->pageNum = pageNum; free(nodes[i].pagehandle->data); nodes[i].pagehandle->data = (char *)calloc(1, PAGE_SIZE); _rc = openPageFile(bm->pageFile, &fHandle); if(_rc != RC_OK){ return _rc; } _rc = readBlock(pageNum, &fHandle, nodes[i].pagehandle->data); closePageFile(&fHandle); if(_rc == RC_OK){ //printf("page # %d is in disk\n", pageNum); bm->numOfRead++; } nodes[i].fix++; nodes[i].time = c; nodes[i].dirty = false; page->pageNum = pageNum; page->data = nodes[i].pagehandle->data; //printf("pinpage succeed, %dth page become page# %d\n", i, page->pageNum); return RC_OK; } } //if all buffers have data i = LRU_findTheEariestUnfixedNode(bm); if (i == -1){ //all buffers are full and occupied return RC_BM_ALL_PAGE_PINNED; } else{ //write the content to disk if(nodes[i].dirty){ _rc = forcePage(bm,nodes[i].pagehandle); //bm->numOfWrite++; } nodes[i].pagehandle->pageNum = pageNum; free(nodes[i].pagehandle->data); nodes[i].pagehandle->data = (char *)calloc(1, PAGE_SIZE); _rc = openPageFile(bm->pageFile, &fHandle); if(_rc != RC_OK){ return _rc; } _rc = readBlock(pageNum, &fHandle, nodes[i].pagehandle->data); closePageFile(&fHandle); if(_rc == RC_OK){ bm->numOfRead++; } nodes[i].fix++; nodes[i].time = c; nodes[i].dirty = false; // nodes[i].time = (double)seconds; page->pageNum = pageNum; page->data = nodes[i].pagehandle->data; return RC_OK; } }
/************************************************************************************** * Function Name: replacePage * * Description: * Replace the current page with the requested page read from the disk * * Parameters: * BM_BufferPool * const bm: Buffer Pool Handler * BM_PageHandle * const page: Buffer Page Handler * PageNumber pageNum: the page number of the requested page * * Return: * RC: return code * * Author: * Xin Su <*****@*****.**> * * History: * Date Name Content * ---------- ---------------------------------- ------------------------ * 2015-03-15 Xin Su <*****@*****.**> Initialization * 2015-03-26 Xin Su <*****@*****.**> Add thread read-write lock **************************************************************************************/ RC replacePage(BM_BufferPool * const bm, BM_PageHandle * const page, PageNumber pageNum) { PageList *queue = (PageList *) bm->mgmtData; RC rc; // init return code // Require lock pthread_rwlock_init(&rwlock, NULL); pthread_rwlock_wrlock(&rwlock); // Open file rc = -99; rc = openPageFile(bm->pageFile, F_HANDLE); if (rc != RC_OK) { return rc; } // If the removable page is dirty, then write it back to the disk before remove it. // Now the fixCount = 0, and the numReadIO = 0 and the numWriteIO = 0 queue->current->fixCount = 1; queue->current->numWriteIO = 1; // if the removable page is dirty, then write it back to the file if (queue->current->dirtyFlag == TRUE) { rc = -99; rc = writeBlock(queue->current->page->pageNum, F_HANDLE, queue->current->page->data); NUM_WRITE_IOS++; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release unlock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } // After writeBlock, set the PageFrame back to clean queue->current->dirtyFlag = FALSE; } // if the page does not exist, then call ensureCapacity to add the requested page to the file if (F_HANDLE->totalNumPages < pageNum + 1) { int totalPages = F_HANDLE->totalNumPages; rc = -99; rc = ensureCapacity(pageNum + 1, F_HANDLE); NUM_WRITE_IOS += pageNum + 1 - totalPages; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release unlock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } } queue->current->numWriteIO = 0; // After ensureCapacity, now we can read the requested page from the file queue->current->numReadIO++; rc = -99; rc = readBlock(pageNum, F_HANDLE, queue->current->page->data); NUM_READ_IOS++; queue->current->numReadIO--; if (rc != RC_OK) { // Do not change fixCount and NumWriteIO back, for this indicates write IO error and need more info to proceed // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return rc; } // Load the requested page to the current PageFrame in the BM_BufferPool // Now the fixCount = 1, the numReadIO = 0, and the numWriteIO = 0 queue->current->page->pageNum = pageNum; queue->current->clockFlag = FALSE; // Load the requested into BM_PageHandle page->data = queue->current->page->data; page->pageNum = queue->current->page->pageNum; // Close file rc = -99; rc = closePageFile(F_HANDLE); if (rc != RC_OK) { return rc; } // Release lock pthread_rwlock_unlock(&rwlock); pthread_rwlock_destroy(&rwlock); return RC_OK; } // replacePage
RC pinPage (BM_BufferPool *const bm, BM_PageHandle *const page, const PageNumber pageNum) { Data_Structure *ds = (Data_Structure *)bm->mgmtData; if(ds[0].pagenum == -1) { //printf("\nINSIDE ds[0]->pagenum == -1\n"); SM_FileHandle fh; openPageFile (bm->pageFile, &fh); ds[0].data = (SM_PageHandle) malloc(PAGE_SIZE); ensureCapacity(pageNum,&fh); readBlock(pageNum, &fh, ds[0].data); ds[0].pagenum = pageNum; ds[0].fixedcnt++; rear = 0; hit = 0; ds[0].hitnum = hit; ds[0].numRef = 0; page->pageNum = pageNum; page->data = ds[0].data; /* printf("\nPinPage function buffer"); int i; for(i=0;i<bufferSize; i++) { printf("\nPagenum: %d fixedcnt: %d dirty: %d",ds[i].pagenum,ds[i].fixedcnt,ds[i].dirtybit); }*/ return RC_OK; } else { //printf("\nINSIDE front != NULL\n"); int i,check = 0; for(i=0;i<bufferSize;i++) { if(ds[i].pagenum != -1) { if(ds[i].pagenum == pageNum) //if Page already in memory { ds[i].fixedcnt++; check = 1; hit++; if(bm->strategy == RS_LRU) ds[i].hitnum = hit; else if(bm->strategy == RS_CLOCK) //if bm-> strategy is RS_CLOCK storing the USED bit in hitnum. ds[i].hitnum = 1; else if(bm->strategy == RS_LFU) { ds[i].numRef++; //printf("Page %d referenced again \n", pageNum); //rear = rear + 2; //printf(" rear : %d \n", rear); } page->pageNum = pageNum; page->data = ds[i].data; clockptr++; break; } } else //Condition when the buffer has space to add a page { SM_FileHandle fh; openPageFile (bm->pageFile, &fh); ds[i].data = (SM_PageHandle) malloc(PAGE_SIZE); readBlock(pageNum, &fh, ds[i].data); ds[i].pagenum = pageNum; ds[i].fixedcnt = 1; ds[i].numRef = 0; rear++; hit++; if(bm->strategy == RS_LRU) ds[i].hitnum = hit; else if(bm->strategy == RS_CLOCK) //if bm-> strategy is RS_CLOCK storing the USED bit in hitnum. ds[i].hitnum = 1; page->pageNum = pageNum; page->data = ds[i].data; check = 1; break; } }//end of for if(check == 0)//Condition when the buffer is full and we need to use a replacement strategy. { Data_Structure *temp = (Data_Structure *)malloc(sizeof(Data_Structure)); SM_FileHandle fh; openPageFile (bm->pageFile, &fh); temp->data = (SM_PageHandle) malloc(PAGE_SIZE); readBlock(pageNum, &fh, temp->data); temp->pagenum = pageNum; temp->dirtybit = 0; temp->fixedcnt = 1; temp->numRef = 0; rear++; hit++; //printf("HIT : %d \n", hit); //test by Rakesh if(bm->strategy == RS_LRU ) temp->hitnum = hit; else if(bm->strategy == RS_CLOCK) //if bm-> strategy is RS_CLOCK storing the USED bit in hitnum. temp->hitnum = 1; page->pageNum = pageNum; page->data = temp->data; switch(bm->strategy) { case RS_FIFO: //printf("\n Inside FIFO switch."); fifo(bm,temp); break; case RS_LRU: //printf("\n Inside LRU switch."); lru(bm,temp); break; case RS_CLOCK: //printf("\n Inside CLOCK switch"); clock(bm,temp); break; case RS_LFU: //printf("\n Inside LFU switch"); LFU(bm,temp); break; case RS_LRU_K: printf("\n Inside LRU_K switch"); break; default: printf("\nAlgorithm Not Implemented\n"); break; }//end of switch }//end of if(check = 0) /* printf("\nPinPage function buffer"); for(i=0;i<bufferSize;i++) printf("\nPagenum: %d fixedcnt: %d dirty: %d",ds[i].pagenum,ds[i].fixedcnt,ds[i].dirtybit); */ return RC_OK; }//end of else }
void testReadWrite(void) { SM_FileHandle fh; SM_PageHandle ph; int i; ph = (SM_PageHandle) malloc(PAGE_SIZE); testName = "test read and write methods"; TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); ASSERT_TRUE(strcmp(fh.fileName, TESTPF) == 0, "filename correct"); ASSERT_TRUE((fh.totalNumPages == 1), "expect 1 page in new file"); ASSERT_TRUE((fh.curPagePos == 0), "freshly opened file's page position should be 0"); //Writes A, B, C, D, E, F, G, H from 0th page to 7th page for(i = 0; i < 8; i ++) { memset(ph, 'A' + i, PAGE_SIZE); TEST_CHECK(writeBlock (i, &fh, ph)); printf("writing %d th block\n", fh.curPagePos); } // read first page into handle i.e. A TEST_CHECK(readFirstBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 'A'), "expected A"); printf("first block contains A\n"); // read last page into handle i.e. H TEST_CHECK(readLastBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 'H'), "expected H"); printf("last block contains H\n"); // read first page into handle i.e. A readFirstBlock (&fh, ph); // read next page into handle i.e. B TEST_CHECK(readNextBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 'B'), "expected B"); printf("block contains B\n"); readNextBlock (&fh, ph); //C readNextBlock (&fh, ph); //D // read previous page into handle i.e. C TEST_CHECK(readPreviousBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 'C'), "expected C"); printf("block contains C\n"); readNextBlock (&fh, ph); //D readNextBlock (&fh, ph); //E // read current page into handle i.e. E TEST_CHECK(readCurrentBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 'E'), "expected E"); printf("block contains E\n"); readPreviousBlock (&fh, ph); //D //Replace D with Z memset(ph, 'Z', PAGE_SIZE); TEST_CHECK(writeCurrentBlock (&fh, ph)); printf("writing D with Z\n"); // read current page into handle i.e. Z TEST_CHECK(readCurrentBlock (&fh, ph)); for (i=0; i < PAGE_SIZE; i++){ ASSERT_TRUE((ph[i] == 'Z'), "expected Z"); } printf("block contains Z\n"); TEST_CHECK(closePageFile (&fh)); TEST_CHECK(destroyPageFile (TESTPF)); free(ph); TEST_DONE(); }
void testAppendEnsureCapMetaData() { SM_FileHandle fh; SM_PageHandle ph; ph = (SM_PageHandle) malloc(PAGE_SIZE); TEST_CHECK(createPageFile (TESTPF)); TEST_CHECK(openPageFile (TESTPF, &fh)); //Append an empty block to the file. appendEmptyBlock(&fh); //Check whether the appended block has only 4096 '\0' in the currentBlock. readBlock(getBlockPos(&fh),&fh,ph); int i; for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page"); printf("Appended Block was empty\n"); //Page File should contain only 2 blocks.first block during createPage and second during appendBlock ASSERT_TRUE((fh.totalNumPages == 2), "Number of Blocks : 2"); //Current Block postion should be 1 ASSERT_TRUE((fh.curPagePos == 1), "Current Page Position is 1"); //add 3 more blocks to the Page File. ensureCapacity(5,&fh); //Verify whether the freshly added 3 blocks are of '\0' characters //[START] readBlock(2,&fh,ph); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page"); readBlock(3,&fh,ph); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page"); readBlock(4,&fh,ph); for (i=0; i < PAGE_SIZE; i++) ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page"); printf("Freshly appended 3 blocks are empty\n"); //[END] //Page File should contain only 5 blocks, as we have called ensureCapacity(5) ASSERT_TRUE((fh.totalNumPages == 5), "Number of Blocks : 5"); //Current Block postion should be 4 ASSERT_TRUE((fh.curPagePos == 4), "Current Page Position is 4"); //Store the metaData into the file and close the pagefile. int totalNoOfPages = fh.totalNumPages; char fileName[100]; memset(fileName,'\0',100); strcpy(fileName,fh.fileName); char metaDataFromFile[100]; memset(metaDataFromFile,'\0',100); closePageFile(&fh); //Verify whether the written MetaData is correct or not //[START] char metaDataToBeVerified[100]; memset(metaDataToBeVerified,'\0',100); char returnData[100]; memset(returnData,'\0',100); metaDataToBeVerified[0]= 'P';metaDataToBeVerified[1]= 'S';metaDataToBeVerified[2]= ':';metaDataToBeVerified[3]= '\0'; getString(PAGE_SIZE,returnData); strcat(metaDataToBeVerified,returnData); strcat(metaDataToBeVerified,";"); memset(returnData,'\0',100); strcat(metaDataToBeVerified,"NP:"); getString(totalNoOfPages,returnData); strcat(metaDataToBeVerified,returnData); strcat(metaDataToBeVerified,";"); readMetaDataFromFile(fileName,metaDataFromFile); ASSERT_TRUE((strcmp(metaDataToBeVerified, metaDataFromFile) == 0), "MetaData read from file is correct"); printf("Read Meta Data from file is :: %s\n",metaDataToBeVerified); //[END] TEST_CHECK(destroyPageFile(TESTPF)); free(ph); TEST_DONE(); }
RC initBufferPool(BM_BufferPool *const bm, const char *const pageFileName, const int numPages, ReplacementStrategy strategy, void *stratData) { if(pageFileName == NULL) return RC_FILE_NAME_NOT_PROVIDED; if(numPages <= 0) return RC_WRONG_NUMBER_OF_FRAMES; int i; // Update bufferpool variables. bm->pageFile = (char *) malloc(strlen(pageFileName) + 1); strcpy(bm->pageFile, pageFileName); bm->numPages = numPages; bm->strategy = strategy; // Initialize mgmt data bm->mgmtData = (BM_MgmtData *) malloc(sizeof(BM_MgmtData)); bm->mgmtData->readIO = 0; bm->mgmtData->writeIO = 0; bm->mgmtData->emptyFrames = numPages; // Define head node for the page replacement linked list. // bm->mgmtData->head = (BM_PageReplaceList *) malloc(sizeof(BM_PageReplaceList)); bm->mgmtData->head = NULL; // bm->mgmtData->last = (BM_PageReplaceList *) malloc(sizeof(BM_PageReplaceList)); bm->mgmtData->last = NULL; // bm->mgmtData->last = NULL; // bm->mgmtData->refPointer = (BM_PageReplaceList *) malloc(sizeof(BM_PageReplaceList)); bm->mgmtData->refPointer = NULL; // Initialize hash table details. bm->mgmtData->hashT = (BM_HashTable *) malloc (sizeof(BM_HashTable)); // bm->mgmtData->hashT->hashArray = (PageInfo **) malloc (sizeof(PageInfo *)); for(i=0; i < numPages; i++) { // Initialize pageInfo in the frame. bm->mgmtData->hashT->hashArray[i] = (PageInfo *) malloc (sizeof(PageInfo)); bm->mgmtData->hashT->hashArray[i]->pageHandle = (BM_PageHandle *) malloc (sizeof(BM_PageHandle)); bm->mgmtData->hashT->hashArray[i]->pageHandle->data = (char *) malloc (PAGE_SIZE); strcpy(bm->mgmtData->hashT->hashArray[i]->pageHandle->data, "\0"); } for(i=0; i < numPages; i++) { bm->mgmtData->hashT->hashArray[i]->fixCount = 0; bm->mgmtData->hashT->hashArray[i]->dirtyFlag = false; // Initialize pageHandle in the frame. // bm->mgmtData->hashT->hashArray[i]->pageHandle = (BM_PageHandle *) malloc (sizeof(BM_PageHandle)); bm->mgmtData->hashT->hashArray[i]->pageHandle->pageNum = NO_PAGE; // Allocate memory for data in the page frame. // bm->mgmtData->hashT->hashArray[i]->pageHandle->data = (char *) malloc (PAGE_SIZE); } bm->mgmtData->hashT->arraySize = numPages; // Initialize file handle for the buffer pool. bm->mgmtData->fh = (SM_FileHandle *) malloc (sizeof(SM_FileHandle)); openPageFile (bm->pageFile, bm->mgmtData->fh); return RC_OK; }