const Status BufMgr::allocBuf(unsigned int & frame) { // Your solution goes here // Phorum says we should remove the entry from BufMap too. I don't really know how to do this. if(numBufs == 0){ frame = clockHand; return OK; } advanceClock(); unsigned int temp = clockHand; //cout << "Clockhand = " << clockHand << endl; do{ if(bufTable[clockHand].valid == false){ //cout << "1" << endl; bufTable[clockHand].Clear(); frame = clockHand; return OK; } else if(bufTable[clockHand].valid == true){ if(bufTable[clockHand].loved == true){ //cout << "2" << endl; bufTable[clockHand].loved = false; advanceClock(); } else if(bufTable[clockHand].loved == false){ //cout << " a " << endl; if(bufTable[clockHand].pinCnt > 0){ //cout << "3 " << endl; advanceClock(); } else if(bufTable[clockHand].pinCnt <= 0){ //cout << "4? " << endl; if(bufTable[clockHand].dirty == true){ //cout << "is this ever called" << endl; Status tempstatus = bufTable[clockHand].file->writePage(bufTable[clockHand].pageNo, &bufPool[clockHand]);//I think this is how you flush the page to disk. if(tempstatus == UNIXERR){ return UNIXERR; }else if(tempstatus == OK){ bufStats.diskwrites ++; } //flush page to disk? UNIXERR if fail; } bufMap.remove(bufTable[clockHand].file, bufTable[clockHand].pageNo); //if(tempst == OK) cout << "all good here" << endl; bufTable[clockHand].Clear(); frame = clockHand; return OK; } } } //cout << "Clockhand = " << clockHand << endl; }while(clockHand != temp); return BUFFEREXCEEDED; }
/* * 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. This private * method will get called by the readPage() and allocPage() methods described below. Make * sure that if the buffer frame allocated has a valid page in it, you remove the appropriate * entry from the hash table. */ void BufMgr::allocBuf(FrameId & frame) { std::uint32_t scannedNum= 0; bool foundbuffer= false; while (scannedNum < numBufs) { scannedNum++; //advance the clock advanceClock(); //check if buffer is valid (if already has file), if not use the buffer if (!bufDescTable[clockhand].valid) { break; } //check if refbit is set and if it is pinned. if has not been referenced and pincount is 0, use it if (!bufDescTable[clockhand].refbit && bufDescTable[clockhand].pinCnt==0) { foundbuffer= true; //remove previous entry from the hashtable hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); //if has bee referenced clear the bit else { bufDescTable[clockHand].refbit= false; } }
TrayIcon::TrayIcon(MainWindow* parent) : KStatusNotifierItem(parent) { setObjectName( "Ktimetracker Tray" ); // the timer that updates the "running" icon in the tray _taskActiveTimer = new QTimer(this); connect( _taskActiveTimer, SIGNAL( timeout() ), this, SLOT( advanceClock()) ); if (icons == 0) { icons = new QVector<QPixmap*>(8); for (int i=0; i<8; i++) { QPixmap *icon = new QPixmap(); QString name; name.sprintf("active-icon-%d.xpm",i); *icon = UserIcon(name); icons->insert(i,icon); } } TimetrackerWidget *timetrackerWidget = static_cast< TimetrackerWidget * >( parent->centralWidget() ); if ( timetrackerWidget ) { KAction *action = timetrackerWidget->action( "configure_ktimetracker" ); if ( action ) contextMenu()->addAction( action ); action = timetrackerWidget->action( "stopAll" ); if ( action ) contextMenu()->addAction( action ); } resetClock(); initToolTip(); }
TEST_F(CachingCorrectnessTest, FreshWithStaleRedirect) { KURL redirectUrl(ParsedURLString, kResourceURL); const char redirectTargetUrlString[] = "http://redirect-target.com"; KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString); ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw); ResourceResponse stale301Response; stale301Response.setURL(redirectUrl); stale301Response.setHTTPStatusCode(301); stale301Response.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString); stale301Response.setHTTPHeaderField(HTTPNames::Location, redirectTargetUrlString); // Add the redirect to our request. ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl); firstResource->willFollowRedirect(redirectRequest, stale301Response); // Add the final response to our request. ResourceResponse fresh200Response; fresh200Response.setURL(redirectTargetUrl); fresh200Response.setHTTPStatusCode(200); fresh200Response.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString); fresh200Response.setHTTPHeaderField(HTTPNames::Expires, kOneDayAfterOriginalRequest); firstResource->setResponse(fresh200Response); memoryCache()->add(firstResource.get()); advanceClock(500.); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(firstResource, fetched); }
TEST_F(ScopedUsHistogramTimerTest, Basic) { TestCustomCountHistogram scopedUsCounter("test", 0, 10000000, 50); { ScopedUsHistogramTimer timer(scopedUsCounter); advanceClock(0.5); } // 0.5s == 500000us EXPECT_EQ(500000, scopedUsCounter.histogram()->SnapshotSamples()->sum()); }
// If the image has been loaded in this "document" before, then it should have list of available images logic, and so // normal cache testing should be bypassed. TEST_F(CachingCorrectnessTest, ReuseImageExpiredFromExpires) { ResourceResponse expired200Response; expired200Response.setHTTPStatusCode(200); expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response, Resource::Image); // Advance the clock within the freshness period, and make a request to add this image to the document resources. advanceClock(15.); ResourcePtr<Resource> firstFetched = fetchImage(); EXPECT_EQ(expired200, firstFetched); // Advance the clock within the expiredness period of this resource before we make a request. advanceClock(24. * 60. * 60. + 15.); ResourcePtr<Resource> fetched = fetchImage(); EXPECT_EQ(expired200, fetched); }
// The strong validator causes a revalidation to be launched, and the proxy and original resources leak because of their reference loop. TEST_F(CachingCorrectnessTest, DISABLED_ExpiredFromLastModified) { ResourceResponse expired200Response; expired200Response.setHTTPStatusCode(200); expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); expired200Response.setHTTPHeaderField("Last-Modified", kOneDayBeforeOriginalRequest); ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response); // Advance the clock beyond the implicit freshness period. advanceClock(24. * 60. * 60. * 0.2); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(expired200, fetched); }
TEST_F(CachingCorrectnessTest, ExpiredFromMaxAge) { ResourceResponse expired200Response; expired200Response.setHTTPStatusCode(200); expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); expired200Response.setHTTPHeaderField("Cache-Control", "max-age=600"); ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response); // Advance the clock within the expiredness period of this resource before we make a request. advanceClock(700.); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(expired200, fetched); }
TEST_F(CachingCorrectnessTest, ExpiredFromExpires) { ResourceResponse expired200Response; expired200Response.setHTTPStatusCode(200); expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString); expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response); // Advance the clock within the expiredness period of this resource before we make a request. advanceClock(24. * 60. * 60. + 15.); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(expired200, fetched); }
TEST_F(CachingCorrectnessTest, FreshButNoStore) { ResourceResponse fresh200NostoreResponse; fresh200NostoreResponse.setHTTPStatusCode(200); fresh200NostoreResponse.setHTTPHeaderField("Date", kOriginalRequestDateAsString); fresh200NostoreResponse.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest); fresh200NostoreResponse.setHTTPHeaderField("Cache-Control", "no-store"); ResourcePtr<Resource> fresh200Nostore = resourceFromResourceResponse(fresh200NostoreResponse); // Advance the clock within the freshness period of this resource before we make a request. advanceClock(24. * 60. * 60. - 15.); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(fresh200Nostore, fetched); }
// FIXME: Determine if ignoring must-revalidate for blink is correct behaviour. // See crbug.com/340088 . TEST_F(CachingCorrectnessTest, DISABLED_FreshButMustRevalidate) { ResourceResponse fresh200MustRevalidateResponse; fresh200MustRevalidateResponse.setHTTPStatusCode(200); fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString); fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Expires, kOneDayAfterOriginalRequest); fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Cache_Control, "must-revalidate"); ResourcePtr<Resource> fresh200MustRevalidate = resourceFromResourceResponse(fresh200MustRevalidateResponse); // Advance the clock within the freshness period of this resource before we make a request. advanceClock(24. * 60. * 60. - 15.); ResourcePtr<Resource> fetched = fetch(); EXPECT_NE(fresh200MustRevalidate, fetched); }
/* * 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; } }
/** * Allocates a frame using the clock algorithm. * If the frame is dirty, writes it back to disk. * If all buffer frames are pinned, returns BUFFEREXCEEDED. * If the call to the I/O layer returned an error when a dirty page was being written to disk, returns UNIXERR. * Otherwise, returns OK. * * @param frame frame being allocated * @return status the status of the function call **/ const Status BufMgr::allocBuf(int & frame) { // number of frames that have been pinned int frameCnt = 0; while (frameCnt < numBufs) { advanceClock(); if (bufTable[clockHand].valid == false){ frame = clockHand; return OK; } else { BufDesc* desc = &(bufTable[clockHand]); if (desc->refbit) { desc->refbit = false; } else { if (desc->pinCnt == 0){ // if the frame is dirty, write it back to disk Status status; if (desc->dirty) { status = (desc->file)->writePage(desc->pageNo, &(bufPool[clockHand])); if (status != OK) return status; desc->dirty = false; } // remove the corresponding entry in hashTable hashTable->remove(bufTable[clockHand].file, bufTable[clockHand].pageNo); frame = clockHand; return OK; } else { frameCnt++; } } } } return BUFFEREXCEEDED; }
/** * 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(); }
/** This function allocates a free frame using the clock algorithm; if necessary, writing a dirty page back to disk. Returns BUFFEREXCEEDED if all buffer frames are pinned, UNIXERR if the call to the I/O layer returned an error when a dirty page was being written to disc; else OK. This private method will get called by the readPage() and allocPage() methods. If the buffer frame allocated has a valid page in it, then remove the appropriate entry from the hash table. @param frame-reference to the frame being allocated @return Status-status information from function **/ const Status BufMgr::allocBuf(int & frame) { int pinCount = 0; //unsigned int initialClockHand = clockHand; while(1){ advanceClock(); //if valid is false, clear and return frame number if (bufTable[clockHand].valid != false) { if (bufTable[clockHand].pinCnt > 0) { pinCount++; } //if pinCount reaches numBufs than every buffer frame is being referenced if (pinCount == numBufs) { return BUFFEREXCEEDED; } //The two loops in the logic diagram if (bufTable[clockHand].refbit == true) { //Check valid bit bufTable[clockHand].refbit = false; continue; //Loop if valid and refbit set } else if (bufTable[clockHand].refbit == false && bufTable[clockHand].pinCnt > 0){ continue; // if valid, unreferenced, not pinned, and dirty; than flush page in frame to disc } else if (bufTable[clockHand].refbit == false && bufTable[clockHand].pinCnt <= 0 && bufTable[clockHand].dirty == true) { assert(bufTable[clockHand].pinCnt == 0); //Sanity check /**Flush page to disk **/ flushFile(bufTable[clockHand].file); bufTable[clockHand].dirty = false; } assert(bufTable[clockHand].dirty == false); //Should not be dirty assert(bufTable[clockHand].pinCnt == 0); //Should be zero if (bufTable[clockHand].valid == true) { assert(bufTable[clockHand].pinCnt == 0); hashTable->remove(bufTable[clockHand].file, bufTable[clockHand].pageNo); } }//end valid == false //A frame has been selected for removal bufTable[clockHand].Clear(); frame = clockHand; //clear frame and return frame pointer return OK; }//end valid not equal to false }// end function allocBuf
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; }
const Status BufMgr::allocBuf(int & frame) { // perform first part of clock algorithm to search for // open buffer frame // Assumes non-concurrent access to buffer manager Status status = OK; int numScanned = 0; bool found = 0; while (numScanned < 2*numBufs) { // advance the clock advanceClock(); numScanned++; // if invalid, use frame if (! bufTable[clockHand].valid) { break; } // is valid, check referenced bit if (! bufTable[clockHand].refbit) { // check to see if someone has it pinned if (bufTable[clockHand].pinCnt == 0) { // hasn't been referenced and is not pinned, use it // remove previous entry from hash table status = hashTable->remove(bufTable[clockHand].file, bufTable[clockHand].pageNo); found = true; //if (status != OK) return status; break; } } else { // has been referenced, clear the bit bufStats.accesses++; bufTable[clockHand].refbit = false; } } // check for full buffer pool if (!found && numScanned >= 2*numBufs) { return BUFFEREXCEEDED; } // flush any existing changes to disk if necessary if (bufTable[clockHand].dirty) { bufStats.diskwrites++; status = bufTable[clockHand].file->writePage(bufTable[clockHand].pageNo, &bufPool[clockHand]); if (status != OK) return status; } // return new frame number frame = clockHand; return OK; } // end allocBuf