|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name : cachehint.cxx
Abstract: Provides hint to caches about whether or not to cache an entry, based on usage patterns Author: Bilal Alam (balam) 11-Nov-2000
Environment: Win32 - User Mode
Project: ULW3.DLL --*/
#include "precomp.hxx"
#include "cachehint.hxx"
BOOL CACHE_HINT_ENTRY::QueryIsOkToCache( DWORD tickCountNow, DWORD cmsecActivityWindow ) /*++
Routine Description:
Is it OK to cache entry, given recent activity
Arguments:
tickCountNow - Current tick count cmsecActivityWindow - Maximum window between access to cause caching
Return Value:
TRUE to cache, FALSE to not cache
--*/ { DWORD lastUsageTime; DWORD timeBetweenUsage; lastUsageTime = InterlockedExchange( (LPLONG) &_cLastUsageTime, tickCountNow ); if ( lastUsageTime > tickCountNow ) { timeBetweenUsage = tickCountNow + ( UINT_MAX - lastUsageTime ); } else { timeBetweenUsage = tickCountNow - lastUsageTime; } if ( timeBetweenUsage < cmsecActivityWindow ) { return TRUE; } else { return FALSE; } }
CACHE_HINT_MANAGER::CACHE_HINT_MANAGER() : _cConfiguredTTL( 0 ), _cmsecActivityWindow( 0 ), _hTimer( NULL ) { }
CACHE_HINT_MANAGER::~CACHE_HINT_MANAGER() { if ( _hTimer ) { DeleteTimerQueueTimer( NULL, _hTimer, INVALID_HANDLE_VALUE ); _hTimer = NULL; } }
//static
VOID WINAPI CACHE_HINT_MANAGER::ScavengerCallback( PVOID pParam, BOOLEAN ) { CACHE_HINT_MANAGER * pHintManager; pHintManager = (CACHE_HINT_MANAGER*) pParam;
pHintManager->FlushByTTL(); }
//static
LK_PREDICATE CACHE_HINT_MANAGER::HintFlushByTTL( CACHE_HINT_ENTRY * pHintEntry, VOID * ) /*++
Routine Description:
Determine whether given entry should be deleted due to TTL
Arguments:
pCacheEntry - Cache hint entry to check pvState - Unused
Return Value:
LKP_PERFORM - do the delete, LKP_NO_ACTION - do nothing
--*/ { DBG_ASSERT( pHintEntry != NULL ); if ( pHintEntry->QueryIsOkToFlushTTL() ) { return LKP_PERFORM; } else { return LKP_NO_ACTION; } }
VOID CACHE_HINT_MANAGER::FlushByTTL( VOID ) /*++
Routine Description:
Flush hint entries which have expired
Arguments:
None Return Value: None
--*/ { _hintTable.DeleteIf( HintFlushByTTL, NULL ); }
HRESULT CACHE_HINT_MANAGER::Initialize( CACHE_HINT_CONFIG * pConfig ) /*++
Routine Description:
Initialize cache hint table
Arguments:
pConfig - Cache hint config table Return Value: HRESULT
--*/ { BOOL fRet; if ( pConfig == NULL ) { DBG_ASSERT( FALSE ); return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); } _cConfiguredTTL = pConfig->cmsecTTL / pConfig->cmsecScavengeTime + 1; _cmsecActivityWindow = pConfig->cmsecActivityWindow; fRet = CreateTimerQueueTimer( &_hTimer, NULL, CACHE_HINT_MANAGER::ScavengerCallback, this, pConfig->cmsecScavengeTime, pConfig->cmsecScavengeTime, WT_EXECUTELONGFUNCTION ); if ( !fRet ) { return HRESULT_FROM_WIN32( GetLastError() ); } return NO_ERROR; }
HRESULT CACHE_HINT_MANAGER::ShouldCacheEntry( CACHE_KEY * pCacheEntryKey, BOOL * pfShouldCache ) /*++
Routine Description:
Determine whether we the given entry should be cached
Arguments:
pCacheEntryKey - Entry key in question (must implement QueryHintKey()) pfShouldCache - Set to TRUE if we should cache Return Value: HRESULT
--*/ { LK_RETCODE lkrc; CACHE_HINT_ENTRY * pHintEntry = NULL; DWORD tickCount; HRESULT hr; if ( pCacheEntryKey == NULL || pfShouldCache == NULL ) { DBG_ASSERT( FALSE ); return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); } *pfShouldCache = FALSE;
DBG_ASSERT( pCacheEntryKey->QueryHintKey() != NULL ); lkrc = _hintTable.FindKey( pCacheEntryKey->QueryHintKey(), &pHintEntry ); if ( lkrc == LK_SUCCESS ) { DBG_ASSERT( pHintEntry != NULL ); tickCount = GetTickCount(); if ( pHintEntry->QueryIsOkToCache( tickCount, _cmsecActivityWindow ) ) { *pfShouldCache = TRUE; }
//
// Release corresponding to the FindKey
//
pHintEntry->Release(); } else { pHintEntry = new CACHE_HINT_ENTRY( _cConfiguredTTL, GetTickCount() ); if ( pHintEntry == NULL ) { return HRESULT_FROM_WIN32( GetLastError() ); } hr = pHintEntry->SetKey( pCacheEntryKey->QueryHintKey() ); if ( FAILED( hr ) ) { pHintEntry->Release(); return hr; } lkrc = _hintTable.InsertRecord( pHintEntry );
//
// Release the extra reference
//
pHintEntry->Release(); } return NO_ERROR; }
|