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.

302 lines
9.1 KiB

  1. /*-----------------------------------------------------------------------------
  2. Microsoft Denali
  3. Microsoft Confidential
  4. Copyright 1996 Microsoft Corporation. All Rights Reserved.
  5. Component: Template Cache Manager
  6. File: CacheMgr.h
  7. Owner: DGottner
  8. Template cache manager definition
  9. -----------------------------------------------------------------------------*/
  10. #ifndef _CACHEMGR_H
  11. #define _CACHEMGR_H
  12. // Includes -------------------------------------------------------------------
  13. #include "Template.h"
  14. #include "lkrhash.h"
  15. #include "aspdmon.h"
  16. class CHitObj;
  17. // Types and Constants --------------------------------------------------------
  18. #define CTEMPLATEBUCKETS 1021 // size of CTemplate hash table
  19. #define CINCFILEBUCKETS 89 // size of CIncFile hash table
  20. /* ****************************************************************************
  21. Class: CTemplateCacheManager
  22. Synopsis: A CCacheManager that manages a cache of Denali templates
  23. */
  24. class CTemplateCacheManager
  25. {
  26. private:
  27. class CTemplateHashTable;
  28. friend class CTemplateHashTable;
  29. // since there is only one CTemplateCacheManager object ever available, namely
  30. // g_TemplateCache, this is safe to call these two members static.
  31. static BOOL m_fFailedToInitPersistCache;
  32. static char m_szPersistCacheDir[MAX_PATH];
  33. // The type for a hash table of CTemplates keyed on instance id + name
  34. //
  35. // since we provide new methods, make parent methods uncallable
  36. class CTemplateHashTable : private CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>
  37. {
  38. private:
  39. CDblLink m_listMemoryTemplates;
  40. CDblLink m_listPersistTemplates;
  41. DWORD m_dwInMemoryTemplates;
  42. DWORD m_dwPersistedTemplates;
  43. VOID ScavengePersistCache();
  44. public:
  45. // export some methods
  46. DWORD InMemoryTemplates() { return m_dwInMemoryTemplates; };
  47. //CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>::Size;
  48. // test to see if the template can be persisted...
  49. BOOL CanPersistTemplate(CTemplate *pTemplate);
  50. // trim some number of templates from the persist cache...
  51. BOOL TrimPersistCache(DWORD dwTrimCount);
  52. // new methods
  53. CTemplateHashTable()
  54. : CTypedHashTable<CTemplateHashTable, CTemplate, const CTemplateKey *>("ASP Template Cache") {
  55. m_dwInMemoryTemplates = 0;
  56. m_dwPersistedTemplates = 0;
  57. }
  58. static const CTemplateKey *ExtractKey(const CTemplate *pTemplate)
  59. {
  60. return pTemplate->ExtractHashKey();
  61. }
  62. // NOTE: We don't hash the pTemplateKey->nInstanceID because it can be wildcarded.
  63. // if we were to include in the hash, the wildcard won't hash to the same key
  64. //
  65. static DWORD CalcKeyHash(const CTemplateKey *pTemplateKey)
  66. {
  67. return HashString(pTemplateKey->szPathTranslated, 0);
  68. }
  69. static bool EqualKeys(const CTemplateKey *pKey1, const CTemplateKey *pKey2) {
  70. return (_tcscmp(pKey1->szPathTranslated, pKey2->szPathTranslated) == 0)
  71. && (pKey1->dwInstanceID == pKey2->dwInstanceID
  72. || pKey1->dwInstanceID == MATCH_ALL_INSTANCE_IDS
  73. || pKey2->dwInstanceID == MATCH_ALL_INSTANCE_IDS);
  74. }
  75. // NOTE: In theory, the LKHash can help solve our ref. counting problems, by
  76. // automatic addref/release. However, since prior code uses non-refcounting
  77. // data structure, it's safer to leave old code alaone in this respect, and
  78. // no-op the AddRefRecord method.
  79. //
  80. static void AddRefRecord(CTemplate *pTemplate, int nIncr)
  81. {
  82. }
  83. // Provide new methods to automatically manage the LRU ordering.
  84. // NOTE: We used to override the methods but ran into inconsistencies (bugs?)
  85. // in VC compiler. Sometimes it would call derived & sometimes the base class
  86. // given the same arguemt datatypes.
  87. //
  88. LK_RETCODE InsertTemplate(CTemplate *pTemplate);
  89. LK_RETCODE RemoveTemplate(CTemplate *pTemplate, BOOL fPersist = FALSE);
  90. // NOTE: Template signature also requires const ptr to const data
  91. LK_RETCODE FindTemplate(const CTemplateKey &rTemplateKey, CTemplate **ppTemplate);
  92. // accessor methods for hidden LRU cache
  93. bool FMemoryTemplatesIsEmpty() const
  94. {
  95. return m_listMemoryTemplates.FIsEmpty();
  96. }
  97. // you CANNOT compare LRU nodes to NULL to know if you are at the end
  98. // of the list! Instead use this member.
  99. //
  100. BOOL FMemoryTemplatesDblLinkAtEnd(CDblLink *pElem)
  101. {
  102. pElem->AssertValid();
  103. return pElem == &m_listMemoryTemplates;
  104. }
  105. CDblLink *MemoryTemplatesBegin() // return pointer to last referenced item
  106. {
  107. return m_listMemoryTemplates.PNext();
  108. }
  109. CDblLink *MemoryTemplatesEnd() // return pointer to least recently accessed item
  110. {
  111. return m_listMemoryTemplates.PPrev();
  112. }
  113. // accessor methods for hidden LRU cache
  114. bool FPersistTemplatesIsEmpty() const
  115. {
  116. return m_listPersistTemplates.FIsEmpty();
  117. }
  118. // you CANNOT compare LRU nodes to NULL to know if you are at the end
  119. // of the list! Instead use this member.
  120. //
  121. BOOL FPersistTemplatesDblLinkAtEnd(CDblLink *pElem)
  122. {
  123. pElem->AssertValid();
  124. return pElem == &m_listPersistTemplates;
  125. }
  126. CDblLink *PersistTemplatesBegin() // return pointer to last referenced item
  127. {
  128. return m_listPersistTemplates.PNext();
  129. }
  130. CDblLink *PersistTemplatesEnd() // return pointer to least recently accessed item
  131. {
  132. return m_listPersistTemplates.PPrev();
  133. }
  134. };
  135. CRITICAL_SECTION m_csUpdate; // CS for updating the data structures
  136. CTemplateHashTable *m_pHashTemplates; // the cache data structure
  137. // Initialize the persistant template cache
  138. BOOL InitPersistCache();
  139. // static methods primarily used from a seperate thread to flush
  140. // the template cache out of band from the FCN thread notification.
  141. static void FlushHashTable(CTemplateHashTable *pTable);
  142. static DWORD __stdcall FlushHashTableThread(VOID *pArg);
  143. public:
  144. CTemplateCacheManager();
  145. ~CTemplateCacheManager();
  146. inline void LockTemplateCache() { EnterCriticalSection(&m_csUpdate); }
  147. inline void UnLockTemplateCache() { LeaveCriticalSection(&m_csUpdate); }
  148. HRESULT Init();
  149. HRESULT UnInit();
  150. HRESULT FirstHitInit() { InitPersistCache(); return S_OK; }
  151. // Find in cache (don't load) -- for look-aheads
  152. /////
  153. HRESULT FindCached(const TCHAR *szFile, DWORD dwInstanceID, CTemplate **ppTemplate);
  154. // Get a template from the cache, or load it into cache
  155. /////
  156. HRESULT Load(BOOL fRunGlobalAsp, const TCHAR *szFile, DWORD dwInstanceID, CHitObj *pHitObj, CTemplate **ppTemplate, BOOL *pfTemplateInCache);
  157. // Remove a template from the cache
  158. // for backward compatibility, "nInstanceID" can be omitted, in which case all instance ID
  159. // templates are flushed.
  160. /////
  161. void Flush(const TCHAR *szFile, DWORD dwInstanceID);
  162. // Remove templates from the cache that have a common prefix
  163. // Instance ID is ignored.
  164. /////
  165. void FlushFiles(const TCHAR *szFilePrefix);
  166. // Remove all templates from the cache
  167. /////
  168. void FlushAll(VOID);
  169. // Add all templates that form an application to the debugger's list of
  170. // running documents
  171. /////
  172. void AddApplicationToDebuggerUI(CAppln *pAppln);
  173. // Remove all templates that form an application from the debugger's list of
  174. // running documents
  175. /////
  176. void RemoveApplicationFromDebuggerUI(CAppln *pAppln);
  177. // Get directory change notification on directories used by template
  178. BOOL RegisterTemplateForChangeNotification(CTemplate *pTemplate, CAppln *pApplication);
  179. // Get directory change notification for applications
  180. BOOL RegisterApplicationForChangeNotification(CTemplate *pTemplate, CAppln *pApplication);
  181. // Stop getting change notification for changes to templates in the cache.
  182. BOOL ShutdownCacheChangeNotification();
  183. };
  184. /* ****************************************************************************
  185. Class: CIncFileMap
  186. Synopsis: A database mapping template include files to a list of their users
  187. */
  188. class CIncFileMap
  189. {
  190. CRITICAL_SECTION m_csUpdate; // CS for updating the data structures
  191. CHashTable m_mpszIncFile; // the cache data structure
  192. public:
  193. CIncFileMap();
  194. ~CIncFileMap();
  195. inline void LockIncFileCache() { EnterCriticalSection(&m_csUpdate); }
  196. inline void UnLockIncFileCache() { LeaveCriticalSection(&m_csUpdate); }
  197. HRESULT Init();
  198. HRESULT UnInit();
  199. HRESULT GetIncFile(const TCHAR *szIncFile, CIncFile **ppIncFile);
  200. void Flush(const TCHAR *szIncFile);
  201. void FlushFiles(const TCHAR *szIncFilePrefix);
  202. };
  203. /* ****************************************************************************
  204. Non-class support functions
  205. */
  206. BOOL FFileChangedSinceCached(const TCHAR *szFile, FILETIME& ftPrevWriteTime);
  207. // Globals --------------------------------------------------------------------
  208. extern CTemplateCacheManager g_TemplateCache;
  209. extern CIncFileMap g_IncFileMap;
  210. inline void LockTemplateAndIncFileCaches()
  211. {
  212. g_TemplateCache.LockTemplateCache();
  213. g_IncFileMap.LockIncFileCache();
  214. }
  215. inline void UnLockTemplateAndIncFileCaches()
  216. {
  217. g_TemplateCache.UnLockTemplateCache();
  218. g_IncFileMap.UnLockIncFileCache();
  219. }
  220. // Prototypes -----------------------------------------------------------------
  221. #endif // _CACHEMGR_H