Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
7.7 KiB

  1. //***************************************************************************
  2. //
  3. // (c) 2001 by Microsoft Corp. All Rights Reserved.
  4. //
  5. // PAGEMGR.H
  6. //
  7. // Declarations for CPageFile, CPageSource for WMI repository for
  8. // Windows XP.
  9. //
  10. // 21-Feb-01 raymcc
  11. //
  12. //***************************************************************************
  13. #ifndef _PAGEMGR_H_
  14. #define _PAGEMGR_H_
  15. #define WMIREP_PAGE_SIZE (8192)
  16. #define WMIREP_INVALID_PAGE 0xFFFFFFFF
  17. #define WMIREP_RESERVED_PAGE 0xFFFFFFFE
  18. #define WMIREP_OBJECT_DATA L"OBJECTS.DATA"
  19. #define WMIREP_OBJECT_MAP L"OBJECTS.MAP"
  20. #define WMIREP_BTREE_DATA L"INDEX.BTR"
  21. #define WMIREP_BTREE_MAP L"INDEX.MAP"
  22. #include <vector>
  23. #include <wstlallc.h>
  24. #include <wstring.h>
  25. #include <sync.h>
  26. struct SCachePage
  27. {
  28. BOOL m_bDirty;
  29. DWORD m_dwPhysId;
  30. LPBYTE m_pPage;
  31. SCachePage() { m_bDirty = 0; m_dwPhysId = 0; m_pPage = 0; }
  32. ~SCachePage() { if (m_pPage) delete [] m_pPage; }
  33. };
  34. class AutoClose
  35. {
  36. HANDLE m_hHandle;
  37. public:
  38. AutoClose(HANDLE h) { m_hHandle = h; }
  39. ~AutoClose() { CloseHandle(m_hHandle); }
  40. };
  41. class CPageCache
  42. {
  43. private:
  44. DWORD m_dwStatus;
  45. DWORD m_dwPageSize;
  46. DWORD m_dwCacheSize;
  47. DWORD m_dwCachePromoteThreshold;
  48. DWORD m_dwCacheSpillRatio;
  49. DWORD m_dwLastFlushTime;
  50. DWORD m_dwWritesSinceFlush;
  51. DWORD m_dwLastCacheAccess;
  52. DWORD m_dwReadHits;
  53. DWORD m_dwReadMisses;
  54. DWORD m_dwWriteHits;
  55. DWORD m_dwWriteMisses;
  56. HANDLE m_hFile;
  57. // Page r/w cache
  58. std::vector <SCachePage *, wbem_allocator<SCachePage *> > m_aCache;
  59. public:
  60. DWORD ReadPhysPage( // Does a real disk access
  61. IN DWORD dwPage, // Always physical ID
  62. OUT LPBYTE *pPageMem // Returns read-only pointer (copy of ptr in SCachePage struct)
  63. );
  64. DWORD WritePhysPage( // Does a real disk access
  65. DWORD dwPageId, // Always physical ID
  66. LPBYTE pPageMem // Read-only; doesn't acquire pointer
  67. );
  68. DWORD Spill();
  69. DWORD Empty();
  70. // Private methods
  71. public:
  72. CPageCache();
  73. ~CPageCache();
  74. DWORD Init(
  75. LPCWSTR pszFilename, // File
  76. DWORD dwPageSize, // In bytes
  77. DWORD dwCacheSize = 64, // Pages in cache
  78. DWORD dwCachePromoteThreshold = 16, // When to ignore promote-to-front
  79. DWORD dwCacheSpillRatio = 4 // How many additional pages to write on cache write-through
  80. );
  81. // Cache operations
  82. DWORD Write( // Only usable from within a transaction
  83. DWORD dwPhysId,
  84. LPBYTE pPageMem // Acquires memory (operator new required)
  85. );
  86. DWORD Read(
  87. IN DWORD dwPhysId,
  88. OUT LPBYTE *pMem // Use operator delete
  89. );
  90. DWORD Flush();
  91. DWORD Status() { return m_dwStatus; }
  92. DWORD EmptyCache() { DWORD dwRet = Flush(); if (dwRet == ERROR_SUCCESS) Empty(); return dwRet; }
  93. void Dump(FILE *f);
  94. DWORD GetReadHits() { return m_dwReadHits; }
  95. DWORD GetReadMisses() { return m_dwReadMisses; }
  96. DWORD GetWriteHits() { return m_dwWriteHits; }
  97. DWORD GetWriteMisses() { return m_dwWriteMisses; }
  98. };
  99. class CPageFile
  100. {
  101. private:
  102. friend class CPageSource;
  103. LONG m_lRef;
  104. DWORD m_dwStatus;
  105. DWORD m_dwPageSize;
  106. DWORD m_dwCachePromotionThreshold;
  107. DWORD m_dwCacheSpillRatio;
  108. CRITICAL_SECTION m_cs;
  109. bool m_bCsInit;
  110. WString m_sDirectory;
  111. WString m_sMapFile;
  112. WString m_sMainFile;
  113. CPageCache *m_pCache;
  114. BOOL m_bInTransaction;
  115. DWORD m_dwLastCheckpoint;
  116. DWORD m_dwTransVersion;
  117. // Generation A Mapping
  118. std::vector <DWORD, wbem_allocator<DWORD> > m_aPageMapA;
  119. std::vector <DWORD, wbem_allocator<DWORD> > m_aPhysFreeListA;
  120. std::vector <DWORD, wbem_allocator<DWORD> > m_aLogicalFreeListA;
  121. std::vector <DWORD, wbem_allocator<DWORD> > m_aReplacedPagesA;
  122. DWORD m_dwPhysPagesA;
  123. // Generation B Mapping
  124. std::vector <DWORD, wbem_allocator<DWORD> > m_aPageMapB;
  125. std::vector <DWORD, wbem_allocator<DWORD> > m_aPhysFreeListB;
  126. std::vector <DWORD, wbem_allocator<DWORD> > m_aLogicalFreeListB;
  127. std::vector <DWORD, wbem_allocator<DWORD> > m_aReplacedPagesB;
  128. DWORD m_dwPhysPagesB;
  129. std::vector <DWORD, wbem_allocator<DWORD> > m_aDeferredFreeList;
  130. //De-initialized the structure and marks it as such. A ReInit is required
  131. //before things will work again
  132. DWORD DeInit();
  133. //Re-initialize after a DeInit
  134. DWORD ReInit();
  135. public: // temp for testing
  136. // Internal methods
  137. DWORD Trans_Begin();
  138. DWORD Trans_Rollback();
  139. DWORD Trans_Commit();
  140. DWORD Trans_Checkpoint();
  141. DWORD InitFreeList();
  142. DWORD ResyncMaps();
  143. DWORD InitMap();
  144. DWORD ReadMap();
  145. DWORD WriteMap(LPCWSTR pszTempFile);
  146. DWORD AllocPhysPage(DWORD *pdwId);
  147. DWORD ReclaimLogicalPages(
  148. DWORD dwCount,
  149. DWORD *pdwId
  150. );
  151. DWORD GetTransVersion() { return m_dwTransVersion; }
  152. void DumpFreeListInfo();
  153. public:
  154. CPageFile();
  155. ~CPageFile();
  156. //First-time initializatoin of structure
  157. DWORD Init(
  158. LPCWSTR pszDirectory,
  159. LPCWSTR pszMainFile,
  160. LPCWSTR pszMapFile,
  161. DWORD dwRepPageSize,
  162. DWORD dwCacheSize,
  163. DWORD dwCachePromotionThreshold,
  164. DWORD dwCacheSpillRatio
  165. );
  166. static DWORD Map_Startup(
  167. LPCWSTR pszDirectory,
  168. LPCWSTR pszBTreeMap,
  169. LPCWSTR pszObjMap
  170. );
  171. ULONG AddRef();
  172. ULONG Release();
  173. DWORD GetPage(
  174. DWORD dwId, // page zero is admin page; doesn't require NewPage() call
  175. DWORD dwFlags,
  176. LPVOID pPage
  177. );
  178. DWORD PutPage(
  179. DWORD dwId,
  180. DWORD dwFlags,
  181. LPVOID pPage
  182. );
  183. DWORD NewPage(
  184. DWORD dwFlags,
  185. DWORD dwCount,
  186. DWORD *pdwFirstId
  187. );
  188. DWORD FreePage(
  189. DWORD dwFlags,
  190. DWORD dwId
  191. );
  192. DWORD GetPageSize() { return m_dwPageSize; }
  193. DWORD GetNumPages() { return m_aPageMapB.size(); }
  194. DWORD GetPhysPage(DWORD dwLogical) { return m_aPageMapB[dwLogical]; }
  195. DWORD Status() { return m_dwStatus; }
  196. DWORD EmptyCache()
  197. {
  198. if ((m_dwStatus == 0) && (m_pCache))
  199. return m_pCache->EmptyCache();
  200. else
  201. return m_dwStatus;
  202. }
  203. void Dump(FILE *f);
  204. };
  205. class CPageSource
  206. {
  207. private:
  208. DWORD m_dwPageSize;
  209. DWORD m_dwCacheSize;
  210. DWORD m_dwCachePromotionThreshold;
  211. DWORD m_dwCacheSpillRatio;
  212. DWORD m_dwLastCheckpoint;
  213. DWORD m_dwCheckpointInterval;
  214. WString m_sDirectory;
  215. WString m_sBTreeMap;
  216. WString m_sObjMap;
  217. CPageFile *m_pBTreePF;
  218. CPageFile *m_pObjPF;
  219. DWORD Restart();
  220. public:
  221. CPageSource();
  222. ~CPageSource();
  223. DWORD Init(
  224. DWORD dwCacheSize = 128,
  225. DWORD dwCheckpointTime = 15000,
  226. DWORD dwPageSize = 8192
  227. );
  228. DWORD Shutdown(DWORD dwFlags);
  229. DWORD GetBTreePageFile(OUT CPageFile **pPF); // Use Release() when done
  230. DWORD GetObjectHeapPageFile(OUT CPageFile **pPF); // Use Release() when done
  231. // Transactions
  232. DWORD BeginTrans();
  233. DWORD CommitTrans();
  234. DWORD RollbackTrans();
  235. // Checkpoint
  236. DWORD Checkpoint();
  237. DWORD CheckpointRollback();
  238. BOOL CheckpointRequired();
  239. // Cache discard
  240. DWORD EmptyCaches();
  241. DWORD GetStatus()
  242. {
  243. if (m_pBTreePF && m_pBTreePF->Status())
  244. return m_pBTreePF->Status();
  245. else if (m_pObjPF && m_pObjPF->Status())
  246. return m_pObjPF->Status();
  247. else if (!m_pBTreePF && !m_pObjPF)
  248. return ERROR_GEN_FAILURE;
  249. else
  250. return 0;
  251. }
  252. void Dump(FILE *f);
  253. };
  254. #endif