void BufferManager::unfixPage(BufferFrame& frame, bool isDirty) { // Adjust the lru-list. pthread_rwlock_wrlock(&lruBuffer_latch); bool foundFrame = false; //cout << "trying to unfix page with id " << frame.pageId << endl; //printBufferStatus(); BufferFrame *frameInBuffer = NULL; for(vector<BufferFrame*>::iterator i = lruBuffer.begin(); i != lruBuffer.end(); ++i) { if((*i)->pageId == frame.pageId) { frameInBuffer = *i; lruBuffer.erase(i); lruBuffer.push_back(frameInBuffer); foundFrame = true; if(isDirty) { frameInBuffer->writeDataToFile(); } int er = pthread_rwlock_unlock(&(frameInBuffer->latch)); // pthread_rwlock_unlock(&(frame.latch)); if(er!=0) cerr << "result code of unlocking frame: " << er; // cout << frame.pageId << " unlocked\n"; break; } } pthread_rwlock_unlock(&lruBuffer_latch); //Error handling. if(!foundFrame) { cerr << "Can not unfix a frame which is not cached!" << endl; } }
// gets the requested data from file and puts a new bufferFrame into the hashmap // if required, this method replaces frames in the buffer void BufferManager::cachePageFromFile(unsigned pageId) { // lock hash table and lru queue pthread_rwlock_wrlock(&buffer_latch); pthread_rwlock_wrlock(&lruBuffer_latch); // if buffer is full, replace a frame in buffer with page from file if(lruBuffer.size() >= size) { // Search for the first lockable buffer frame BufferFrame *toBeFreed = NULL; for(vector<BufferFrame*>::iterator i = lruBuffer.begin(); i != lruBuffer.end(); ++i) { // try to lock this frame, if not possible continue with next frame in lruBuffer int lockResult = pthread_rwlock_trywrlock(&((*i)->latch)); //cout << "lockResult: " << lockResult << " for pageId " << (*i)->pageId << endl; if(lockResult == 0) { pthread_rwlock_unlock(&((*i)->latch)); // cout << (*i)->pageId << " wr_locked and unlocked\n"; toBeFreed = *i; // if we found our candidate frame, delete it from the buffers and deallocate the memory int cnt = buffer.erase(toBeFreed->pageId); // delete from hash map assert(cnt == 1); toBeFreed->writeDataToFile(); // save changes lruBuffer.erase(i); //free mmapped memory if (munmap(toBeFreed->getData(), FRAME_SIZE) == -1) { cerr << "Error un-mmapping the file"; } delete toBeFreed; // deallocate memory break; } } if(toBeFreed==NULL) { cerr<<"no candidate was found => release locks and return!!!"; pthread_rwlock_unlock(&lruBuffer_latch); pthread_rwlock_unlock(&buffer_latch); return; } } // add new frame to hash map and append to end of lruBuffer BufferFrame *bf = new BufferFrame(file, pageId); buffer[pageId] = bf; lruBuffer.push_back(bf); // release locks pthread_rwlock_unlock(&lruBuffer_latch); pthread_rwlock_unlock(&buffer_latch); }