예제 #1
0
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;
    }
}
예제 #2
0
// 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);
}