数据库作业要求

存储和缓冲管理

实验目的

实现一个简易的存储和缓冲管理器


缓冲区和页面

缓冲区Buffer代表了在主存中的空间
缓冲区由frame组成
frame由下面的数据结构表示

#define FRAMESIZE 4096
    struct bFrame{
        Char field[FRAMESIZE];
    };

缓冲区buffer数组(array)会存储一系列frame(存储已装载的page),这个array如下所示:

    #define DEFBUFSIZE 1024
    bFrame buf[DEFBUFSIZE]

页面Page格式

在这个项目中,我们不需要提及page的具体结构。只关心页面id和页面大小,所以不需要设计页面格式。

文件File格式

我们建议使用基于目录的结构区组织数据库文件。每个文件都有一个起始页(它包含了指向文件所有页的指针),使用基于目录的好处在于当指定某一个特定页面时,这样更加快捷。

缓冲技术(Buffer Technique)

我们选择LRU作唯一的置换算法,好处自然不必多说

哈希技术(Hashing Technique)

对于缓冲中的每个frame,都必须要有一个BCB被保存(buffer control block)。它包含了一个page_id,frame_id,fix_count,dirty_bit.
两个哈希表需要被保存,第一个是page_id对应frame_id和BCB,第二个是frame_id对应page_id.
我们建议使用简单的静态哈希技术。
哈希函数会像是
H(K)=(page_id)%buffer_size
对于page_id到BCB的哈希表会像是:BCB hTable[BufferSize]
对于frame_id到page_id的哈希表会像是:int hTable[BufferSize]

struct BCB{
    BCB();
    int page_id;
    int frame_id;
    int count;
    int dirty;
    BCB *next;
};

文件存储

在此项目中,我们只需要磁盘上的一个物理文件,所有数据库中的数据都会存在这一个文件中,命名为data.dbf.

类设计

数据存储管理类
class DSMgr{
    public:
        DSMgr();
        int OpenFile(String filename);
        int CloseFile();
        bFrame ReadPage(int page_id);
        int WritePage(int frame_id, bFrame frm);
        int Seek(int offset, int pos);
        FILE * GetFile();
        void IncNumPages();
        int GetNumPages();
        void SetUse(int index, int use_bit);
        int GetUse(int index);
    private:
        FILE *currFile;
        int numPages;
        int Pages[MAXPAGES];
}
缓冲区管理
class BMgr{
    public:
        BMgr();
        int FixPage(int page_id, int prot);
        void NewPage FixNewPage();
        int UnfixPage(int page_id);
        int NumFreeFrames();
        int SelectVictim();
        int Hash(int page_id);
        void RemoveBCB(BCB * ptr,int page_id);
        void RemoveLRUEle(int frid);
        void SetDirty(int frame_id);
        void UnsetDirty(int frame_id);
        void WriteDirtys();
        PrintFrame(int frame_id);
    private:
        int ftop[DEFBUFSIZE];
        BCB * ptof[DEFBUFSIZE];
}

对类中函数的解释(顶奥)

缓冲类接口函数

  • FixPage(int page_id,int prot)

    原型FixPage(Page_id,protection),返回一个frame_id.这个函数是为了判断页面是否存在于缓冲区,并返回对应的frame_id;如果这个页面并不在缓冲区内,它会选择一个victim page(牺牲页?),如果需要的话,将它载入。

  • FixNewPage()

    原型FixNewPage(),返回一个page_id和frame_id。这个函数在插入(索引分割、对象创建)时,需要一个新页面。这个函数会找到一个空页面供上层使用。

  • UnfixPage(int page_id)

    原型UnfixPage(int page_id),返回一个frame_id.这个函数是前两个函数的补足。这个函数会消耗frame上的fix count,如果count减少至0,如果被选中的话这个frame可以被移除,page_id 变换成frame_id,并且可以被选成牺牲页,如果该页面上的count已经降低至0.

  • NumFreeFrames()

    这个函数查看缓冲区,返回缓冲区中可以被使用的页面的个数

  • SelectVictim()

    这个函数选择一个frame被取代。如果被选择frame的dirty位已经被置,那么这个页面需要被写回磁盘。

  • Hash(int page_id)

    返回frame_id

  • RemoveBCB(BCB *ptr, int page_id)

    这个函数根据page_id从数组中移除BCB。仅当SelectVictim()函数需要替换一个frame。

  • RemoveLRUEle(int frid)

    从列表中移除LRU元素???

  • SetDirty(int frame_id)

    设置frame_id的脏位。脏位是用来知道是否要将frame写出。bit=1->will be written,otherwise will not be written

  • UnsetDirty(int frame_id)

    设置frame_id的脏位为0.当setDirty函数被调用,但是该页面在当前还有联系,在这种情况下,该页面不需要被写回,因为他不想现在被保存。

  • WriteDirtys()

    这个函数只有当系统关机时调用,这个函数将会把所有脏位为1的页面写回内存

  • PrintFrame(int frame_id)

    根据frame_id打印frame内容


数据存储类接口函数

  • OpenFile(string filename)

    任何时间,当一个文件需要被读或者写,根据文件名打开文件

  • CloseFile()

    当数据文件需要被关闭调用

  • ReadPage(int page_id)

    被缓冲区管理的FixPage调用,返回他已经读到的内容。这个函数调用fseek()和fread()去从一个文件中获取数据

  • WritePage(int frame_id, bFrame frm)

    每当一个页面从缓冲区中调出,这个函数就会被调用。返回已经写了多少字节,这个函数采用fseek和fwrite往file里写文件

  • Seek(int offset, int pos)

    移动文件指针

  • GetFile

    获取当前文件

  • IncNumPages()

    增加page计数

  • GetNumPages()

    返回page计数

  • SetUse(int page_id, int use_bit)

    有个数组保存被使用的页面,这个函数设置指定页面的被使用位

  • GetUse(int page_id)

    返回指定page_id的使用位


我们会提供50,000个页面,每个页面索引从0-49,999.每个记录格式像是“x,###”,这里x是0(读)或者1(写),###代表指代的编号。
要求扫描trace记录表,然后打印主存和磁盘间总的IO次数。实验一开始时缓冲区为空.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值