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.

195 lines
5.8 KiB

  1. /*++
  2. Copyright (C) 2000-2001 Microsoft Corporation
  3. --*/
  4. #ifndef __WMI_A51__HIECACHE__H_
  5. #define __WMI_A51__HIECACHE__H_
  6. //
  7. // NOTE: it is critical that things be marked in the cache while the repository
  8. // lock is held! Otherwise, invalidation/completion logic will break
  9. //
  10. #include <wbemint.h>
  11. #include <map>
  12. #include <sync.h>
  13. #include "a51tools.h"
  14. class wcscless : public binary_function<LPCWSTR, LPCWSTR, bool>
  15. {
  16. public:
  17. bool operator()(const LPCWSTR& wcs1, const LPCWSTR& wcs2) const
  18. {return wcscmp(wcs1, wcs2) < 0;}
  19. };
  20. class CClassRecord
  21. {
  22. protected:
  23. long m_lRef;
  24. LPWSTR m_wszClassName;
  25. WCHAR m_wszHash[MAX_HASH_LEN+1];
  26. _IWmiObject* m_pClassDef;
  27. DWORD m_dwClassDefSize;
  28. CClassRecord* m_pParent;
  29. bool m_bIsKeyed;
  30. CPointerArray<CClassRecord> m_apChildren;
  31. bool m_bTreeComplete;
  32. bool m_bChildrenComplete;
  33. LONGLONG m_lLastChildInvalidationIndex;
  34. DWORD m_dwLastUsed;
  35. CClassRecord* m_pMoreRecentlyUsed;
  36. CClassRecord* m_pLessRecentlyUsed;
  37. int m_nStatus;
  38. __int64 m_nClassDefCachedTime;
  39. bool m_bRead;
  40. public:
  41. CClassRecord(LPCWSTR wszClassName, LPCWSTR wszHash);
  42. ~CClassRecord();
  43. void AddRef() {InterlockedIncrement(&m_lRef);}
  44. void Release() {if(InterlockedDecrement(&m_lRef) == 0) delete this;}
  45. HRESULT EnsureChild(CClassRecord* pChild);
  46. HRESULT RemoveChild(CClassRecord* pChild);
  47. friend class CHierarchyCache;
  48. friend class CForestCache;
  49. };
  50. class CForestCache;
  51. class CHierarchyCache
  52. {
  53. protected:
  54. long m_lRef;
  55. typedef std::map<LPCWSTR, CClassRecord*, wcscless> TMap;
  56. typedef TMap::iterator TIterator;
  57. CForestCache* m_pForest;
  58. CCritSec m_cs;
  59. TMap m_map;
  60. LONGLONG m_lNextInvalidationIndex;
  61. HRESULT m_hresError;
  62. public:
  63. CHierarchyCache(CForestCache* pForest);
  64. ~CHierarchyCache();
  65. long AddRef() {return InterlockedIncrement(&m_lRef);}
  66. long Release() {return InterlockedDecrement(&m_lRef);}
  67. HRESULT AssertClass(_IWmiObject* pClass, LPCWSTR wszClassName,
  68. bool bClone, __int64 nTime);
  69. HRESULT InvalidateClass(LPCWSTR wszClassName);
  70. HRESULT DoneWithChildren(LPCWSTR wszClassName, bool bRecursive,
  71. LONGLONG lStartingIndex,
  72. CClassRecord* pRecord = NULL);
  73. HRESULT DoneWithChildrenByHash(LPCWSTR wszHash, bool bRecursive,
  74. LONGLONG lStartIndex);
  75. LONGLONG GetLastInvalidationIndex() {return m_lNextInvalidationIndex-1;}
  76. void SetError(HRESULT hresError);
  77. HRESULT GetError();
  78. public:
  79. RELEASE_ME _IWmiObject* GetClassDef(LPCWSTR wszClassName,
  80. bool bClone, __int64* pnTime = NULL,
  81. bool* pbRead = NULL);
  82. HRESULT EnumChildren(LPCWSTR wszClassName, bool bRecursive,
  83. CWStringArray& awsChildren);
  84. HRESULT EnumChildKeysByKey(LPCWSTR wszClassKey,
  85. CWStringArray& awsChildKeys);
  86. HRESULT GetKeyRootByKey(LPCWSTR wszKey,
  87. TEMPFREE_ME LPWSTR* pwszKeyRoot);
  88. HRESULT GetKeyRoot(LPCWSTR wszClassName,
  89. TEMPFREE_ME LPWSTR* pwszKeyRoot);
  90. HRESULT GetKeyRootByRecord(CClassRecord* pRecord,
  91. TEMPFREE_ME LPWSTR* pwszKeyRoot);
  92. DELETE_ME LPWSTR GetParent(LPCWSTR wszClassName);
  93. RELEASE_ME _IWmiObject* GetClassDefByHash(LPCWSTR wszHash, bool bClone,
  94. __int64* pnTime = NULL,
  95. bool* pbRead = NULL);
  96. protected:
  97. INTERNAL CClassRecord* FindClass(LPCWSTR wszClassName);
  98. INTERNAL CClassRecord* FindClassByKey(LPCWSTR wszKey);
  99. RELEASE_ME _IWmiObject* GetClassDefFromRecord(CClassRecord* pRecord,
  100. bool bClone);
  101. INTERNAL CClassRecord* EnsureClass(LPCWSTR wszClassName);
  102. HRESULT EnumChildrenInternal(CClassRecord* pRecord,
  103. bool bRecursive,
  104. CWStringArray& awsChildren);
  105. HRESULT InvalidateClassInternal(CClassRecord* pRecord);
  106. HRESULT DoneWithChildrenByRecord(CClassRecord* pRecord,
  107. bool bRecursive, LONGLONG lStartIndex);
  108. static void MakeKey(LPCWSTR wszClassName, LPWSTR wszKey);
  109. };
  110. class CForestCache
  111. {
  112. protected:
  113. CCritSec m_cs;
  114. CClassRecord* m_pMostRecentlyUsed;
  115. CClassRecord* m_pLeastRecentlyUsed;
  116. DWORD m_dwMaxMemory;
  117. DWORD m_dwMaxAgeMs;
  118. DWORD m_dwTotalMemory;
  119. HANDLE m_hTimerQueue;
  120. HANDLE m_hCurrentTimer;
  121. HANDLE m_hCompletionEvent;
  122. typedef std::map<WString, CHierarchyCache*, WSiless> TMap;
  123. typedef TMap::iterator TIterator;
  124. TMap m_map;
  125. long m_lRef;
  126. public:
  127. CForestCache() : m_dwMaxMemory(0xFFFFFFFF), m_dwTotalMemory(0),
  128. m_pMostRecentlyUsed(NULL), m_pLeastRecentlyUsed(NULL),
  129. m_dwMaxAgeMs(0), m_hTimerQueue(NULL), m_hCurrentTimer(NULL),
  130. m_hCompletionEvent(NULL), m_lRef(0)
  131. {
  132. }
  133. ~CForestCache();
  134. HRESULT Initialize();
  135. void SetMaxMemory(DWORD dwMaxMemory, DWORD dwMaxAgeMs);
  136. bool MakeRoom(DWORD dwSize);
  137. bool Flush();
  138. void MakeMostRecentlyUsed(CClassRecord* pRecord);
  139. void Add(CClassRecord* pRecord);
  140. void RemoveRecord(CClassRecord* pRecord);
  141. public:
  142. CHierarchyCache* GetNamespaceCache(LPCWSTR wszNamespace);
  143. void ReleaseNamespaceCache(LPCWSTR wszNamespace, CHierarchyCache* pCache);
  144. long AddRef() {return InterlockedIncrement(&m_lRef);}
  145. long Release() {long lRet = InterlockedDecrement(&m_lRef); if (!lRet) delete this; return lRet;}
  146. protected:
  147. CCritSec* GetLock() {return &m_cs;}
  148. bool Test();
  149. void Untie(CClassRecord* pRecord);
  150. void TimerCallback();
  151. static void staticTimerCallback(VOID* pParam, BOOLEAN);
  152. friend class CHierarchyCache;
  153. };
  154. #endif