331 lines
7.7 KiB
C++
331 lines
7.7 KiB
C++
|
|
//***************************************************************************
|
|
//
|
|
// (c) 2001 by Microsoft Corp. All Rights Reserved.
|
|
//
|
|
// PAGEMGR.H
|
|
//
|
|
// Declarations for CPageFile, CPageSource for WMI repository for
|
|
// Windows XP.
|
|
//
|
|
// 21-Feb-01 raymcc
|
|
//
|
|
//***************************************************************************
|
|
|
|
#ifndef _PAGEMGR_H_
|
|
#define _PAGEMGR_H_
|
|
|
|
#define WMIREP_PAGE_SIZE (8192)
|
|
|
|
#define WMIREP_INVALID_PAGE 0xFFFFFFFF
|
|
#define WMIREP_RESERVED_PAGE 0xFFFFFFFE
|
|
|
|
#define WMIREP_OBJECT_DATA L"OBJECTS.DATA"
|
|
#define WMIREP_OBJECT_MAP L"OBJECTS.MAP"
|
|
#define WMIREP_BTREE_DATA L"INDEX.BTR"
|
|
#define WMIREP_BTREE_MAP L"INDEX.MAP"
|
|
|
|
#include <vector>
|
|
#include <wstlallc.h>
|
|
#include <wstring.h>
|
|
#include <sync.h>
|
|
|
|
|
|
struct SCachePage
|
|
{
|
|
BOOL m_bDirty;
|
|
DWORD m_dwPhysId;
|
|
LPBYTE m_pPage;
|
|
|
|
SCachePage() { m_bDirty = 0; m_dwPhysId = 0; m_pPage = 0; }
|
|
~SCachePage() { if (m_pPage) delete [] m_pPage; }
|
|
};
|
|
|
|
class AutoClose
|
|
{
|
|
HANDLE m_hHandle;
|
|
public:
|
|
AutoClose(HANDLE h) { m_hHandle = h; }
|
|
~AutoClose() { CloseHandle(m_hHandle); }
|
|
};
|
|
|
|
class CPageCache
|
|
{
|
|
private:
|
|
DWORD m_dwStatus;
|
|
|
|
DWORD m_dwPageSize;
|
|
DWORD m_dwCacheSize;
|
|
|
|
DWORD m_dwCachePromoteThreshold;
|
|
DWORD m_dwCacheSpillRatio;
|
|
|
|
DWORD m_dwLastFlushTime;
|
|
DWORD m_dwWritesSinceFlush;
|
|
DWORD m_dwLastCacheAccess;
|
|
DWORD m_dwReadHits;
|
|
DWORD m_dwReadMisses;
|
|
DWORD m_dwWriteHits;
|
|
DWORD m_dwWriteMisses;
|
|
|
|
HANDLE m_hFile;
|
|
|
|
// Page r/w cache
|
|
std::vector <SCachePage *, wbem_allocator<SCachePage *> > m_aCache;
|
|
public:
|
|
DWORD ReadPhysPage( // Does a real disk access
|
|
IN DWORD dwPage, // Always physical ID
|
|
OUT LPBYTE *pPageMem // Returns read-only pointer (copy of ptr in SCachePage struct)
|
|
);
|
|
|
|
DWORD WritePhysPage( // Does a real disk access
|
|
DWORD dwPageId, // Always physical ID
|
|
LPBYTE pPageMem // Read-only; doesn't acquire pointer
|
|
);
|
|
|
|
DWORD Spill();
|
|
DWORD Empty();
|
|
|
|
// Private methods
|
|
public:
|
|
CPageCache();
|
|
~CPageCache();
|
|
|
|
DWORD Init(
|
|
LPCWSTR pszFilename, // File
|
|
DWORD dwPageSize, // In bytes
|
|
DWORD dwCacheSize = 64, // Pages in cache
|
|
DWORD dwCachePromoteThreshold = 16, // When to ignore promote-to-front
|
|
DWORD dwCacheSpillRatio = 4 // How many additional pages to write on cache write-through
|
|
);
|
|
|
|
// Cache operations
|
|
|
|
DWORD Write( // Only usable from within a transaction
|
|
DWORD dwPhysId,
|
|
LPBYTE pPageMem // Acquires memory (operator new required)
|
|
);
|
|
|
|
DWORD Read(
|
|
IN DWORD dwPhysId,
|
|
OUT LPBYTE *pMem // Use operator delete
|
|
);
|
|
|
|
DWORD Flush();
|
|
DWORD Status() { return m_dwStatus; }
|
|
|
|
DWORD EmptyCache() { DWORD dwRet = Flush(); if (dwRet == ERROR_SUCCESS) Empty(); return dwRet; }
|
|
void Dump(FILE *f);
|
|
|
|
DWORD GetReadHits() { return m_dwReadHits; }
|
|
DWORD GetReadMisses() { return m_dwReadMisses; }
|
|
DWORD GetWriteHits() { return m_dwWriteHits; }
|
|
DWORD GetWriteMisses() { return m_dwWriteMisses; }
|
|
};
|
|
|
|
class CPageFile
|
|
{
|
|
private:
|
|
friend class CPageSource;
|
|
|
|
LONG m_lRef;
|
|
DWORD m_dwStatus;
|
|
DWORD m_dwPageSize;
|
|
DWORD m_dwCachePromotionThreshold;
|
|
DWORD m_dwCacheSpillRatio;
|
|
|
|
CRITICAL_SECTION m_cs;
|
|
bool m_bCsInit;
|
|
|
|
WString m_sDirectory;
|
|
WString m_sMapFile;
|
|
WString m_sMainFile;
|
|
|
|
CPageCache *m_pCache;
|
|
BOOL m_bInTransaction;
|
|
DWORD m_dwLastCheckpoint;
|
|
DWORD m_dwTransVersion;
|
|
|
|
// Generation A Mapping
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aPageMapA;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aPhysFreeListA;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aLogicalFreeListA;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aReplacedPagesA;
|
|
DWORD m_dwPhysPagesA;
|
|
|
|
// Generation B Mapping
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aPageMapB;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aPhysFreeListB;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aLogicalFreeListB;
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aReplacedPagesB;
|
|
DWORD m_dwPhysPagesB;
|
|
|
|
std::vector <DWORD, wbem_allocator<DWORD> > m_aDeferredFreeList;
|
|
|
|
//De-initialized the structure and marks it as such. A ReInit is required
|
|
//before things will work again
|
|
DWORD DeInit();
|
|
|
|
//Re-initialize after a DeInit
|
|
DWORD ReInit();
|
|
|
|
public: // temp for testing
|
|
// Internal methods
|
|
DWORD Trans_Begin();
|
|
DWORD Trans_Rollback();
|
|
DWORD Trans_Commit();
|
|
|
|
DWORD Trans_Checkpoint();
|
|
|
|
DWORD InitFreeList();
|
|
DWORD ResyncMaps();
|
|
DWORD InitMap();
|
|
DWORD ReadMap();
|
|
DWORD WriteMap(LPCWSTR pszTempFile);
|
|
|
|
DWORD AllocPhysPage(DWORD *pdwId);
|
|
|
|
DWORD ReclaimLogicalPages(
|
|
DWORD dwCount,
|
|
DWORD *pdwId
|
|
);
|
|
|
|
DWORD GetTransVersion() { return m_dwTransVersion; }
|
|
void DumpFreeListInfo();
|
|
|
|
public:
|
|
CPageFile();
|
|
~CPageFile();
|
|
|
|
//First-time initializatoin of structure
|
|
DWORD Init(
|
|
LPCWSTR pszDirectory,
|
|
LPCWSTR pszMainFile,
|
|
LPCWSTR pszMapFile,
|
|
DWORD dwRepPageSize,
|
|
DWORD dwCacheSize,
|
|
DWORD dwCachePromotionThreshold,
|
|
DWORD dwCacheSpillRatio
|
|
);
|
|
|
|
|
|
static DWORD Map_Startup(
|
|
LPCWSTR pszDirectory,
|
|
LPCWSTR pszBTreeMap,
|
|
LPCWSTR pszObjMap
|
|
);
|
|
|
|
|
|
ULONG AddRef();
|
|
ULONG Release();
|
|
|
|
DWORD GetPage(
|
|
DWORD dwId, // page zero is admin page; doesn't require NewPage() call
|
|
DWORD dwFlags,
|
|
LPVOID pPage
|
|
);
|
|
|
|
DWORD PutPage(
|
|
DWORD dwId,
|
|
DWORD dwFlags,
|
|
LPVOID pPage
|
|
);
|
|
|
|
DWORD NewPage(
|
|
DWORD dwFlags,
|
|
DWORD dwCount,
|
|
DWORD *pdwFirstId
|
|
);
|
|
|
|
DWORD FreePage(
|
|
DWORD dwFlags,
|
|
DWORD dwId
|
|
);
|
|
|
|
DWORD GetPageSize() { return m_dwPageSize; }
|
|
DWORD GetNumPages() { return m_aPageMapB.size(); }
|
|
DWORD GetPhysPage(DWORD dwLogical) { return m_aPageMapB[dwLogical]; }
|
|
DWORD Status() { return m_dwStatus; }
|
|
|
|
DWORD EmptyCache()
|
|
{
|
|
if ((m_dwStatus == 0) && (m_pCache))
|
|
return m_pCache->EmptyCache();
|
|
else
|
|
return m_dwStatus;
|
|
}
|
|
|
|
void Dump(FILE *f);
|
|
};
|
|
|
|
class CPageSource
|
|
{
|
|
private:
|
|
|
|
DWORD m_dwPageSize;
|
|
|
|
DWORD m_dwCacheSize;
|
|
DWORD m_dwCachePromotionThreshold;
|
|
DWORD m_dwCacheSpillRatio;
|
|
|
|
DWORD m_dwLastCheckpoint;
|
|
DWORD m_dwCheckpointInterval;
|
|
WString m_sDirectory;
|
|
WString m_sBTreeMap;
|
|
WString m_sObjMap;
|
|
|
|
CPageFile *m_pBTreePF;
|
|
CPageFile *m_pObjPF;
|
|
|
|
DWORD Restart();
|
|
|
|
public:
|
|
CPageSource();
|
|
~CPageSource();
|
|
|
|
DWORD Init(
|
|
DWORD dwCacheSize = 128,
|
|
DWORD dwCheckpointTime = 15000,
|
|
DWORD dwPageSize = 8192
|
|
);
|
|
|
|
DWORD Shutdown(DWORD dwFlags);
|
|
|
|
DWORD GetBTreePageFile(OUT CPageFile **pPF); // Use Release() when done
|
|
DWORD GetObjectHeapPageFile(OUT CPageFile **pPF); // Use Release() when done
|
|
|
|
// Transactions
|
|
|
|
DWORD BeginTrans();
|
|
DWORD CommitTrans();
|
|
DWORD RollbackTrans();
|
|
|
|
// Checkpoint
|
|
|
|
DWORD Checkpoint();
|
|
DWORD CheckpointRollback();
|
|
BOOL CheckpointRequired();
|
|
|
|
// Cache discard
|
|
|
|
DWORD EmptyCaches();
|
|
|
|
DWORD GetStatus()
|
|
{
|
|
if (m_pBTreePF && m_pBTreePF->Status())
|
|
return m_pBTreePF->Status();
|
|
else if (m_pObjPF && m_pObjPF->Status())
|
|
return m_pObjPF->Status();
|
|
else if (!m_pBTreePF && !m_pObjPF)
|
|
return ERROR_GEN_FAILURE;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void Dump(FILE *f);
|
|
};
|
|
|
|
|
|
#endif
|
|
|