📄 buf.c
字号:
#include <memory.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <fcntl.h>#include <iostream>#include <stdio.h>#include "page.h"#include "buf.h"#define ASSERT(c) { if (!(c)) { \ cerr << "At line " << __LINE__ << ":" << endl << " "; \ cerr << "This condition should hold: " #c << endl; \ exit(1); \ } \ }//----------------------------------------// Constructor of the class BufMgr//----------------------------------------BufMgr::BufMgr(const int bufs){ numBufs = bufs ; hashTable = new BufHashTbl(bufs * 2) ; bufTable = new BufDesc[bufs] ; bufPool = new Page[bufs] ; bufTable[0].next = &bufTable[1] ; bufTable[0].prior = NULL ; bufTable[0].frameNo = 0 ; for (int i = 1; i < bufs - 1; i++){ bufTable[i].next = &bufTable[i+1] ; bufTable[i].prior = &bufTable[i-1] ; bufTable[i].frameNo = i ; } bufTable[bufs - 1].next = NULL ; bufTable[bufs - 1].prior = &bufTable[bufs-2] ; bufTable[bufs - 1].frameNo = numBufs - 1 ; rearUPL = &bufTable[0] ; frontUPL = &bufTable[bufs-1] ; }BufMgr::~BufMgr() { BufDesc *tmpbuf = NULL ; for (int i = 0; i < numBufs; i++){ tmpbuf = &bufTable[i] ; if (tmpbuf->valid == true && tmpbuf->dirty == true) tmpbuf->file->writePage( tmpbuf->pageNo, &bufPool[i]) ; } delete hashTable ; delete []bufTable ; delete []bufPool ;}void BufMgr::BufDump() {// late}const Status BufMgr::allocBuf(int& frame) { BufDesc *mybuf = NULL ; if (rearUPL == NULL) return BUFFEREXCEEDED ; mybuf = rearUPL ; if (rearUPL == frontUPL) rearUPL = frontUPL = NULL ; else{ rearUPL = rearUPL->next ; rearUPL->prior = NULL ; } if (mybuf->dirty){ mybuf->file->writePage(mybuf->pageNo,&bufPool[mybuf->frameNo]) ; hashTable->remove(mybuf->file, mybuf->pageNo) ; } if (mybuf->valid == true) hashTable->remove(mybuf->file, mybuf->pageNo) ; mybuf->Clear() ; frame = mybuf->frameNo ; return OK ;}// release an unused buffer frame - used in error conditionsconst void BufMgr::releaseBuf(int frame) { rearUPL->prior = &bufTable[frame] ; bufTable[frame].next = rearUPL ; rearUPL = &bufTable[frame] ; rearUPL->prior = NULL ;}const Status BufMgr::readPage(File* file, const int PageNo, Page*& page){ int myframeNo ;// cout<<file<<" "<<PageNo<<endl ; if (hashTable->lookup(file,PageNo,myframeNo) == OK){ if (bufTable[myframeNo].pinCnt >= 1) bufTable[myframeNo].pinCnt++ ; else{ if (&bufTable[myframeNo] == rearUPL) rearUPL = bufTable[myframeNo].next ; if (&bufTable[myframeNo] == frontUPL) frontUPL = bufTable[myframeNo].prior ; if (bufTable[myframeNo].prior != NULL) bufTable[myframeNo].prior->next = bufTable[myframeNo].next ; if (bufTable[myframeNo].next != NULL) bufTable[myframeNo].next->prior = bufTable[myframeNo].prior ; bufTable[myframeNo].next = bufTable[myframeNo].prior = NULL ; bufTable[myframeNo].pinCnt = 1 ; } page = &bufPool[myframeNo] ; return OK ; } else{ if (allocBuf(myframeNo) != OK) return BUFFEREXCEEDED ; if (file->readPage(PageNo,&bufPool[myframeNo]) != OK){ releaseBuf(myframeNo) ; return UNIXERR ; }// cout<<"n read page ="<<(char *)&bufPool[myframeNo]<<endl ; bufTable[myframeNo].Set(file,PageNo) ; if(hashTable->insert(file,PageNo,myframeNo) != OK) return HASHTBLERROR ; page = &bufPool[myframeNo] ; return OK ; }}const Status BufMgr::unPinPage(const File* file, const int PageNo, const bool dirty, const bool loveIt){ int myframeNo; if (hashTable->lookup(file,PageNo,myframeNo) != OK) return HASHNOTFOUND ;// cout<<"relese frame ="<<myframeNo<<endl ; if(dirty) bufTable[myframeNo].dirty = dirty ;// cout<<"frame ="<<myframeNo<<" info =" ;// cout<<(char *)&bufPool[myframeNo]<<endl ; if (bufTable[myframeNo].pinCnt == 0) return PAGENOTPINNED ; bufTable[myframeNo].pinCnt-- ; if(bufTable[myframeNo].pinCnt != 0) return OK ; if ((rearUPL == NULL) && (frontUPL == NULL)){ rearUPL = frontUPL = &bufTable[myframeNo] ; return OK ; } if (loveIt == false) releaseBuf(myframeNo) ; else{ frontUPL->next = &bufTable[myframeNo] ; bufTable[myframeNo].prior = frontUPL ; frontUPL = &bufTable[myframeNo] ; frontUPL->next = NULL ; } return OK ;}const Status BufMgr::flushFile(const File* file) { for (int i = 0; i < numBufs; i++){ if (bufTable[i].file == file){ if (bufTable[i].pinCnt != 0) return PAGEPINNED ; if (bufTable[i].dirty) (bufTable[i].file)->writePage(bufTable[i].pageNo,&bufPool[bufTable[i].frameNo]) ; if (bufTable[i].valid) hashTable->remove( file, bufTable[i].pageNo) ; bufTable[i].valid = false ; bufTable[i].dirty = false ; } } return OK ;}const Status BufMgr::disposePage(File* file, const int pageNo) { int myframeNo ; if (hashTable->lookup(file,pageNo,myframeNo) != OK) return HASHTBLERROR ; if (bufTable[myframeNo].pinCnt != 0) return PAGEPINNED ; hashTable->remove(file,pageNo) ; releaseBuf(myframeNo) ; if (file->disposePage(pageNo) != OK) return UNIXERR ; return OK ;}const Status BufMgr::allocPage(File* file, int& pageNo, Page*& page) { int myframeNo ; if (file->allocatePage(pageNo) != OK) return UNIXERR ; if (allocBuf(myframeNo) != OK) return BUFFEREXCEEDED ;// cout<<"alloc frame="<<myframeNo<<endl ; if (hashTable->insert (file, pageNo, myframeNo) != OK){ releaseBuf(myframeNo) ; return HASHTBLERROR ; } bufTable[myframeNo].Set( file, pageNo) ; page = &bufPool[myframeNo] ; return OK ;}void BufMgr::printSelf(void) { cout<<"rearUPL framNo="<<rearUPL->frameNo<<endl ; cout<<"frontUPL frameNo="<<frontUPL->frameNo<<endl ; BufDesc* tmpbuf; int i = 1 ; cout << endl << "Print buffer...\n"; tmpbuf = rearUPL; do{ cout << tmpbuf->frameNo << "\t" << (char*)(&bufPool[tmpbuf->frameNo]) << "\tpinCnt: " << tmpbuf->pinCnt ; if (tmpbuf->valid == true) cout << "\tvalid" ; if (tmpbuf->dirty == true) cout << "\tdirty\n" ; cout << endl; tmpbuf = tmpbuf->next ; i = i + 1 ; }while(tmpbuf != NULL) ; cout<<"ky buf num = "<<i<<endl ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -