Buffer.h
资源名称:minisqlc.rar [点击查看]
上传用户:lkd6667
上传日期:2015-05-13
资源大小:1448k
文件大小:12k
源码类别:
其他数据库
开发平台:
C/C++
- #ifndef _BUFFER_H_
- #define _BUFFER_H_
- //-------------------------------------------------------
- extern "C"{
- #include <io.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <string.h>
- };
- //-------------------------------------------------------
- #define FILE_PAGESIZE 4096 // 内存页大小
- #define MEM_PAGEAMOUNT 1000 // 内存页数量
- #ifndef MAX_FILENAME_LEN
- #define MAX_FILENAME_LEN 256 // 文件(包含路径)最大长度
- #endif
- //-------------------------------------------------------
- /*********************************************************
- * 页头信息,用以标识文件页
- **********************************************************/
- typedef struct {
- unsigned long ulPageID; // 页编号
- bool bIsFixed; // 页是否常驻内存
- void Initial(unsigned long mypageid,bool myisfixed); // 初始化操作
- }_TB_PAGEHEAD;
- //-------------------------------------------------------
- /*********************************************************
- * 文件内地址(相当于内存地址),用以标识数据在文件中
- * 的具体存放地址,做为对象可持续化的一个重要一环,通
- * 过调用其中的MemAddr()方法可以得到数据在内存中的地址
- * 是整个buffer模块成功与其他模块整合的关键
- **********************************************************/
- class _F_FileAddr{
- public:
- unsigned long ulFilePageID; // 页编号
- unsigned int uiOffset; // 页内偏移量
- // char Status; //当前地址状态为使用和删除statu=('u','l')如果有遍历整个文件功能时加,始化为'u'
- void Initialize(); // 初始化 (0,0)
- //**根据页编号和偏移量,取出当前文件该地址在内存中的地址,同时测试页偏移量是否溢出
- void* MemAddr() const;
- //**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
- void* MemAddr(class _M_File&) const;
- //**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
- void* MemAddr(class _M_File*) const;
- bool operator>=(_F_FileAddr& other) const; // _F_FileAddr >= 操作
- bool operator> (_F_FileAddr& other) const; // _F_FileAddr > 操作
- bool operator==(_F_FileAddr& other) const; // _F_FileAddr == 操作
- bool operator!=(_F_FileAddr& other) const; // _F_FileAddr != 操作
- bool operator==(const int zero) const; // _F_FileAddr == 操作
- //**在当前页中滑动offset量(可正可负)
- void ShiftOffset(int offset);
- };
- //-------------------------------------------------------
- /*********************************************************
- * 文件头信息
- **********************************************************/
- typedef struct{
- _F_FileAddr DelFirst; // 第一条被删除记录地址
- _F_FileAddr DelLast; // 最后一条被删除记录地址
- _F_FileAddr NewInsert; // 文件末尾可插入新数据的地址
- unsigned long ulPageTotal; // 目前文件中共有页数
- void InitialFileCond(); // 初始化
- }_TB_FILECOND;
- //-------------------------------------------------------
- /*********************************************************
- * 内存页,用以从文件中读取页和往文件中写回页
- * 同时也提供页头信息等相关信息
- **********************************************************/
- class _M_Page{
- friend class _M_PageInfo;
- friend class _F_FileAddr;
- friend class _M_Clock;
- private:
- unsigned int uiFileID; // 所属文件编号(程序动态分配)
- unsigned long ulFilePageID; // 在文件中的PageID
- void* Ptr2PageBegin; // 调入内存后的页首地址
- _TB_PAGEHEAD* Ptr2Head; // 页头信息
- _TB_FILECOND* Ptr2FileCond(); // 文件头信息(若页PageID==0,则有,否则返回空)
- _M_Page(); // 成员初始化,开辟内存空间
- ~_M_Page(); // 释放内存空间
- //**从文件中调入页至开辟好的内存空间中
- void LoadFromFile(unsigned int fileid,unsigned long filepageid);
- //**把内存中的页写回到文件中
- void Back2File() const;
- };
- //-------------------------------------------------------
- /*********************************************************
- * 内存页管理信息,用以管理内存页的开辟,释放等
- * 之所以和内存页类分开,为在不必要的情况下可以
- * 避免开辟内存页,减少内存的浪费
- **********************************************************/
- class _M_PageInfo{
- friend class _M_Clock;
- friend class _F_FileAddr;
- friend class _M_Buffer;
- private:
- bool bIsLastUsed; // 最近一次访问内存是否被使用,用于Clock算法
- bool bIsModified; // 从调入内存开始,是否被修改,用于决定是否需要写会文件
- class _M_Page* Ptr2Page; // 所分配的内存页对象
- _M_PageInfo(); // 成员初始化
- ~_M_PageInfo(); // 析构,根据bIsModified决定是否需要写会文件
- void UpdatePageInfo(unsigned int fileid,unsigned long filepageid); // 页替换、开辟等
- _TB_PAGEHEAD* GetPtr2Head() const; // 取得页头信息地址
- _TB_FILECOND* GetPtr2FileCond() const; // 取得文件头信息地址
- unsigned int GetFileID() const; // 取得所分配的内存页目前内容所属的文件编号
- void SetFileID(unsigned int fileid); // 设置新的文件编号(抛弃页时设为0即可)
- unsigned long GetFilePageID() const; // 取得所分配的内存页目前内容在文件中的页编号
- };
- //------------------------------------------------------------
- /*********************************************************
- * 内存页置换算法实现类,采用Clock算法
- * 开辟内存页管理对象数组,每个内存页管
- * 理对象对应一个内存页对象,需要的时候
- * 才开辟,避免内存的浪费
- **********************************************************/
- class _M_Clock
- {
- friend class _M_Buffer;
- friend class _M_File;
- friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
- private:
- unsigned int uiClockSize; // 内存中页总数,即Clock钟点总数
- unsigned int uiCurrClockPtr; // 目前正在使用的内存页
- class _M_PageInfo* Ptr2MemPageInfo[MEM_PAGEAMOUNT+1]; // 内存页管理对象(不包含内存页空间)
- _M_Clock(); // 成员初始化
- ~_M_Clock(); // 析构
- void SetPageModified(); // 设置当前页使之为脏页
- void CloseFilePages(unsigned int fileid); // 关闭文件并抛弃所属内存页(适用于欲删除一个文件的时候)
- unsigned int GetNullPage(); // 查找Clock中尚未分配内存空间的页
- unsigned int GetFreePage(); // 查找Clock中已经被抛弃的页
- unsigned int GetSwapPage(unsigned int fileid); // 查找Clock中最近一页可被替换的页
- // 查找Clock中最早打开的文件所占用的内存页,如果是常驻内存页则关闭该文件(该写回的写回)
- // 所有打开的文件已经由_M_Buffer类组织成链表
- unsigned int NR_Search(unsigned int tarfileid);
- // Clock算法实现,通过U_M_Search()四次调用,完成Clock算法
- unsigned int U_M_Search(bool islastused,bool ismodified,bool changeused);
- // 查找已经存在的页(假设要找的页已经存在的话)
- unsigned int GetExsitPage(unsigned int fileid,unsigned long filepageid);
- // 根据文件编号和页号取得内存页(通过上面各种方法)
- _M_PageInfo* GetTargetPage(unsigned int fileid,unsigned long filepageid);
- };
- //-------------------------------------------------------
- /*********************************************************
- * 内存文件类,与其他模块的主要接口,将
- * 通过此类得到欲访问文件中的数据的内存首地址
- **********************************************************/
- class _M_File{
- friend class _M_Buffer;
- friend class _F_FileAddr;
- friend class _M_Clock;
- friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
- private:
- unsigned int uiFileID; // 文件编号
- unsigned long ulPageTotal; // 目前文件总的页数
- bool IsNew; // 该文件是否新建
- char FileName[MAX_FILENAME_LEN]; // 文件名称(包含路径)
- _M_File* _F_Next; // 下一个打开的文件
- int Ptr2File; // 文件指针
- void Deconstruct(); // 析构,关闭文件
- _M_PageInfo* GetPageInfo(unsigned long filepageid) const; // 根据页号取得属于该文件的内存页
- // 初始化,打开和新建文件,若当前文件开的太多,导致无法再打开新文件,可自动关闭最早打开的文件
- _M_File(const char *name,unsigned int fileid);
- // 取得相关文件,由于一个表包含两个文件(.idx,.dbf),故查找关联的文件编号
- unsigned int GetRelativeFileID() const;
- public:
- _F_FileAddr GetCataPoint() const; // 取得Catalog模块在文件中可写的第一个位置
- _F_FileAddr GetIdxPoint() const; // 取得Catalog模块在文件中可写的第一个位置
- _F_FileAddr GetDelListCond() const; // 取得文件内记录删除维护信息
- unsigned long GetPageTotal() const; // 取得目前总的页数
- // 关闭文件,同时属于该文件的内存页改写回的写回.为保证一致性,同时关闭关联文件
- void Close();
- };
- //-------------------------------------------------------
- /*********************************************************
- * Buffer模块管理类,包含两部分数据的管理
- * 一、内存页的管理,通过一个_M_Clock对象实现
- * 二、打开文件的管理,组织所有的文件
- **********************************************************/
- class _M_Buffer{
- friend class _M_Page;
- friend class _M_PageInfo;
- friend class _M_File;
- friend class _M_Clock;
- friend class _F_FileAddr;
- friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
- friend _F_FileAddr MemWriteTest(size_t,_F_FileAddr*);
- private:
- unsigned int uiFileCount; // 打开文件总数
- _M_File* _F_First; // 第一个文件
- _M_File* _F_Last; // 最后一个文件
- _M_File* _F_Current; // 当前使用文件
- class _M_Clock* MemPageClock; // Clock算法实现类(管理所有内存页)
- _M_File* operator[](unsigned int fileid) const; // 根据文件编号返回内存文件对象
- void CloseFile(unsigned int fileid); // 根据文件编号关闭内存文件对象
- void CloseTable(unsigned int fileid); // 根据文件编号关闭内存文件对象及其关联内存文件对象
- bool GetIsNew(unsigned int fileid) const; // 根据文件编号返回内存文件对象是否为新建
- void SetIsNew(unsigned int fileid,bool isnew); // 根据文件编号设置内存文件对象是否为新建
- unsigned long GetPageTotal(unsigned int fileid) const; // 根据文件编号返回内存文件对象总页数
- void AddPageTotal(unsigned int fileid,int add); // 根据文件编号色设置内存文件对象的总页数
- int GetPtr2File(unsigned int fileid) const; // 根据文件编号返回内存文件对象的文件指针
- public:
- _M_File operator[](const char* filename); // 根据文件名称返回内存文件对象
- void Start(); // Buffer初始化
- void End(); // Buffer结束,写回内存页,关闭文件
- };
- //-------------------------------------------------------
- /*****************************************************************
- ** 函数名: MemWrite
- ** 输 入: const void*,size_t,_F_FileAddr*
- ** const void* --- 欲写入buffer的对象(数据)的内存地址
- ** size_t --- 数据总长度
- ** _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
- 况下,将自动修正为最终写入文件的地址
- ** 输 出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
- ** 功能描述: 根据欲写入的文件地址,把其他模块内存中的数据写
- 入buffer中,最终自动写入文件中
- ** 全局变量: 无
- **********************************************************/
- _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
- //-------------------------------------------------------
- /*****************************************************************
- ** 函数名: MemWriteTest
- ** 输 入: const void*,size_t,_F_FileAddr*
- ** const void* --- 欲写入buffer的对象(数据)的内存地址
- ** size_t --- 数据总长度
- ** _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
- 况下,将自动修正为最终写入文件的地址
- ** 输 出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
- ** 功能描述: 根据欲写入的文件地址,测试把其他模块内存中的数据写入
- 实际未写入。用于当整个数据对象不能跨快写的时候又不能
- 一次写入(如链表结构(各字段)的一条记录,在内存中不连
- 续)的场合。
- *****************************************************************/
- _F_FileAddr MemWriteTest(size_t,_F_FileAddr*);
- //-------------------------------------------------------
- #endif //define _BUFFER_H_
- //-------------------------------------------------------
- //-------------------------------------------------------