windows-nt/Source/XPSP1/NT/admin/wmi/wbem/winmgmt/a51/hiecache.h
2020-09-26 16:20:57 +08:00

196 lines
5.8 KiB
C++

/*++
Copyright (C) 2000-2001 Microsoft Corporation
--*/
#ifndef __WMI_A51__HIECACHE__H_
#define __WMI_A51__HIECACHE__H_
//
// NOTE: it is critical that things be marked in the cache while the repository
// lock is held! Otherwise, invalidation/completion logic will break
//
#include <wbemint.h>
#include <map>
#include <sync.h>
#include "a51tools.h"
class wcscless : public binary_function<LPCWSTR, LPCWSTR, bool>
{
public:
bool operator()(const LPCWSTR& wcs1, const LPCWSTR& wcs2) const
{return wcscmp(wcs1, wcs2) < 0;}
};
class CClassRecord
{
protected:
long m_lRef;
LPWSTR m_wszClassName;
WCHAR m_wszHash[MAX_HASH_LEN+1];
_IWmiObject* m_pClassDef;
DWORD m_dwClassDefSize;
CClassRecord* m_pParent;
bool m_bIsKeyed;
CPointerArray<CClassRecord> m_apChildren;
bool m_bTreeComplete;
bool m_bChildrenComplete;
LONGLONG m_lLastChildInvalidationIndex;
DWORD m_dwLastUsed;
CClassRecord* m_pMoreRecentlyUsed;
CClassRecord* m_pLessRecentlyUsed;
int m_nStatus;
__int64 m_nClassDefCachedTime;
bool m_bRead;
public:
CClassRecord(LPCWSTR wszClassName, LPCWSTR wszHash);
~CClassRecord();
void AddRef() {InterlockedIncrement(&m_lRef);}
void Release() {if(InterlockedDecrement(&m_lRef) == 0) delete this;}
HRESULT EnsureChild(CClassRecord* pChild);
HRESULT RemoveChild(CClassRecord* pChild);
friend class CHierarchyCache;
friend class CForestCache;
};
class CForestCache;
class CHierarchyCache
{
protected:
long m_lRef;
typedef std::map<LPCWSTR, CClassRecord*, wcscless> TMap;
typedef TMap::iterator TIterator;
CForestCache* m_pForest;
CCritSec m_cs;
TMap m_map;
LONGLONG m_lNextInvalidationIndex;
HRESULT m_hresError;
public:
CHierarchyCache(CForestCache* pForest);
~CHierarchyCache();
long AddRef() {return InterlockedIncrement(&m_lRef);}
long Release() {return InterlockedDecrement(&m_lRef);}
HRESULT AssertClass(_IWmiObject* pClass, LPCWSTR wszClassName,
bool bClone, __int64 nTime);
HRESULT InvalidateClass(LPCWSTR wszClassName);
HRESULT DoneWithChildren(LPCWSTR wszClassName, bool bRecursive,
LONGLONG lStartingIndex,
CClassRecord* pRecord = NULL);
HRESULT DoneWithChildrenByHash(LPCWSTR wszHash, bool bRecursive,
LONGLONG lStartIndex);
LONGLONG GetLastInvalidationIndex() {return m_lNextInvalidationIndex-1;}
void SetError(HRESULT hresError);
HRESULT GetError();
public:
RELEASE_ME _IWmiObject* GetClassDef(LPCWSTR wszClassName,
bool bClone, __int64* pnTime = NULL,
bool* pbRead = NULL);
HRESULT EnumChildren(LPCWSTR wszClassName, bool bRecursive,
CWStringArray& awsChildren);
HRESULT EnumChildKeysByKey(LPCWSTR wszClassKey,
CWStringArray& awsChildKeys);
HRESULT GetKeyRootByKey(LPCWSTR wszKey,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
HRESULT GetKeyRoot(LPCWSTR wszClassName,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
HRESULT GetKeyRootByRecord(CClassRecord* pRecord,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
DELETE_ME LPWSTR GetParent(LPCWSTR wszClassName);
RELEASE_ME _IWmiObject* GetClassDefByHash(LPCWSTR wszHash, bool bClone,
__int64* pnTime = NULL,
bool* pbRead = NULL);
protected:
INTERNAL CClassRecord* FindClass(LPCWSTR wszClassName);
INTERNAL CClassRecord* FindClassByKey(LPCWSTR wszKey);
RELEASE_ME _IWmiObject* GetClassDefFromRecord(CClassRecord* pRecord,
bool bClone);
INTERNAL CClassRecord* EnsureClass(LPCWSTR wszClassName);
HRESULT EnumChildrenInternal(CClassRecord* pRecord,
bool bRecursive,
CWStringArray& awsChildren);
HRESULT InvalidateClassInternal(CClassRecord* pRecord);
HRESULT DoneWithChildrenByRecord(CClassRecord* pRecord,
bool bRecursive, LONGLONG lStartIndex);
static void MakeKey(LPCWSTR wszClassName, LPWSTR wszKey);
};
class CForestCache
{
protected:
CCritSec m_cs;
CClassRecord* m_pMostRecentlyUsed;
CClassRecord* m_pLeastRecentlyUsed;
DWORD m_dwMaxMemory;
DWORD m_dwMaxAgeMs;
DWORD m_dwTotalMemory;
HANDLE m_hTimerQueue;
HANDLE m_hCurrentTimer;
HANDLE m_hCompletionEvent;
typedef std::map<WString, CHierarchyCache*, WSiless> TMap;
typedef TMap::iterator TIterator;
TMap m_map;
long m_lRef;
public:
CForestCache() : m_dwMaxMemory(0xFFFFFFFF), m_dwTotalMemory(0),
m_pMostRecentlyUsed(NULL), m_pLeastRecentlyUsed(NULL),
m_dwMaxAgeMs(0), m_hTimerQueue(NULL), m_hCurrentTimer(NULL),
m_hCompletionEvent(NULL), m_lRef(0)
{
}
~CForestCache();
HRESULT Initialize();
void SetMaxMemory(DWORD dwMaxMemory, DWORD dwMaxAgeMs);
bool MakeRoom(DWORD dwSize);
bool Flush();
void MakeMostRecentlyUsed(CClassRecord* pRecord);
void Add(CClassRecord* pRecord);
void RemoveRecord(CClassRecord* pRecord);
public:
CHierarchyCache* GetNamespaceCache(LPCWSTR wszNamespace);
void ReleaseNamespaceCache(LPCWSTR wszNamespace, CHierarchyCache* pCache);
long AddRef() {return InterlockedIncrement(&m_lRef);}
long Release() {long lRet = InterlockedDecrement(&m_lRef); if (!lRet) delete this; return lRet;}
protected:
CCritSec* GetLock() {return &m_cs;}
bool Test();
void Untie(CClassRecord* pRecord);
void TimerCallback();
static void staticTimerCallback(VOID* pParam, BOOLEAN);
friend class CHierarchyCache;
};
#endif