コード例 #1
0
RC forceFlushPool(BM_BufferPool *const bm) {

	int i;
	if(bm == NULL)
		return RC_BUFFER_MGR_NOT_INIT;

	// Get the head node of the linked list.
	BM_PageReplaceList *current = bm->mgmtData->head;

	while(current != NULL) {
		if(current->pageFrameHandle->fixCount == 0)
		{
			if(current->pageFrameHandle->dirtyFlag)
			{
				BM_PageHandle *const page = current->pageFrameHandle->pageHandle;
				if(forcePage(bm, page) != RC_OK)
				{
					return RC_FORCE_FLUSH_FAILED;
				}
			}
		}
		current = current->nextFrame;
	}

	return RC_OK;
}
コード例 #2
0
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();
}
コード例 #3
0
void updateOperationDetails(RM_TableData *rel, recordTableInfo *rec,
		BM_PageHandle *pageHandle, int recordId) {
	char *data;
	recordId = 0;
	markDirty(rec->bufferManager, pageHandle);
	unpinPage(rec->bufferManager, pageHandle);
	forcePage(rec->bufferManager, pageHandle);
	tableInfoDetailsToFileData(rel->name, data, rec);
}
コード例 #4
0
/**************************************************************************************
 * Function Name: forceFlushPool
 *
 * Description:
 *		Write back the data in all dirty pages in the Buffer Pool
 *
 * Parameters:
 *		BM_BufferPool *const bm: Buffer Pool Handler
 *
 * Return:
 *		RC: return code
 *
 * Author:
 *		Chengnan Zhao <*****@*****.**>
 *
 * History:
 *		Date        Name									Content
 *		----------  --------------------------------------	------------------------
 *		2015-03-14  Chengnan Zhao <*****@*****.**>	Initialization
 *		2015-03-20	Xin Su <*****@*****.**>				Modify the PageList queue
 *															Add comments
 *															Add judgment of the rc returned by write function
 *		2015-03-27	Xin Su <*****@*****.**>				Add validation of whether there is any unwritable page
 **************************************************************************************/
RC forceFlushPool(BM_BufferPool * const bm) {
	PageList *queue = (PageList *) bm->mgmtData;
	int unwritableCount = 0;

	// Set the current pointer to the head
	queue->current = queue->head;

	// Before writing a page back to disk, do check whether the fixCount = 0
	// Just call forcePage() to write a dirty and writable page back to the file

	// The while loop ends when the current pointer points to the tail
	while (queue->current != queue->tail) {
		// Validate whether the page is writable
		// if the page is unwritable, then increment the unwritableCount
		// else if the page is dirty and writable, call forcePage() to write the page back to the file
		if (queue->current->dirtyFlag == TRUE && queue->current->fixCount > 0) {
			unwritableCount++;
		} else if (queue->current->dirtyFlag == TRUE
				&& queue->current->fixCount == 0) {
			forcePage(bm, queue->current->page);
		}

		queue->current = queue->current->next;
	}

	// After the while loop, the current points to the tail of the PageList
	// We still need to check the page in the tail, using the same logic above
	if (queue->current == queue->tail) {
		if (queue->current->dirtyFlag == TRUE && queue->current->fixCount > 0) {
			unwritableCount++;
		} else if (queue->current->dirtyFlag == TRUE
				&& queue->current->fixCount == 0) {
			forcePage(bm, queue->current->page);
		}
	}

	// if there is any unwritable page, then return error code
	if (unwritableCount != 0) {
		return RC_FLUSH_POOL_ERROR;
	}

	return RC_OK;
} // forceFlushPool
コード例 #5
0
ファイル: record_mgr.c プロジェクト: shalinc/Nested-Loop-Join
/*
 * This function is used to update a Record,
 * updating on a deleted page is not possible
 */
RC updateRecord (RM_TableData *rel, Record *record)
{
	//Find the data to be updated
	if(record->id.page > 0 && record->id.page <=  totalPages)
	{
		BM_PageHandle *page = MAKE_PAGE_HANDLE();

		int pageNum, slotNum;

		// Setting record id and slot number
		pageNum = record->id.page;
		slotNum = record->id.slot;

		//Compare if the record is a deleted Record,
		//return update not possible for deleted records (EC 401)

		if(strncmp(record->data, "DELETED_RECORD", 14) == 0)
			return RC_RM_UPDATE_NOT_POSSIBLE_ON_DELETED_RECORD;

		//Take the serailized updated record data
		char *record_str = serializeRecord(record, rel->schema);

		//pin page
		pinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page, record->id.page);

		//set the new fields, or the entire modified page
		memset(page->data, '\0', strlen(page->data));
		sprintf(page->data, "%s", record_str);

		//free the temp data
		free(record_str);

		//mark the page as dirty
		markDirty(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//unpin the page, after use
		unpinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//force write onto the page, as it is modified page now
		forcePage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//printf("record data in update: %s\n", page->data);

		free(page);		//free page, avoid leaks
		return RC_OK;
	}
	else
	{
		return RC_RM_NO_MORE_TUPLES;	//return the data to be modfied not found
	}

	return RC_OK;
}
コード例 #6
0
ファイル: record_mgr.c プロジェクト: shalinc/Nested-Loop-Join
/*
 * This function is used to Delete the Record from the Table
 * BONUS IMPLEMENTATION - TOMBSTONE IS USED IN DELETION PROCESS
 */
RC deleteRecord (RM_TableData *rel, RID id)
{
	/*A TOMBSTONE FLAG is set to mark it as a Deleted Record, but actual delete is not done
	 * The Record is Prefixed with DELETED_RECORD string
	 * ex. consider the record to be deleted be
	 * (a:1,b:aaaa,c:45), the serializer store it as [1-0](a:1,b:aaaa,c:45)
	 * deleted will be marked as DELETED RECORD[1-0](a:1,b:aaaa,c:45)
	 */

	char deleteTombStomeFlag[14] = "DELETED_RECORD";	//Tombstone flag

	char *temp = (char*)malloc(sizeof(char*));			//temp memory allocation to preappend the flag

	if(id.page > 0 && id.page <=  totalPages)
	{
		BM_PageHandle *page = MAKE_PAGE_HANDLE();

		//Pin page, to mark it in USE
		pinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page, id.page);

		//attach the flag to deletedRecord
		strcpy(temp, deleteTombStomeFlag);
		strcat(temp, page->data);

		//set pageNum
		page->pageNum = id.page;

		//copy the new data onto the Page i.e. modify the page->data
		memset(page->data, '\0', strlen(page->data));
		sprintf(page->data, "%s", temp);

		//marking the page dirty, as new data has been written, i.e. tombstone data
		markDirty(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//unpin page, after use
		unpinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		//write the new data onto the page, in the pageFile
		forcePage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

		page = NULL;
		free(page);		//free page, avoid leaks
		return RC_OK;
	}
	else
	{
		return RC_RM_NO_MORE_TUPLES;
	}

	return RC_OK;
}
コード例 #7
0
RC shutdownBufferPool(BM_BufferPool *const bm) {

	RC retCode;
	// Get the head node of the linked list.
	BM_PageReplaceList *current = bm->mgmtData->last;

	while(current != NULL) {
		if(current->pageFrameHandle->fixCount == 0) {
			// If fix count is 0, then proceed, else throw error.
			if(current->pageFrameHandle->dirtyFlag) {
                                // If dirty flag is set, write page back to the disk.
				BM_PageHandle *const page = current->pageFrameHandle->pageHandle;
				if(forcePage(bm, page) != RC_OK) {
					return RC_FORCE_FLUSH_FAILED;
				}
			}
                        current = current->prevFrame;
		} else {
                        // Throw error as buffer pool is still in use.
			return RC_POOL_IN_USE;
		}
	}

	int i;
        // Deallocate memory allocated for frame data and page handle.
        for(i=0; i < bm->numPages; i++) {
                free(bm->mgmtData->hashT->hashArray[i]->pageHandle->data);	// Char *
                free(bm->mgmtData->hashT->hashArray[i]->pageHandle);		// BM_PageHandle
                free(bm->mgmtData->hashT->hashArray[i]);			// PageInfo
        }

//        free(bm->mgmtData->hashT->hashArray);
        // Close file and deallocate memory assigned to file handle.
        closePageFile(bm->mgmtData->fh);

        // Deallocate memory assigned for each link in the linked list.
        current = bm->mgmtData->last;
        while(current->prevFrame != NULL) {
                free(current->nextFrame);
                current = current->prevFrame;
        }
        free(current);

        free(bm->mgmtData->fh);		// Deallocate memory for SM_FileHandle
        free(bm->mgmtData->hashT);	// Deallocation of PageInfo **
        free(bm->mgmtData);		// Deallocation of BM_MgmtData
        free(bm->pageFile);		// Deallocation of page file

	return RC_OK;
}
コード例 #8
0
// 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();  
}
コード例 #9
0
// 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();  
}
コード例 #10
0
void pageOperations(recordTableInfo *table, int pageNum, int slot,
		RM_TableData *rel, Record *record) {
	BM_PageHandle *pageHandle=NULL;
	pageHandle = getBuffPageHandle();
	char *strRecord,*tempData;
	strRecord = serializeRecord(record, rel->schema);
	if(pinPage(table->bufferManager, pageHandle, pageNum)==RC_OK)
			strncpy(pageHandle->data + (slot * table->slotSize), strRecord,
			strlen(strRecord));

	markDirty(table->bufferManager, pageHandle);
	unpinPage(table->bufferManager, pageHandle);
	if(forcePage(table->bufferManager, pageHandle)==RC_OK)
		record->id.tombS = false;
	table->numOfRecords = table->numOfRecords + 1;
	tableInfoDetailsToFileData(rel->name, tempData, table);
		free(pageHandle);
		free(strRecord);
}
コード例 #11
0
ファイル: buffer_mgr.c プロジェクト: 2troger/cs_525_1
RC unpinPage (BM_BufferPool *const bm, BM_PageHandle *const page)
{
  resetPages();
  int i;
  for (i = 0; i < bm->numPages; i++) {
    if (pages->pageNum == page->pageNum) {
      break;
    }
    if(i < bm->numPages-1){
      pages = pages->nextPage;
    }
  }


  if(pages->isMark){
    forcePage(bm, page);
  }

  pages->fixCount--;
 
  resetPages();
  return RC_OK; 
}
コード例 #12
0
//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;
    }
    
}
コード例 #13
0
ファイル: record_mgr.c プロジェクト: shalinc/Nested-Loop-Join
/*
 * This function is used to insert a new Record into the table
 * while inserting, the record Manager assigns a RID to the record
 * and update the "record" parameter too
 */
