Buffer.h
上传用户:lkd6667
上传日期:2015-05-13
资源大小:1448k
文件大小:12k
源码类别:

其他数据库

开发平台:

C/C++

  1. #ifndef _BUFFER_H_
  2. #define _BUFFER_H_
  3. //-------------------------------------------------------
  4. extern "C"{
  5. #include <io.h>
  6. #include <fcntl.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. };
  10. //-------------------------------------------------------
  11.  
  12. #define FILE_PAGESIZE 4096 // 内存页大小
  13. #define MEM_PAGEAMOUNT 1000 // 内存页数量
  14. #ifndef MAX_FILENAME_LEN
  15. #define MAX_FILENAME_LEN    256 // 文件(包含路径)最大长度
  16. #endif
  17. //-------------------------------------------------------
  18. /*********************************************************
  19. *            页头信息,用以标识文件页
  20. **********************************************************/
  21. typedef struct {
  22. unsigned long ulPageID; // 页编号
  23. bool bIsFixed; // 页是否常驻内存
  24.     void Initial(unsigned long mypageid,bool myisfixed); // 初始化操作
  25. }_TB_PAGEHEAD;
  26. //-------------------------------------------------------
  27. /*********************************************************
  28. *     文件内地址(相当于内存地址),用以标识数据在文件中
  29. *     的具体存放地址,做为对象可持续化的一个重要一环,通
  30. *     过调用其中的MemAddr()方法可以得到数据在内存中的地址
  31. *     是整个buffer模块成功与其他模块整合的关键
  32. **********************************************************/
  33. class _F_FileAddr{
  34. public:
  35. unsigned long ulFilePageID;     // 页编号
  36.     unsigned int  uiOffset;         // 页内偏移量
  37. // char Status;  //当前地址状态为使用和删除statu=('u','l')如果有遍历整个文件功能时加,始化为'u'
  38.     void Initialize();              // 初始化 (0,0)
  39.     //**根据页编号和偏移量,取出当前文件该地址在内存中的地址,同时测试页偏移量是否溢出
  40.     void* MemAddr() const;          
  41.     //**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
  42. void* MemAddr(class _M_File&) const;
  43.     //**根据页编号和偏移量,取出文件该地址在内存中的地址,同时测试页偏移量是否溢出
  44.     void* MemAddr(class _M_File*) const;
  45.     bool operator>=(_F_FileAddr& other) const; // _F_FileAddr >= 操作
  46. bool operator> (_F_FileAddr& other) const; // _F_FileAddr >  操作
  47.     bool operator==(_F_FileAddr& other) const; // _F_FileAddr == 操作
  48. bool operator!=(_F_FileAddr& other) const; // _F_FileAddr != 操作
  49. bool operator==(const int zero) const;     // _F_FileAddr == 操作
  50.     //**在当前页中滑动offset量(可正可负)
  51.     void ShiftOffset(int offset);              
  52. };
  53. //-------------------------------------------------------
  54. /*********************************************************
  55. *               文件头信息
  56. **********************************************************/
  57. typedef struct{
  58.     _F_FileAddr DelFirst;             // 第一条被删除记录地址
  59.     _F_FileAddr DelLast;              // 最后一条被删除记录地址  
  60.     _F_FileAddr NewInsert;            // 文件末尾可插入新数据的地址
  61.     unsigned long ulPageTotal;        // 目前文件中共有页数
  62.     void InitialFileCond();           // 初始化
  63. }_TB_FILECOND;
  64. //-------------------------------------------------------
  65. /*********************************************************
  66. *            内存页,用以从文件中读取页和往文件中写回页
  67. *            同时也提供页头信息等相关信息
  68. **********************************************************/
  69. class _M_Page{
  70. friend class _M_PageInfo;
  71. friend class _F_FileAddr;
  72. friend class _M_Clock;
  73. private:
  74. unsigned int  uiFileID;        // 所属文件编号(程序动态分配)
  75. unsigned long ulFilePageID;     // 在文件中的PageID
  76. void* Ptr2PageBegin;            // 调入内存后的页首地址
  77. _TB_PAGEHEAD* Ptr2Head;         // 页头信息
  78.     _TB_FILECOND* Ptr2FileCond();   // 文件头信息(若页PageID==0,则有,否则返回空)
  79. _M_Page();                      // 成员初始化,开辟内存空间
  80. ~_M_Page();                     // 释放内存空间
  81.     //**从文件中调入页至开辟好的内存空间中
  82. void LoadFromFile(unsigned int fileid,unsigned long filepageid);
  83.     //**把内存中的页写回到文件中
  84. void Back2File() const;
  85. };
  86. //-------------------------------------------------------
  87. /*********************************************************
  88. *            内存页管理信息,用以管理内存页的开辟,释放等
  89. *            之所以和内存页类分开,为在不必要的情况下可以
  90. *            避免开辟内存页,减少内存的浪费
  91. **********************************************************/
  92. class _M_PageInfo{
  93. friend class _M_Clock;
  94. friend class _F_FileAddr;
  95. friend class _M_Buffer;
  96. private:
  97. bool bIsLastUsed;             // 最近一次访问内存是否被使用,用于Clock算法
  98.     bool bIsModified;             // 从调入内存开始,是否被修改,用于决定是否需要写会文件
  99. class _M_Page* Ptr2Page;      // 所分配的内存页对象
  100. _M_PageInfo();                // 成员初始化
  101. ~_M_PageInfo();               // 析构,根据bIsModified决定是否需要写会文件
  102.     void UpdatePageInfo(unsigned int fileid,unsigned long filepageid);  // 页替换、开辟等
  103.     _TB_PAGEHEAD* GetPtr2Head() const;      // 取得页头信息地址
  104.     _TB_FILECOND* GetPtr2FileCond() const;  // 取得文件头信息地址
  105.     unsigned int GetFileID() const;         // 取得所分配的内存页目前内容所属的文件编号
  106.     void SetFileID(unsigned int fileid);    // 设置新的文件编号(抛弃页时设为0即可)
  107.     unsigned long GetFilePageID() const;    // 取得所分配的内存页目前内容在文件中的页编号
  108. };
  109. //------------------------------------------------------------
  110. /*********************************************************
  111. *            内存页置换算法实现类,采用Clock算法
  112. *            开辟内存页管理对象数组,每个内存页管
  113. *            理对象对应一个内存页对象,需要的时候
  114. *            才开辟,避免内存的浪费
  115. **********************************************************/
  116. class _M_Clock
  117. {
  118. friend class _M_Buffer;
  119. friend class _M_File;
  120. friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
  121. private:
  122. unsigned int uiClockSize;    // 内存中页总数,即Clock钟点总数
  123. unsigned int uiCurrClockPtr; // 目前正在使用的内存页
  124. class _M_PageInfo* Ptr2MemPageInfo[MEM_PAGEAMOUNT+1];   // 内存页管理对象(不包含内存页空间)
  125. _M_Clock();                  // 成员初始化
  126. ~_M_Clock();                 // 析构
  127.     void SetPageModified();      // 设置当前页使之为脏页
  128. void CloseFilePages(unsigned int fileid); // 关闭文件并抛弃所属内存页(适用于欲删除一个文件的时候)
  129. unsigned int GetNullPage();  // 查找Clock中尚未分配内存空间的页
  130.     unsigned int GetFreePage();  // 查找Clock中已经被抛弃的页
  131. unsigned int GetSwapPage(unsigned int fileid);   // 查找Clock中最近一页可被替换的页
  132.     // 查找Clock中最早打开的文件所占用的内存页,如果是常驻内存页则关闭该文件(该写回的写回)
  133.     // 所有打开的文件已经由_M_Buffer类组织成链表
  134. unsigned int NR_Search(unsigned int tarfileid); 
  135.     // Clock算法实现,通过U_M_Search()四次调用,完成Clock算法
  136. unsigned int U_M_Search(bool islastused,bool ismodified,bool changeused);
  137.     // 查找已经存在的页(假设要找的页已经存在的话)
  138. unsigned int GetExsitPage(unsigned int fileid,unsigned long filepageid);
  139.     // 根据文件编号和页号取得内存页(通过上面各种方法)
  140. _M_PageInfo* GetTargetPage(unsigned int fileid,unsigned long filepageid);
  141. };
  142. //-------------------------------------------------------
  143. /*********************************************************
  144. *            内存文件类,与其他模块的主要接口,将
  145. *            通过此类得到欲访问文件中的数据的内存首地址
  146. **********************************************************/
  147. class _M_File{
  148. friend class _M_Buffer;
  149. friend class _F_FileAddr;
  150. friend class _M_Clock;
  151. friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
  152. private:
  153. unsigned int uiFileID;      // 文件编号
  154.     unsigned long ulPageTotal;  // 目前文件总的页数
  155.     bool IsNew;                 // 该文件是否新建
  156. char FileName[MAX_FILENAME_LEN];  // 文件名称(包含路径)
  157. _M_File* _F_Next;           // 下一个打开的文件
  158.     int Ptr2File;               // 文件指针
  159.     void Deconstruct();         // 析构,关闭文件
  160.     _M_PageInfo* GetPageInfo(unsigned long filepageid) const; // 根据页号取得属于该文件的内存页
  161.     // 初始化,打开和新建文件,若当前文件开的太多,导致无法再打开新文件,可自动关闭最早打开的文件
  162.     _M_File(const char *name,unsigned int fileid);            
  163.     // 取得相关文件,由于一个表包含两个文件(.idx,.dbf),故查找关联的文件编号
  164.     unsigned int GetRelativeFileID() const;
  165. public:
  166.     _F_FileAddr GetCataPoint() const;    // 取得Catalog模块在文件中可写的第一个位置
  167.     _F_FileAddr GetIdxPoint() const;     // 取得Catalog模块在文件中可写的第一个位置
  168.     _F_FileAddr GetDelListCond() const;  // 取得文件内记录删除维护信息
  169.     unsigned long GetPageTotal() const;  // 取得目前总的页数
  170.     // 关闭文件,同时属于该文件的内存页改写回的写回.为保证一致性,同时关闭关联文件
  171. void Close();                        
  172. };
  173. //-------------------------------------------------------
  174. /*********************************************************
  175. *            Buffer模块管理类,包含两部分数据的管理
  176. *            一、内存页的管理,通过一个_M_Clock对象实现
  177. *            二、打开文件的管理,组织所有的文件    
  178. **********************************************************/
  179. class _M_Buffer{
  180. friend class _M_Page;
  181. friend class _M_PageInfo;
  182. friend class _M_File;
  183. friend class _M_Clock;
  184. friend class _F_FileAddr;
  185. friend _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
  186. friend _F_FileAddr MemWriteTest(size_t,_F_FileAddr*);
  187. private:
  188. unsigned int uiFileCount;       // 打开文件总数
  189. _M_File* _F_First;              // 第一个文件
  190. _M_File* _F_Last;               // 最后一个文件 
  191.     _M_File* _F_Current;            // 当前使用文件  
  192.     class _M_Clock* MemPageClock;   // Clock算法实现类(管理所有内存页)
  193.     _M_File* operator[](unsigned int fileid) const; // 根据文件编号返回内存文件对象
  194. void CloseFile(unsigned int fileid);            // 根据文件编号关闭内存文件对象
  195.     void CloseTable(unsigned int fileid);           // 根据文件编号关闭内存文件对象及其关联内存文件对象
  196.     bool GetIsNew(unsigned int fileid) const;       // 根据文件编号返回内存文件对象是否为新建
  197.     void SetIsNew(unsigned int fileid,bool isnew);  // 根据文件编号设置内存文件对象是否为新建
  198.     unsigned long GetPageTotal(unsigned int fileid) const; // 根据文件编号返回内存文件对象总页数
  199.     void AddPageTotal(unsigned int fileid,int add); // 根据文件编号色设置内存文件对象的总页数
  200.     int GetPtr2File(unsigned int fileid) const;     // 根据文件编号返回内存文件对象的文件指针
  201. public:
  202.     _M_File operator[](const char* filename);       // 根据文件名称返回内存文件对象
  203.     void Start();                                   // Buffer初始化
  204.     void End();                                     // Buffer结束,写回内存页,关闭文件
  205. };
  206. //-------------------------------------------------------
  207. /***************************************************************** 
  208. ** 函数名: MemWrite
  209. ** 输  入: const void*,size_t,_F_FileAddr*
  210. **      const void* --- 欲写入buffer的对象(数据)的内存地址
  211. **      size_t      --- 数据总长度
  212. **      _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
  213. 况下,将自动修正为最终写入文件的地址
  214. ** 输  出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
  215. ** 功能描述: 根据欲写入的文件地址,把其他模块内存中的数据写
  216.  入buffer中,最终自动写入文件中
  217. ** 全局变量: 无
  218. **********************************************************/
  219. _F_FileAddr MemWrite(const void*,size_t,_F_FileAddr*);
  220. //-------------------------------------------------------
  221. /***************************************************************** 
  222. ** 函数名: MemWriteTest
  223. ** 输  入: const void*,size_t,_F_FileAddr*
  224. **      const void* --- 欲写入buffer的对象(数据)的内存地址
  225. **      size_t      --- 数据总长度
  226. **      _F_FileAddr* ---文件内地址,测试判断后,若越界、跨块等情
  227. 况下,将自动修正为最终写入文件的地址
  228. ** 输  出: _F_FileAddr --- 文件内地址,为下一个文件末尾可写的地址
  229. ** 功能描述: 根据欲写入的文件地址,测试把其他模块内存中的数据写入
  230.              实际未写入。用于当整个数据对象不能跨快写的时候又不能
  231.  一次写入(如链表结构(各字段)的一条记录,在内存中不连
  232.  续)的场合。
  233. *****************************************************************/
  234. _F_FileAddr MemWriteTest(size_t,_F_FileAddr*);
  235. //-------------------------------------------------------
  236. #endif //define _BUFFER_H_
  237. //-------------------------------------------------------
  238. //-------------------------------------------------------