windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/pki/chain/lru.h
2020-09-26 16:20:57 +08:00

620 lines
13 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: lru.h
//
// Contents: LRU cache class definitions
//
// History: 22-Dec-97 kirtd Created
//
//----------------------------------------------------------------------------
#if !defined(__LRU_H__)
#define __LRU_H__
#include <lrucache.h>
//
// Forward declaration of LRU cache classes
//
class CLruCache;
class CLruEntry;
typedef CLruCache* PCLRUCACHE;
typedef CLruEntry* PCLRUENTRY;
//
// LRU cache bucket structure
//
typedef struct _LRU_CACHE_BUCKET {
DWORD Usage;
PCLRUENTRY pList;
} LRU_CACHE_BUCKET, *PLRU_CACHE_BUCKET;
//
// CLruEntry class definition
//
class CLruEntry
{
public:
//
// Construction
//
CLruEntry (
IN PCLRUCACHE pCache,
IN PCRYPT_DATA_BLOB pIdentifier,
IN LPVOID pvData,
OUT BOOL& rfResult
);
~CLruEntry ();
//
// Reference counting
//
inline VOID AddRef ();
inline VOID Release ();
//
// Cache and Bucket access
//
inline PCLRUCACHE Cache ();
inline PLRU_CACHE_BUCKET Bucket ();
//
// Data access
//
inline PCRYPT_DATA_BLOB Identifier ();
inline LPVOID Data ();
//
// Link access
//
inline VOID SetPrevPointer (IN PCLRUENTRY pPrevEntry);
inline VOID SetNextPointer (IN PCLRUENTRY pNextEntry);
inline PCLRUENTRY PrevPointer ();
inline PCLRUENTRY NextPointer ();
//
// LRU usage access
//
inline VOID SetUsage (DWORD Usage);
inline DWORD Usage ();
//
// Cache Destruction notification
//
inline VOID OnCacheDestruction ();
private:
//
// Reference count
//
ULONG m_cRefs;
//
// Cache pointer
//
PCLRUCACHE m_pCache;
//
// Entry information
//
CRYPT_DATA_BLOB m_Identifier;
LPVOID m_pvData;
//
// Links
//
PCLRUENTRY m_pPrevEntry;
PCLRUENTRY m_pNextEntry;
PLRU_CACHE_BUCKET m_pBucket;
//
// Usage
//
DWORD m_Usage;
};
//
// CLruCache class definition
//
class CLruCache
{
public:
//
// Construction
//
CLruCache (
IN PLRU_CACHE_CONFIG pConfig,
OUT BOOL& rfResult
);
~CLruCache ();
//
// Clearing the cache
//
VOID PurgeAllEntries (
IN DWORD dwFlags,
IN OPTIONAL LPVOID pvRemovalContext
);
//
// Cache locking
//
inline VOID LockCache ();
inline VOID UnlockCache ();
//
// LRU enable and disable
//
VOID EnableLruOfEntries (IN OPTIONAL LPVOID pvLruRemovalContext);
VOID DisableLruOfEntries ();
//
// Cache entry manipulation
//
VOID InsertEntry (
IN PCLRUENTRY pEntry,
IN OPTIONAL LPVOID pvLruRemovalContext
);
VOID RemoveEntry (
IN PCLRUENTRY pEntry,
IN DWORD dwFlags,
IN OPTIONAL LPVOID pvRemovalContext
);
VOID TouchEntry (IN PCLRUENTRY pEntry, IN DWORD dwFlags);
//
// Cache entry retrieval
//
PCLRUENTRY FindEntry (IN PCRYPT_DATA_BLOB pIdentifier, IN BOOL fTouchEntry);
PCLRUENTRY NextMatchingEntry (
IN PCLRUENTRY pPrevEntry,
IN BOOL fTouchEntry
);
//
// Cache bucket retrieval
//
inline PLRU_CACHE_BUCKET BucketFromIdentifier (
IN PCRYPT_DATA_BLOB pIdentifier
);
//
// Configuration access
//
//
// Use the configured free function to release the
// pvData in an entry
//
// MOTE: This is called from the CLruEntry destructor
//
inline VOID FreeEntryData (IN LPVOID pvData);
//
// Access the configuration flags
//
inline DWORD Flags ();
//
// Usage clock access
//
inline VOID IncrementUsageClock ();
inline DWORD UsageClock ();
//
// Walk all cache entries
//
VOID WalkEntries (IN PFN_WALK_ENTRIES pfnWalk, IN LPVOID pvParameter);
private:
//
// Cache configuration
//
LRU_CACHE_CONFIG m_Config;
//
// Cache lock
//
CRITICAL_SECTION m_Lock;
//
// Entry count
//
DWORD m_cEntries;
//
// Cache Buckets
//
PLRU_CACHE_BUCKET m_aBucket;
//
// Usage clock
//
DWORD m_UsageClock;
//
// LRU disabled count
//
DWORD m_cLruDisabled;
//
// Private methods
//
VOID RemoveEntryFromBucket (
IN PLRU_CACHE_BUCKET pBucket,
IN PCLRUENTRY pEntry,
IN DWORD dwFlags,
IN OPTIONAL LPVOID pvRemovalContext
);
PCLRUENTRY FindNextMatchingEntryInBucket (
IN PLRU_CACHE_BUCKET pBucket,
IN PCLRUENTRY pCurrent,
IN PCRYPT_DATA_BLOB pIdentifier,
IN BOOL fTouchEntry
);
VOID PurgeLeastRecentlyUsed (IN OPTIONAL LPVOID pvLruRemovalContext);
inline VOID TouchEntryNoLock (IN PCLRUENTRY pEntry, IN DWORD dwFlags);
};
//
// Inline functions
//
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::AddRef, public
//
// Synopsis: increment entry reference count
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::AddRef ()
{
InterlockedIncrement( (LONG *)&m_cRefs );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Release, public
//
// Synopsis: decrement entry reference count and if count goes to zero
// free the entry
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::Release ()
{
if ( InterlockedDecrement( (LONG *)&m_cRefs ) == 0 )
{
delete this;
}
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Cache, public
//
// Synopsis: return the internal cache pointer
//
//----------------------------------------------------------------------------
inline PCLRUCACHE
CLruEntry::Cache ()
{
return( m_pCache );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Bucket, public
//
// Synopsis: return the internal cache bucket pointer
//
//----------------------------------------------------------------------------
inline PLRU_CACHE_BUCKET
CLruEntry::Bucket ()
{
return( m_pBucket );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Identifier, public
//
// Synopsis: return the internal entry identifier
//
//----------------------------------------------------------------------------
inline PCRYPT_DATA_BLOB
CLruEntry::Identifier ()
{
return( &m_Identifier );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Data, public
//
// Synopsis: return the internal entry data
//
//----------------------------------------------------------------------------
inline LPVOID
CLruEntry::Data ()
{
return( m_pvData );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::SetPrevPointer, public
//
// Synopsis: set the previous entry pointer
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::SetPrevPointer (IN PCLRUENTRY pPrevEntry)
{
m_pPrevEntry = pPrevEntry;
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::SetNextPointer, public
//
// Synopsis: set the next entry pointer
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::SetNextPointer (IN PCLRUENTRY pNextEntry)
{
m_pNextEntry = pNextEntry;
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::PrevPointer, public
//
// Synopsis: return the previous entry pointer
//
//----------------------------------------------------------------------------
inline PCLRUENTRY
CLruEntry::PrevPointer ()
{
return( m_pPrevEntry );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::NextPointer, public
//
// Synopsis: return the next entry pointer
//
//----------------------------------------------------------------------------
inline PCLRUENTRY
CLruEntry::NextPointer ()
{
return( m_pNextEntry );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::SetUsage, public
//
// Synopsis: set the usage on the entry object and on
// the corresponding cache bucket
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::SetUsage (IN DWORD Usage)
{
m_Usage = Usage;
m_pBucket->Usage = Usage;
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::Usage, public
//
// Synopsis: return the internal entry usage
//
//----------------------------------------------------------------------------
inline DWORD
CLruEntry::Usage ()
{
return( m_Usage );
}
//+---------------------------------------------------------------------------
//
// Member: CLruEntry::OnCacheDestruction, public
//
// Synopsis: cleanup reference to cache that is being destroyed
//
//----------------------------------------------------------------------------
inline VOID
CLruEntry::OnCacheDestruction ()
{
m_pCache = NULL;
m_pBucket = NULL;
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::LockCache, public
//
// Synopsis: acquire the cache lock
//
//----------------------------------------------------------------------------
inline VOID
CLruCache::LockCache ()
{
if ( m_Config.dwFlags & LRU_CACHE_NO_SERIALIZE )
{
return;
}
EnterCriticalSection( &m_Lock );
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::UnlockCache, public
//
// Synopsis: release the cache lock
//
//----------------------------------------------------------------------------
inline VOID
CLruCache::UnlockCache ()
{
if ( m_Config.dwFlags & LRU_CACHE_NO_SERIALIZE )
{
return;
}
LeaveCriticalSection( &m_Lock );
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::BucketFromIdentifier, public
//
// Synopsis: retrieve the associated cache bucket given the entry identifier
//
//----------------------------------------------------------------------------
inline PLRU_CACHE_BUCKET
CLruCache::BucketFromIdentifier (
IN PCRYPT_DATA_BLOB pIdentifier
)
{
DWORD Hash = ( *m_Config.pfnHash )( pIdentifier );
return( &m_aBucket[ Hash % m_Config.cBuckets ] );
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::FreeEntryData, public
//
// Synopsis: free the data using the configured free function
//
//----------------------------------------------------------------------------
inline VOID
CLruCache::FreeEntryData (IN LPVOID pvData)
{
if ( m_Config.pfnFree != NULL )
{
( *m_Config.pfnFree )( pvData );
}
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::Flags, public
//
// Synopsis: access the configured flags
//
//----------------------------------------------------------------------------
inline DWORD
CLruCache::Flags ()
{
return( m_Config.dwFlags );
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::IncrementUsageClock, public
//
// Synopsis: increment the usage clock
//
//----------------------------------------------------------------------------
inline VOID
CLruCache::IncrementUsageClock ()
{
m_UsageClock += 1;
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::UsageClock, public
//
// Synopsis: return the usage clock value
//
//----------------------------------------------------------------------------
inline DWORD
CLruCache::UsageClock ()
{
return( m_UsageClock );
}
//+---------------------------------------------------------------------------
//
// Member: CLruCache::TouchEntryNoLock, public
//
// Synopsis: touch entry without taking the cache lock
//
//----------------------------------------------------------------------------
inline VOID
CLruCache::TouchEntryNoLock (IN PCLRUENTRY pEntry, IN DWORD dwFlags)
{
if ( !( dwFlags & LRU_SUPPRESS_CLOCK_UPDATE ) )
{
IncrementUsageClock();
}
pEntry->SetUsage( UsageClock() );
}
#endif