欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實(shí)現(xiàn)頁面的緩沖區(qū)管理器

 更新時間:2022年08月01日 16:16:58   作者:biyezuopinvip  
這篇文章主要介紹了C++實(shí)現(xiàn)頁面的緩沖區(qū)管理器,文章圍繞主題展開詳細(xì)的內(nèi)容介紹具有一定的參考價值,需要的小伙伴可以參考一下

1. 實(shí)驗(yàn)?zāi)繕?biāo)

本次實(shí)驗(yàn)要實(shí)現(xiàn)一個頁面的緩沖區(qū)管理器。

具體要實(shí)現(xiàn)以下的函數(shù):

~BufMgr():

清除所有臟頁并釋放緩沖池和 BufDesc 表

void advanceClock():

用來找到下一個時鐘的位置

void allocBuf(FrameId& frame):

使用時鐘算法分配自由幀;如有必要,將臟頁寫回磁盤。

void readPage(File* file, const PageId PageNo, Page*& page)

通過調(diào)用 lookup()方法檢查頁是否已經(jīng)在緩沖池中。當(dāng)頁不在緩沖池中可以在哈希表上拋出 HashNotFoundException 以獲取幀編號。

void unPinPage(File* file, const PageId PageNo, const bool dirty)

減少一個頁面的占用次數(shù)

void allocPage(File* file, PageId& PageNo, Page*& page)

通過調(diào)用 file->allocatePage()方法在指定的文件中分配一個空頁。此方法將返回新分配的頁。然后調(diào)用 allocBuf()以獲取緩沖池幀。接下來,將一個條目插入到哈希表中,并在幀上調(diào)用 Set(),以正確設(shè)置它。

void disposePage(File* file, const PageId pageNo)

功能是釋放一個頁面

void flushFile(File* file)

功能是找到含有對應(yīng)文件的頁面,并釋放

2. 代碼實(shí)現(xiàn)

BufMgr::~BufMgr() {
    delete hashTable;
    delete[] bufPool;
    delete[] bufDescTable;
}

直接調(diào)用 delete 刪除哈希表、緩沖池、緩沖池表

void BufMgr::advanceClock() {
    clockHand++;
    if (clockHand >= numBufs) {
        clockHand %= numBufs;
    }
}

將時鐘提前到緩沖池的下一幀。

如果指針超過了最大值,進(jìn)行取模操作。

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;
    }
}

遍歷棧區(qū)尋找可用的頁面。如果是沒有被使用過的頁面,直接進(jìn)行分配。如果緩沖區(qū)所有的頁面都被占用,那么會進(jìn)行報錯 BufferExceededException()。如果找到臟頁,會將它寫回磁盤,并將臟頁標(biāo)記給清除。如果不是臟頁,那么就進(jìn)行分配操作。如果它在哈希表中要將它移除。

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);
    }
}

如果頁面在緩沖池中,增加它的占用次數(shù),調(diào)用 page 返回指向該頁面的指針。

如果頁面不在緩沖池中,那么將頁面讀取到緩沖池,插入哈希表中,調(diào)用 set 正確設(shè)置該界面,調(diào)用 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);
    }
}

如果緩沖池中沒有該頁面,進(jìn)行異常提示。

如果在緩沖池中,那么將它的占用次數(shù)減少。如果占用次數(shù)為 0,進(jìn)行報錯。

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();
        }
    }
}

遍歷整個表,找到含有對應(yīng)頁面的緩沖頁,移除并清空該頁面。如果頁面是臟頁,則將其寫回磁盤,初始化臟頁標(biāo)記。如果頁面被占用或者頁面不可用,則進(jìn)行報錯。

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()分配一個新頁面,加入哈希表,調(diào)用 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);
}

刪除一個頁面。如果它在緩沖池中,要將緩沖內(nèi)容一并刪除。

3.實(shí)驗(yàn)結(jié)果

12個樣例均能通過,實(shí)驗(yàn)結(jié)果如下:

me].Clear();
} catch (HashNotFoundException &) {
}
file->deletePage(PageNo);
}

刪除一個頁面。如果它在緩沖池中,要將緩沖內(nèi)容一并刪除

到此這篇關(guān)于C++實(shí)現(xiàn)頁面的緩沖區(qū)管理器的文章就介紹到這了,更多相關(guān)C++緩沖區(qū)管理器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用C++中的ADO對SQLite進(jìn)行增刪改查

    使用C++中的ADO對SQLite進(jìn)行增刪改查

    本文將介紹如何使用C++的ADO (ActiveX Data Objects)對SQLite數(shù)據(jù)庫進(jìn)行增刪改查操作,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-06-06
  • C++使用一棵紅黑樹同時封裝出map和set實(shí)例代碼

    C++使用一棵紅黑樹同時封裝出map和set實(shí)例代碼

    紅黑樹(Red?Black?Tre)是一種自平衡二叉查找樹,是在計(jì)算機(jī)科學(xué)中用到的一種數(shù)據(jù)結(jié)構(gòu),典型的用途是實(shí)現(xiàn)關(guān)聯(lián)數(shù)組,下面這篇文章主要給大家介紹了關(guān)于C++使用一棵紅黑樹同時封裝出map和set的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Qt中const?QString轉(zhuǎn)換?char?*可能的坑

    Qt中const?QString轉(zhuǎn)換?char?*可能的坑

    本文主要介紹了Qt中const?QString轉(zhuǎn)換?char?*可能的坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • c++ 智能指針基礎(chǔ)詳解

    c++ 智能指針基礎(chǔ)詳解

    這篇文章主要介紹了c++ 智能指針基礎(chǔ)的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下
    2021-02-02
  • 深入了解C語言指針

    深入了解C語言指針

    這篇文章主要介紹了C語言指針詳解及用法示例,介紹了其相關(guān)概念,然后分享了幾種用法,具有一定參考價值。需要的朋友可以了解下
    2021-07-07
  • C++ vector的用法小結(jié)

    C++ vector的用法小結(jié)

    這篇文章主要介紹了c++中,vector是一個十分有用的容器,下面對這個容器做一下總結(jié)
    2013-12-12
  • C/C++?Qt?MdiArea?多窗體組件應(yīng)用教程

    C/C++?Qt?MdiArea?多窗體組件應(yīng)用教程

    MDI窗體控件類似于畫布,該控件只具備展示窗體的功能,無法實(shí)現(xiàn)生成窗體,所以我們需要在項(xiàng)目中手動增加自定義的Dialog對話框,并對該對話框進(jìn)行一定的定制,這篇文章主要介紹了C/C++?Qt?MdiArea?多窗體組件應(yīng)用,需要的朋友可以參考下
    2021-12-12
  • C++如何調(diào)用已經(jīng)寫好的C接口

    C++如何調(diào)用已經(jīng)寫好的C接口

    如何在C++代碼中調(diào)用寫好的C接口?你可能會奇怪,C++不是兼容C嗎?直接調(diào)用不就可以了,那么我們來測試一下,先看看C++如何調(diào)用C代碼接口的,需要的朋友可以參考一下
    2021-10-10
  • vs2019中使用MFC構(gòu)建簡單windows窗口程序

    vs2019中使用MFC構(gòu)建簡單windows窗口程序

    今天發(fā)現(xiàn)網(wǎng)上好多MFC代碼都不能用,給大家分享一個簡單的MFC窗口語言,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言實(shí)現(xiàn)自動發(fā)牌程序

    C語言實(shí)現(xiàn)自動發(fā)牌程序

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)自動發(fā)牌程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評論