windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/iisplus/w3cache/cachehint.cxx

300 lines
5.8 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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 TimerOrWaitFired
)
{
CACHE_HINT_MANAGER * pHintManager;
pHintManager = (CACHE_HINT_MANAGER*) pParam;
pHintManager->FlushByTTL();
}
//static
LK_PREDICATE
CACHE_HINT_MANAGER::HintFlushByTTL(
CACHE_HINT_ENTRY * pHintEntry,
VOID * pvState
)
/*++
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 ) )
{
//
// We can delete this hint entry now
//
_hintTable.DeleteRecord( pHintEntry );
*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;
}