这一块是在助教给的参考代码的基础上进行了一些小范围的修改。
感觉最麻烦的是一个是文件的管理。一开始认定一定要(读一行表示一块),发现这样的话要循环调用getline这个函数,感觉并没有达到好的一个效率。后来查找了蛮多资料然后才熟悉了具体的存储方法……因为写的文件会用txt打开,无法显示的内容都会以为丢失了。
这一块我和写record的同学协商之后打算用强制类型转换的方法来读写,就是,比如int和float都是4个字节,就用四个字节的char来表示,相当于256进制。然后在后期拼合代码的时候……发现如果用这种方法来记录的话,字符串什么的类型都没法用了因为,默认0是字符串的结尾。所以后来扩充了那个类型,为了代码的容易理解最后是,用5个字节来表示int(所以int没法完全表达,比如负数和五位以上的正数)和8个字节表示float(128进制,这样可以避开之前让我们困扰的0的问题而且让大部分落在’可见’也就是能显示的区域)。
有些问题还是集中在个人的水平上,比如,因为内存分配什么的出过很多问题……
还是需要协调……比如说,我的buffer这一块需要建立的文件节点的链表,在队友写的时候是有一个头节点,而我是直接用第一个文件的节点,这样的话在释放的时候可能会有未考虑到的部分。(所以总觉得该用C++啊摔)。而且好像我写的两块独立测试都比较麻烦……而且测试看不出来……
一、BufferManager负责缓冲区的管理,主要功能有:
1. 根据需要,读取指定的数据到系统缓冲区或将缓冲区中的数据写出到文件;
2. 实现缓冲区的替换算法,当缓冲区满时选择合适的页进行替换;
3. 记录缓冲区中各页的状态,如是否被修改过等;
4. 提供缓冲区页的pin功能,及锁定缓冲区的页,不允许替换出去。
为提高磁盘I/O操作的效率,缓冲区与文件系统交互的单位是块,块的大小应为文件系统与磁盘交互单位的整数倍,一般可定为4KB或8KB。
二、模块总体设计思路
记录管理模块(RecordManager)和索引管理模块(IndexManager)向缓冲区管理申请所要的数据,缓冲区管理器首先在缓冲区中查看数据是否存在,若存在,直接返回,否则,从磁盘中将数据读入缓冲区,然后返回。
最近最少使用(LRU)算法:每次访问一个块的时候,如果是重新读取的话把该块的iTime置为1,如果是已经有的话把它的使用次数加一。采用这种方式记录主要是因为对于Index部分,比如根节点的使用率一直保持非常高。
换出脏块时需要写出块。
三、具体实现
1、宏
#defineBLOCK_LEN 4096 // the size of one block
#defineMAX_BLOCK 40 // the max number of the blocks
2、结构体
1)、文件头结构体(structfileInfo) :
包含文件的基本信息:类型(数据文件或索引文件)、文件名、记录数、空块号、记录长度、指向下一个文件的指针、文件所指向的第一个块。
structfileInfo {
int type; //0-> data file, 1 -> index file
CString fileName; // the name of the file
int recordAmount; // the number of record in the file
int freeNum; // the free block number which could be used for thefile
int recordLength; // the length of the record in the file
fileInfo *next; // the pointer points to the next file
blockInfo *firstBlock; // point to the first block within the file
};
2)、块信息结构体(struct blockInfo):
包含块的基本信息:块号、脏位、指向下一个块的指针、块中的字符数、存放信息的字符型数组、年龄(用于LRU算法)、锁。
struct blockInfo {
intblockNum; // the block number of theblock,
// which in