<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本次實驗要實現一個頁面的緩衝區管理器。
具體要實現以下的函數:
~BufMgr():
清除所有髒頁並釋放緩衝池和 BufDesc 表
void advanceClock():
用來找到下一個時鐘的位置
void allocBuf(FrameId& frame):
使用時鐘演演算法分配自由幀;如有必要,將髒頁寫回磁碟。
void readPage(File* file, const PageId PageNo, Page*& page)
通過呼叫 lookup()方法檢查頁是否已經在緩衝池中。當頁不在緩衝池中可以在雜湊表上丟擲 HashNotFoundException 以獲取幀編號。
void unPinPage(File* file, const PageId PageNo, const bool dirty)
減少一個頁面的佔用次數
void allocPage(File* file, PageId& PageNo, Page*& page)
通過呼叫 file->allocatePage()方法在指定的檔案中分配一個空頁。此方法將返回新分配的頁。然後呼叫 allocBuf()以獲取緩衝池幀。接下來,將一個條目插入到雜湊表中,並在幀上呼叫 Set(),以正確設定它。
void disposePage(File* file, const PageId pageNo)
功能是釋放一個頁面
void flushFile(File* file)
功能是找到含有對應檔案的頁面,並釋放
BufMgr::~BufMgr() { delete hashTable; delete[] bufPool; delete[] bufDescTable; }
直接呼叫 delete 刪除雜湊表、緩衝池、緩衝池表
void BufMgr::advanceClock() { clockHand++; if (clockHand >= numBufs) { clockHand %= numBufs; } }
將時鐘提前到緩衝池的下一幀。
如果指標超過了最大值,進行取模操作。
void BufMgr::allocBuf(FrameId &frame) { unsigned pinned = 0; while (true) { advanceClock(); if (!bufDescTable[clockHand].valid) { frame = clockHand; return; } if (bufDescTable[clockHand].refbit) { bufDescTable[clockHand].refbit = false; continue; } if (bufDescTable[clockHand].pinCnt) { pinned++; if (pinned == numBufs) { throw BufferExceededException(); } else { continue; } } if (bufDescTable[clockHand].dirty) { bufDescTable[clockHand].file->writePage(bufPool[clockHand]); bufDescTable[clockHand].dirty = false; } frame = clockHand; if (bufDescTable[clockHand].valid) { try { hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); } catch (HashNotFoundException &) { } } break; } }
遍歷棧區尋找可用的頁面。如果是沒有被使用過的頁面,直接進行分配。如果緩衝區所有的頁面都被佔用,那麼會進行報錯 BufferExceededException()。如果找到髒頁,會將它寫回磁碟,並將髒頁標記給清除。如果不是髒頁,那麼就進行分配操作。如果它在雜湊表中要將它移除。
void BufMgr::readPage(File *file, const PageId pageNo, Page *&page) { FrameId frame; try { hashTable->lookup(file, pageNo, frame); bufDescTable[frame].refbit = true; bufDescTable[frame].pinCnt++; page = (bufPool + frame); } catch (HashNotFoundException &) { allocBuf(frame); bufPool[frame] = file->readPage(pageNo); hashTable->insert(file, pageNo, frame); bufDescTable[frame].Set(file, pageNo); page = (bufPool + frame); } }
如果頁面在緩衝池中,增加它的佔用次數,呼叫 page 返回指向該頁面的指標。
如果頁面不在緩衝池中,那麼將頁面讀取到緩衝池,插入雜湊表中,呼叫 set 正確設定該介面,呼叫 page 返回指向該頁面的指標。
void BufMgr::unPinPage(File *file, const PageId pageNo, const bool dirty) { FrameId frame; try { hashTable->lookup(file, pageNo, frame); } catch (HashNotFoundException &) { //沒有該頁面 cerr << "Warning: unpinning a nonexistent page" << endl; return; } //找到頁面 if (bufDescTable[frame].pinCnt > 0) { bufDescTable[frame].pinCnt--; if (dirty) { bufDescTable[frame].dirty = true; } } else { //pin = 0,丟擲異常 throw PageNotPinnedException(bufDescTable[frame].file->filename(), bufDescTable[frame].pageNo, frame); } }
如果緩衝池中沒有該頁面,進行異常提示。
如果在緩衝池中,那麼將它的佔用次數減少。如果佔用次數為 0,進行報錯。
void BufMgr::flushFile(const File *file) { for (FrameId fi = 0; fi < numBufs; fi++) { if (bufDescTable[fi].file == file) { if (!bufDescTable[fi].valid) { throw BadBufferException(fi, bufDescTable[fi].dirty, bufDescTable[fi].valid, bufDescTable[fi].refbit); } if (bufDescTable[fi].pinCnt > 0) { throw PagePinnedException(file->filename(), bufDescTable[fi].pageNo, fi); } if (bufDescTable[fi].dirty) { bufDescTable[fi].file->writePage(bufPool[fi]); bufDescTable[fi].dirty = false; } hashTable->remove(file, bufDescTable[fi].pageNo); bufDescTable[fi].Clear(); } } }
遍歷整個表,找到含有對應頁面的緩衝頁,移除並清空該頁面。如果頁面是髒頁,則將其寫回磁碟,初始化髒頁標記。如果頁面被佔用或者頁面不可用,則進行報錯。
void BufMgr::allocPage(File *file, PageId &pageNo, Page *&page) { FrameId frame; Page p = file->allocatePage(); allocBuf(frame); bufPool[frame] = p; pageNo = p.page_number(); hashTable->insert(file, pageNo, frame); bufDescTable[frame].Set(file, pageNo); page = bufPool + frame; }
掉用 allocatePage()分配一個新頁面,加入雜湊表,呼叫 set(),返回該頁面指標。
void BufMgr::disposePage(File *file, const PageId PageNo) { FrameId frame; try { hashTable->lookup(file, PageNo, frame); hashTable->remove(file, PageNo); bufDescTable[frame].Clear(); } catch (HashNotFoundException &) { } file->deletePage(PageNo); }
刪除一個頁面。如果它在緩衝池中,要將緩衝內容一併刪除。
12個樣例均能通過,實驗結果如下:
me].Clear(); } catch (HashNotFoundException &) { } file->deletePage(PageNo); }
刪除一個頁面。如果它在緩衝池中,要將緩衝內容一併刪除
到此這篇關於C++實現頁面的緩衝區管理器的文章就介紹到這了,更多相關C++緩衝區管理器內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45