中科大研究生高级数据库实验报告,用LRU算法实现buffermanager,模拟数据库对记录的处理过程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据库实现技术实验报告
SC11011042吴**源代码获取请联系:email:wude_yun@
wdyun@
一、实验目的
为了了解数据库buffer管理器的工作原理,对数据库底层结构有更进一步的了解,我们将实现一个简单的存储和缓冲管理器。该实验涉及的存储和缓冲管理器,缓冲技术,散列技术,文件存储结构,磁盘空间和缓冲模块的接口功能。
二、实验环境
硬件平台:LENOVO ThinkPad E425
软件平台:开发系统:win7
开发工具:eclipse
开发语言:java
JDK版本jdk1.6
三、实验内容
1、相关数据结构描述
BCB类
1)1)BCB
BCB类的属性如下所示:
public class BCB{
private int page_id;//文件号
private int frame_id;//存放文件号的buffer地址的下标
private int latch;//锁
private int count;//计数器
private int dirty;//是否脏,修改过
private BCB next;//下一个bcb链
……
}
BCB类主要是实现快速的查找功能,既查找给定的文件号是否在缓存中。查找给定的文件号是否在缓存中,一种比较简单的方法是遍历整个buffer,但是这样势必浪费时间。因为整个记录的数目为50万条,buffer空间为1024。那么对所有的记录查找是否在buffer中就需要50万×1024≈5亿次。如果用BCB数组(类似一个十字链表的结构)Hash划分对每个文件号查找平均次数1(假设是平均划分,即使不是平均划分其平均查找次数远远小于1024
次),对所有的记录的查找只要5万次,明显要快。
BCB类具体包含的属性及方法的UML如图1所示。
图1BCB的UML结构
2)BufferManager与LRU类
BufferManager类的属性如下所示:
public class BufferManager{
public static final int DEFBUFSIZE=1024;
private int[]ftop;//对应buffer的号中存放frame_id
private BCB[]ptof;//Hash Table
private LRU lru;//lru类管理替换规则
private int freeBuffer;//用于表示空闲的buffer的下标
public BufferManager(){
super();
this.ftop=new int[this.DEFBUFSIZE];
this.ptof=new BCB[this.DEFBUFSIZE];
this.initialFtop();
this.intialPtof();
lru.intial();
}
……
}
其中LRU类为实现当buffer满了时,使用LRU算法替换buffer。LRU类的属性如下所示:
public class LRU{
private Note head;
class Note{
private int bufNumber;//buffer的下标
private Note next;//后驱
private Note front;//前驱
}
public Note intial(){
//只申请1个空间
head=new Note();
head.front=head;
head.next=head;
return head;
}
……
}
LRU类包含一个head引用(类似c语言的指针)指示LRU链表的头,表示当前刚刚使用过的buffer地址。Note类是LRU的内部类,其实就相当于实现c语言的结构体,用于表示LRU链表的内部节点,将链表表示成一个双向循环链表。用双向循环链表实现LRU算法的好处是算法实现很简单。head引用所指向的节点是当前刚刚使用的节点,head的next 指向的节点是将要替换的节点。
LRU类包含一个初始化函数intial()初始化LRU类,LRU类只有一个节点。这里需要指出不一次性生成1024个节点(或者说是buffersize大小的节点数)好处在于当buffer 未满时,如果page_id在buffer中既已命中,这时需要调整更新LRU链表,将命中的存有page_id的buffer调到head指向的节点的前面,调换两个节点的次序即可;否则如果生成1024个节点,由于此时buffer未满,则肯定有空的LRU节点,因此将命中的存有page_id的buffer 调到head指向的节点的前面,势必要调整整个链表。
BufferManager与LRU类及其之间的关系的UML如图2所示。
图2BufferManager与LRU类及其之间的关系的UML
DataStorageManager类
3)3)DataStorageManager
DataStorageManager类的属性如下所示:
public class DataStorageManager{
private BufferManager buffer;
private int ioCount;//io次数
private int hitCount;//lru命中次数
……
}
DataStorageManager类主要要是实现读取文件记录实现整个buffer管理。包含一个BufferManager类的成员变量buffer用于实现缓存的管理,ioCount表示整个I/O的次数,hitCount记录命中次数。DataStorageManager类的UML与其他类之间的关系如图3所示。
图3DataStorageManager类的UML与其他类之间的关系
2、算法描述及流程图
先依次读入所给测试文档里面的数据,然后按行依次处理每个命令,循环执行如下:判断是文件号是否已存在于缓存中,是则在ptob数组中修改该页对应的BCB参数,并同时找出该页在双向链表head中的位置,插到首位。读下一条记录。
若不存在I/O次数加1。并判断buffer是否已满,如果未满,在双向链表head首部插入新节点,并同时在ftop数组添加该页映射;如果满用LRU算法选择一个替换的buffer地址(将head移到下一个节点),在ftop数组中找到替换的oldpage_id,删除ptob数组中旧的oldpage_id节点,在ftop数组添加该页映射。最后将该页相关信息插入ptob数组中(不管是buffer否满)。并读下一条记录。