/* * Allocates a free frame using the clock algorithm; * if necessary, writing a dirty page back to disk. * * Throws BufferExceededException if all buffer frames are pinned. * params: FrameId & frame */ void BufMgr::allocBuf(FrameId & frame) { uint32_t pinnedPageCnt = 0; // implementation of the clock algorithm // remember to change the while(true) while(true) { advanceClock(); BufDesc* tmpbuf = &(bufDescTable[clockHand]); // if invalid then allocate this page if (tmpbuf->valid == false) { frame = clockHand; return; } // if refbit is set then clear and advance clock else if (tmpbuf->refbit == true) { tmpbuf->refbit = false; continue; } // ignore if page pinned else if (tmpbuf->pinCnt > 0) { pinnedPageCnt = pinnedPageCnt + 1; if(pinnedPageCnt >= numBufs) { throw BufferExceededException(); } continue; } // frame can be used // if the page is dirty flush to disk if (tmpbuf->dirty == true) { tmpbuf->file->writePage(bufPool[clockHand]); tmpbuf->dirty = false; } // now we can select this frame frame = clockHand; //remove from hashtable hashTable->remove(tmpbuf->file, tmpbuf->pageNo); return; } }
/** * Allocate a free frame. * * @param frame Frame reference, frame ID of allocated frame returned via this variable * @throws BufferExceededException If no such buffer is found which can be allocated */ void BufMgr::allocBuf(FrameId & frame) { bool found = false; FrameId starting = clockHand; //Loop through the buffer pool until you find a valid frame to replace while(!found){ advanceClock(); if(bufDescTable[clockHand].valid){ if(!bufDescTable[clockHand].refbit){ if(bufDescTable[clockHand].pinCnt == 0){ //we have found the correct frame found = true; hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); //remove from hash table if(bufDescTable[clockHand].dirty){ //write page to disk. bufDescTable[clockHand].file->writePage(bufPool[clockHand]); } else{ bufDescTable[clockHand].Clear(); } frame = bufDescTable[clockHand].frameNo; } else{ if(starting == clockHand && !found){ //we looped all the way around the buffer pool, throw an exception throw BufferExceededException(); } } } else{ //clear refbit bufDescTable[clockHand].refbit = false; } } else{ found = true; frame = bufDescTable[clockHand].frameNo; } } bufDescTable[clockHand].Clear(); }
void BufMgr::allocBuf(FrameId & frame) { std::uint32_t scanner = 0; bool cont = 0; while(scanner < 2*numBufs){ advanceClock(); scanner++; if(bufDescTable[clockHand].valid == false){ break; } if(!(bufDescTable[clockHand].refbit)){ if(bufDescTable[clockHand].pinCnt == 0){ hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); cont = true; break; } } else{ bufStats.accesses++; bufDescTable[clockHand].refbit = false; } } if((!cont) && (scanner >= 2*numBufs-1)){ throw BufferExceededException(); } if(bufDescTable[clockHand].dirty && bufDescTable[clockHand].valid){ bufStats.diskwrites++; bufDescTable[clockHand].file->writePage(bufPool[clockHand]); } bufDescTable[clockHand].Clear(); //bufDescTable[clockHand].Set(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); frame = clockHand; }
/* * * Allocate a free frame. * * @param frame Frame reference, frame ID of allocated frame returned via this variable * @throws BufferExceededException If no such buffer is found which can be allocated */ void BufMgr::allocBuf(FrameId & frame) { std::uint32_t clock_count = 0; //clock algorithm while(1){ advanceClock(); if(bufDescTable[clockHand].valid == true){ if(bufDescTable[clockHand].refbit == true){ bufDescTable[clockHand].refbit = false; //skip all the steps below and loop again continue; } if(bufDescTable[clockHand].pinCnt > 0){ clock_count++; //if every pages is being pinned in buffer pool, throw exception if(clock_count > numBufs){ throw BufferExceededException(); } continue; } if(bufDescTable[clockHand].dirty == true){ flushFile(bufDescTable[clockHand].file); bufDescTable[clockHand].dirty = false; } else{ hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); } break; } else{ break; } } frame = bufDescTable[clockHand].frameNo; }