中科大研究生高级数据库实验报告,用LRU算法实现buffermanager,模拟数据库对记录的处理过程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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否满)。并读下一条记录。

相关文档
最新文档