Leaked source code of windows server 2003
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.

293 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. cachehint.cxx
  5. Abstract:
  6. Provides hint to caches about whether or not to cache an entry, based
  7. on usage patterns
  8. Author:
  9. Bilal Alam (balam) 11-Nov-2000
  10. Environment:
  11. Win32 - User Mode
  12. Project:
  13. ULW3.DLL
  14. --*/
  15. #include "precomp.hxx"
  16. #include "cachehint.hxx"
  17. BOOL
  18. CACHE_HINT_ENTRY::QueryIsOkToCache(
  19. DWORD tickCountNow,
  20. DWORD cmsecActivityWindow
  21. )
  22. /*++
  23. Routine Description:
  24. Is it OK to cache entry, given recent activity
  25. Arguments:
  26. tickCountNow - Current tick count
  27. cmsecActivityWindow - Maximum window between access to cause caching
  28. Return Value:
  29. TRUE to cache, FALSE to not cache
  30. --*/
  31. {
  32. DWORD lastUsageTime;
  33. DWORD timeBetweenUsage;
  34. lastUsageTime = InterlockedExchange( (LPLONG) &_cLastUsageTime,
  35. tickCountNow );
  36. if ( lastUsageTime > tickCountNow )
  37. {
  38. timeBetweenUsage = tickCountNow + ( UINT_MAX - lastUsageTime );
  39. }
  40. else
  41. {
  42. timeBetweenUsage = tickCountNow - lastUsageTime;
  43. }
  44. if ( timeBetweenUsage < cmsecActivityWindow )
  45. {
  46. return TRUE;
  47. }
  48. else
  49. {
  50. return FALSE;
  51. }
  52. }
  53. CACHE_HINT_MANAGER::CACHE_HINT_MANAGER()
  54. : _cConfiguredTTL( 0 ),
  55. _cmsecActivityWindow( 0 ),
  56. _hTimer( NULL )
  57. {
  58. }
  59. CACHE_HINT_MANAGER::~CACHE_HINT_MANAGER()
  60. {
  61. if ( _hTimer )
  62. {
  63. DeleteTimerQueueTimer( NULL,
  64. _hTimer,
  65. INVALID_HANDLE_VALUE );
  66. _hTimer = NULL;
  67. }
  68. }
  69. //static
  70. VOID
  71. WINAPI
  72. CACHE_HINT_MANAGER::ScavengerCallback(
  73. PVOID pParam,
  74. BOOLEAN
  75. )
  76. {
  77. CACHE_HINT_MANAGER * pHintManager;
  78. pHintManager = (CACHE_HINT_MANAGER*) pParam;
  79. pHintManager->FlushByTTL();
  80. }
  81. //static
  82. LK_PREDICATE
  83. CACHE_HINT_MANAGER::HintFlushByTTL(
  84. CACHE_HINT_ENTRY * pHintEntry,
  85. VOID *
  86. )
  87. /*++
  88. Routine Description:
  89. Determine whether given entry should be deleted due to TTL
  90. Arguments:
  91. pCacheEntry - Cache hint entry to check
  92. pvState - Unused
  93. Return Value:
  94. LKP_PERFORM - do the delete,
  95. LKP_NO_ACTION - do nothing
  96. --*/
  97. {
  98. DBG_ASSERT( pHintEntry != NULL );
  99. if ( pHintEntry->QueryIsOkToFlushTTL() )
  100. {
  101. return LKP_PERFORM;
  102. }
  103. else
  104. {
  105. return LKP_NO_ACTION;
  106. }
  107. }
  108. VOID
  109. CACHE_HINT_MANAGER::FlushByTTL(
  110. VOID
  111. )
  112. /*++
  113. Routine Description:
  114. Flush hint entries which have expired
  115. Arguments:
  116. None
  117. Return Value:
  118. None
  119. --*/
  120. {
  121. _hintTable.DeleteIf( HintFlushByTTL, NULL );
  122. }
  123. HRESULT
  124. CACHE_HINT_MANAGER::Initialize(
  125. CACHE_HINT_CONFIG * pConfig
  126. )
  127. /*++
  128. Routine Description:
  129. Initialize cache hint table
  130. Arguments:
  131. pConfig - Cache hint config table
  132. Return Value:
  133. HRESULT
  134. --*/
  135. {
  136. BOOL fRet;
  137. if ( pConfig == NULL )
  138. {
  139. DBG_ASSERT( FALSE );
  140. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  141. }
  142. _cConfiguredTTL = pConfig->cmsecTTL / pConfig->cmsecScavengeTime + 1;
  143. _cmsecActivityWindow = pConfig->cmsecActivityWindow;
  144. fRet = CreateTimerQueueTimer( &_hTimer,
  145. NULL,
  146. CACHE_HINT_MANAGER::ScavengerCallback,
  147. this,
  148. pConfig->cmsecScavengeTime,
  149. pConfig->cmsecScavengeTime,
  150. WT_EXECUTELONGFUNCTION );
  151. if ( !fRet )
  152. {
  153. return HRESULT_FROM_WIN32( GetLastError() );
  154. }
  155. return NO_ERROR;
  156. }
  157. HRESULT
  158. CACHE_HINT_MANAGER::ShouldCacheEntry(
  159. CACHE_KEY * pCacheEntryKey,
  160. BOOL * pfShouldCache
  161. )
  162. /*++
  163. Routine Description:
  164. Determine whether we the given entry should be cached
  165. Arguments:
  166. pCacheEntryKey - Entry key in question (must implement QueryHintKey())
  167. pfShouldCache - Set to TRUE if we should cache
  168. Return Value:
  169. HRESULT
  170. --*/
  171. {
  172. LK_RETCODE lkrc;
  173. CACHE_HINT_ENTRY * pHintEntry = NULL;
  174. DWORD tickCount;
  175. HRESULT hr;
  176. if ( pCacheEntryKey == NULL ||
  177. pfShouldCache == NULL )
  178. {
  179. DBG_ASSERT( FALSE );
  180. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  181. }
  182. *pfShouldCache = FALSE;
  183. DBG_ASSERT( pCacheEntryKey->QueryHintKey() != NULL );
  184. lkrc = _hintTable.FindKey( pCacheEntryKey->QueryHintKey(),
  185. &pHintEntry );
  186. if ( lkrc == LK_SUCCESS )
  187. {
  188. DBG_ASSERT( pHintEntry != NULL );
  189. tickCount = GetTickCount();
  190. if ( pHintEntry->QueryIsOkToCache( tickCount,
  191. _cmsecActivityWindow ) )
  192. {
  193. *pfShouldCache = TRUE;
  194. }
  195. //
  196. // Release corresponding to the FindKey
  197. //
  198. pHintEntry->Release();
  199. }
  200. else
  201. {
  202. pHintEntry = new CACHE_HINT_ENTRY( _cConfiguredTTL,
  203. GetTickCount() );
  204. if ( pHintEntry == NULL )
  205. {
  206. return HRESULT_FROM_WIN32( GetLastError() );
  207. }
  208. hr = pHintEntry->SetKey( pCacheEntryKey->QueryHintKey() );
  209. if ( FAILED( hr ) )
  210. {
  211. pHintEntry->Release();
  212. return hr;
  213. }
  214. lkrc = _hintTable.InsertRecord( pHintEntry );
  215. //
  216. // Release the extra reference
  217. //
  218. pHintEntry->Release();
  219. }
  220. return NO_ERROR;
  221. }