📄 cache.cpp
字号:
/*
DB.CPP
This module implements a simple ip address cache. The cached addresses are kept
in an LRU sorted list. If there will be a large number of simultaneous
addresses, then a sorted array would be more appropriate.
*/
#include "stdafx.h"
#include "IPAddressFilter.h"
/*
Routine Description:
Initializes the cache module
Return Value:
TRUE if initialized successfully, FALSE on error
*/
BOOL CIPAddressFilter::InitializeCache()
{
if ( m_fCacheInitialized )
return TRUE;
InitializeCriticalSection( &m_csCacheLock );
m_CacheListHead.Blink = m_CacheListHead.Flink = &m_CacheListHead;
m_fCacheInitialized = TRUE;
return TRUE;
}
/*
Routine Description:
Checks to see if an address is in the cache
Arguments:
pszIPAddress - IP address to find
pfFound - Set to TRUE if the specified address was found
Return Value:
TRUE if no errors occurred.
*/
BOOL CIPAddressFilter::LookupIPAddressInCache(const CHAR* pszIPAddress, BOOL* pfFound)
{
LIST_ENTRY* pEntry;
IP_INFO* pIPAddress;
DWORD cPosition = 0;
// Search the cache for the specified address
EnterCriticalSection( &m_csCacheLock );
for ( pEntry = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink)
{
pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
if ( !stricmp( pszIPAddress, pIPAddress->achIPAddress ))
goto Found;
cPosition++;
}
LeaveCriticalSection( &m_csCacheLock );
// Not Found
*pfFound = FALSE;
return TRUE;
Found:
// Move this address entry to the front of the list as we're probably going
// to get subsequent requests for this address. Note we only move it
// if it's not already near the front
if ( cPosition > LIST_REORDER_THRESHOLD )
{
// Remove from the old position...
pEntry->Blink->Flink = pEntry->Flink;
pEntry->Flink->Blink = pEntry->Blink;
// ...and insert it at the beginning of the list
pEntry->Blink = &m_CacheListHead;
pEntry->Flink = m_CacheListHead.Flink;
m_CacheListHead.Flink->Blink = pEntry;
m_CacheListHead.Flink = pEntry;
}
LeaveCriticalSection( &m_csCacheLock );
*pfFound = TRUE;
return TRUE;
}
/*
Routine Description:
Adds the specified address to the cache
Arguments:
pszIPAddress - IP address to add
Return Value:
TRUE if no errors occurred.
*/
BOOL CIPAddressFilter::AddIPAddressToCache(const CHAR* pszIPAddress)
{
LIST_ENTRY* pEntry;
IP_INFO* pIPAddress;
// Check our parameters before adding them to the cache
if ( strlen( pszIPAddress ) > MAX_IP_ADDRESS )
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
// Search the cache for the specified address to make sure there are no
// duplicates
EnterCriticalSection( &m_csCacheLock );
for ( pEntry = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink )
{
pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
if ( !stricmp( pszIPAddress, pIPAddress->achIPAddress ))
goto Found;
}
// Allocate a new cache item and put it at the head of the list
pIPAddress = (IP_INFO *) LocalAlloc( LPTR, sizeof( IP_INFO ));
if ( !pIPAddress )
{
LeaveCriticalSection( &m_csCacheLock );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
pIPAddress->ListEntry.Flink = m_CacheListHead.Flink;
pIPAddress->ListEntry.Blink = &m_CacheListHead;
m_CacheListHead.Flink->Blink = &pIPAddress->ListEntry;
m_CacheListHead.Flink = &pIPAddress->ListEntry;
Found:
// Set the various fields
strcpy( pIPAddress->achIPAddress, pszIPAddress );
m_cCacheItems++;
// If there are too many cached addresses, remove the least recently
// used one now
if ( m_cCacheItems > MAX_CACHED_ADDRESSES )
{
pEntry = m_CacheListHead.Blink;
pEntry->Blink->Flink = &m_CacheListHead;
m_CacheListHead.Blink = pEntry->Blink;
LocalFree( CONTAINING_RECORD( pEntry, IP_INFO, ListEntry ));
m_cCacheItems--;
}
LeaveCriticalSection( &m_csCacheLock );
return TRUE;
}
/*
Routine Description:
Terminates the cache module and frees any allocated memory
*/
VOID CIPAddressFilter::TerminateCache()
{
LIST_ENTRY* pEntry;
LIST_ENTRY* pEntryNext;
IP_INFO* pIPAddress;
if ( !m_fCacheInitialized )
return;
EnterCriticalSection( &m_csCacheLock );
// Free all of the cache entries
for ( pEntry = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntryNext )
{
pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
pEntryNext = pEntry->Flink;
// Remove this entry from the list and free it
pEntry->Blink->Flink = pEntry->Flink;
pEntry->Flink->Blink = pEntry->Blink;
LocalFree( pIPAddress );
}
m_cCacheItems = 0;
LeaveCriticalSection( &m_csCacheLock );
DeleteCriticalSection( &m_csCacheLock );
m_fCacheInitialized = FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -