Example #1
0
//--------------------------------------------------------------------
// BufMgr::FindFrame
//
// Input    : pid - a page id 
// Output   : None
// Purpose  : Look for the page in the buffer pool, return the frame
//            number if found.
// PreCond  : None
// PostCond : None
// Return   : the frame number if found. INVALID_FRAME otherwise.
//--------------------------------------------------------------------
int BufMgr::FindFrame( PageID pid )
{
	Frame* currFrame;
	for (int iter = 0; iter < numFrames; iter++) {
		currFrame = &frames[iter];
		if (currFrame->GetPageID() == pid) {
			return iter;
		}
	}
	return INVALID_FRAME;
}
Example #2
0
//--------------------------------------------------------------------
// BufMgr::UnpinPage
//
// Input    : pid     - page id of a particular page 
//            dirty   - indicate whether the page with page id = pid
//                      is dirty or not. (Optional, default to false)
// Output   : None
// Purpose  : Unpin the page with page id = pid in the buffer. Mark 
//            the page dirty if dirty is true.  
// Condition: The page is already in the buffer and is pinned.
// PostCond : The page is unpinned and the number of pin on the
//            page decrease by one. 
// Return   : OK if operation is successful.  FAIL otherwise.
//--------------------------------------------------------------------
Status BufMgr::UnpinPage(PageID pid, bool dirty)
{
	//std::cout << "Unin PageID " << pid << std::endl;
	////std::cout << "Unpinning page  " << pid << " Dirty?: " << dirty << std::endl;
	int frameIndex = FindFrame(pid);
	if (frameIndex == INVALID_FRAME) return FAIL;

	Frame* targetFrame = &frames[frameIndex];
	if (targetFrame->NotPinned()) return FAIL;

	if (dirty) targetFrame->DirtyIt();

	targetFrame->Unpin();

	if (targetFrame->NotPinned()) replacer->AddFrame(targetFrame->GetPageID());

	return OK;
}
Example #3
0
//--------------------------------------------------------------------
// BufMgr::FlushPage
//
// Input    : pid  - page id of a particular page 
// Output   : None
// Purpose  : Flush the page with the given pid to disk.
// Condition: The page with page id = pid must be in the buffer,
//            and is not pinned. pid cannot be INVALID_PAGE.
// PostCond : The page with page id = pid is written to disk if it's dirty. 
//            The frame where the page resides is empty.
// Return   : OK if operation is successful.  FAIL otherwise.
//--------------------------------------------------------------------
Status BufMgr::FlushPage(PageID pid)
{
	//std::cout << "Flush Page" << pid << std::endl;
	////std::cout << "Flush Page  " << pid << std::endl;
	int frameIndex = FindFrame(pid);
	if (frameIndex == INVALID_FRAME) return FAIL;

	Frame* targetFrame = &frames[frameIndex];
	if(!targetFrame->IsValid() || !targetFrame->NotPinned()) return FAIL;

	if (targetFrame->IsDirty()){
		if (targetFrame->Write() != OK) return FAIL;
		numDirtyPageWrites++;
	}
	
	replacer->RemoveFrame(targetFrame->GetPageID());
	targetFrame->EmptyIt();
	//std::cout << "Flush OK " << std::endl;
	return OK;
} 
Example #4
0
Status BufMgr::FlushAllPages()
{
	//std::cout << "Flush all " << std::endl;
	bool failedOnce = false;
	Frame* currFrame;
	for (int iter = 0; iter < numFrames; iter++) {
		currFrame = &frames[iter];
		if (currFrame->IsValid()) {
			// Check that the frame is not pinned
			if (!currFrame->NotPinned()){
				failedOnce = true;
			}

			if (currFrame->IsDirty()){
				if (currFrame->Write() != OK) failedOnce = true;
				numDirtyPageWrites++;
			}

			replacer->RemoveFrame(currFrame->GetPageID());
			currFrame->EmptyIt();
		}
	}
	return (failedOnce) ? FAIL : OK;
}
Example #5
0
//--------------------------------------------------------------------
// BufMgr::PinPage
//
// Input    : pid     - page id of a particular page 
//            isEmpty - (optional, default to false) if true indicate
//                      that the page to be pinned is an empty page.
// Output   : page - a pointer to a page in the buffer pool. (NULL
//            if fail)
// Purpose  : Pin the page with page id = pid to the buffer.  
//            Read the page from disk unless isEmpty is true or unless
//            the page is already in the buffer.
// Condition: Either the page is already in the buffer, or there is at
//            least one frame available in the buffer pool for the 
//            page.
// PostCond : The page with page id = pid resides in the buffer and 
//            is pinned. The number of pin on the page increase by
//            one.
// Return   : OK if operation is successful.  FAIL otherwise.
//--------------------------------------------------------------------
Status BufMgr::PinPage(PageID pid, Page*& page, bool isEmpty)
{
	if(pid == INVALID_PAGE) return FAIL;

	totalCall++;

	// Check if the page is in the buffer pool
	bool inPool = false;
	Frame* currFrame;
	for (int iter = 0; iter < numFrames; iter++) {
		currFrame = &frames[iter];
		if (currFrame->GetPageID() == pid){
			inPool = true;
			totalHit++;
			break;
		}
	}

	if (inPool){
		// Increase its pin count and set output page pointer
		currFrame->Pin();
		page = currFrame->GetPage();
	}
	else {
		
		// Find the first free frame if there is one
		bool foundEmptyFrame = false;
		for (int iter = 0; iter < numFrames; iter++) {
			currFrame = &frames[iter];
			if (!currFrame->IsValid()){
				foundEmptyFrame = true;
				break;
			}
		}
		
		if (!foundEmptyFrame) {
		
			// Find a page to evict based on our replacement policy
			int replacedPageID = replacer->PickVictim();

			// Get a pointer to the frame we will flush
			for (int iter = 0; iter < numFrames; iter++) {
				currFrame = &frames[iter];
				if (currFrame->GetPageID() == replacedPageID){
					break;
				}
			}

			if(FlushPage(replacedPageID) != OK) { 
				page = NULL;
				return FAIL;
			}
		}

		currFrame->SetPageID(pid);
		currFrame->Pin();

		// If the page is not empty, read it in from disk
		if (!isEmpty && currFrame->Read(pid) != OK) {
			page = NULL;
			return FAIL;
		}
		

		page = currFrame->GetPage();
	}

	// Now that the frame is pinned we need to remove it from the ones that can be evicted
	replacer->RemoveFrame(currFrame->GetPageID());
	////std::cout << "pinned page: " << currFrame->GetPageID() <<std::endl;
	return OK;
}