RC insertRecord (RM_TableData *rel, Record *record)
{
	//Create a record variable
	Record *r = (Record *)malloc(sizeof(Record));

	RID rid;
	rid.page = 1;
	rid.slot = 0;

	//Find the next place of insertion of a record
	while(rid.page > 0 && rid.page < totalPages)
	{
		rid.page = rid.page + 1;
		rid.slot = 0;

		/*getRecord(rel, rid, r); //obtaining the record from the table
		//checking for soft delete record in the table space for insertion
		if(strncmp(r->data, "DELETED_RECORD", 14) == 0)
			break;*/
	}


	r = NULL;
	free(r); //free the memory of r which was just a temporary allocation

	//mark the page as free page
	((RM_RecordMgmt *)rel->mgmtData)->freePages[0] = rid.page;

	//create a page handle
	BM_PageHandle *page = MAKE_PAGE_HANDLE();

	//assign the record, its RID and slot number
	record->id.page = ((RM_RecordMgmt *)rel->mgmtData)->freePages[0];
	record->id.slot = 0;

	//Serialize the Record to be inserted
	char * serializedRecord = serializeRecord(record, rel->schema);

	//Pin the record page, to mark that it is in use
	pinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page, ((RM_RecordMgmt *)rel->mgmtData)->freePages[0]);

	//insert the new record data, into the Table i.e. Pages of the PageFile
	memset(page->data, '\0', strlen(page->data));
	sprintf(page->data, "%s", serializedRecord);

	//mark the page as Dirty Page, as now there is a new record entry on that page
	markDirty(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//Unpin the page as now it has been used
	unpinPage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//Force Page to push entire data onto the page
	forcePage(((RM_RecordMgmt *)rel->mgmtData)->bm, page);

	//printf("record data: %s\n", page->data);

	free(page);		//free page, avoid memory leaks

	((RM_RecordMgmt *)rel->mgmtData)->freePages[0] += 1;

	totalPages++;
	return RC_OK;
}