diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /sp/src/public/datacache/idatacache.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/public/datacache/idatacache.h')
| -rw-r--r-- | sp/src/public/datacache/idatacache.h | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/sp/src/public/datacache/idatacache.h b/sp/src/public/datacache/idatacache.h new file mode 100644 index 00000000..6e3fb61a --- /dev/null +++ b/sp/src/public/datacache/idatacache.h @@ -0,0 +1,545 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef IDATACACHE_H
+#define IDATACACHE_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "tier0/dbg.h"
+#include "appframework/IAppSystem.h"
+
+class IDataCache;
+
+//-----------------------------------------------------------------------------
+//
+// Shared Data Cache API
+//
+//-----------------------------------------------------------------------------
+
+#define DATACACHE_INTERFACE_VERSION "VDataCache003"
+
+//-----------------------------------------------------------------------------
+// Support types and enums
+//-----------------------------------------------------------------------------
+
+//---------------------------------------------------------
+// Unique (per section) identifier for a cache item defined by client
+//---------------------------------------------------------
+typedef uint32 DataCacheClientID_t;
+
+
+//---------------------------------------------------------
+// Cache-defined handle for a cache item
+//---------------------------------------------------------
+FORWARD_DECLARE_HANDLE( memhandle_t );
+typedef memhandle_t DataCacheHandle_t;
+#define DC_INVALID_HANDLE ((DataCacheHandle_t)0)
+
+//---------------------------------------------------------
+// Cache Limits
+//---------------------------------------------------------
+struct DataCacheLimits_t
+{
+ DataCacheLimits_t( unsigned _nMaxBytes = (unsigned)-1, unsigned _nMaxItems = (unsigned)-1, unsigned _nMinBytes = 0, unsigned _nMinItems = 0 )
+ : nMaxBytes(_nMaxBytes),
+ nMaxItems(_nMaxItems),
+ nMinBytes(_nMinBytes),
+ nMinItems(_nMinItems)
+ {
+ }
+
+ // Maximum levels permitted
+ unsigned nMaxBytes;
+ unsigned nMaxItems;
+
+ // Minimum levels permitted
+ unsigned nMinBytes;
+ unsigned nMinItems;
+};
+
+//---------------------------------------------------------
+// Cache status
+//---------------------------------------------------------
+struct DataCacheStatus_t
+{
+ // Current state of the cache
+ unsigned nBytes;
+ unsigned nItems;
+
+ unsigned nBytesLocked;
+ unsigned nItemsLocked;
+
+ // Diagnostics
+ unsigned nFindRequests;
+ unsigned nFindHits;
+};
+
+//---------------------------------------------------------
+// Cache options
+//---------------------------------------------------------
+enum DataCacheOptions_t
+{
+ DC_TRACE_ACTIVITY = (1 << 0),
+ DC_FORCE_RELOCATE = (1 << 1),
+ DC_ALWAYS_MISS = (1 << 2),
+ DC_VALIDATE = (1 << 3),
+};
+
+
+//---------------------------------------------------------
+// Cache report types
+//---------------------------------------------------------
+enum DataCacheReportType_t
+{
+ DC_SUMMARY_REPORT,
+ DC_DETAIL_REPORT,
+ DC_DETAIL_REPORT_LRU,
+};
+
+
+//---------------------------------------------------------
+// Notifications to section clients on cache events
+//---------------------------------------------------------
+enum DataCacheNotificationType_t
+{
+ // Used internally to prohibit notifications
+ DC_NONE,
+
+ // Item is falling off the LRU and should be deleted, return false to block
+ DC_AGE_DISCARD,
+
+ // Item is being explicitly flushed and should be deleted, return false to block
+ DC_FLUSH_DISCARD,
+
+ // Item is being explicitly removed and should be deleted. Failure is not an option
+ DC_REMOVED,
+
+ // Cache is requesting item be relocated for debugging purposes
+ DC_RELOCATE,
+
+ // Item info should be output to console, return false to accept default handling
+ DC_PRINT_INF0,
+};
+
+//-------------------------------------
+
+struct DataCacheNotification_t
+{
+ DataCacheNotificationType_t type;
+ const char * pszSectionName;
+ DataCacheClientID_t clientId;
+ const void * pItemData;
+ unsigned nItemSize;
+};
+
+//---------------------------------------------------------
+
+const int DC_MAX_CLIENT_NAME = 15;
+const int DC_MAX_ITEM_NAME = 511;
+
+//---------------------------------------------------------
+// Result codes
+//---------------------------------------------------------
+enum DataCacheRemoveResult_t
+{
+ DC_OK,
+ DC_NOT_FOUND,
+ DC_LOCKED,
+};
+
+//---------------------------------------------------------
+// Add flags
+//---------------------------------------------------------
+enum DataCacheAddFlags_t
+{
+ DCAF_LOCK = ( 1 << 0 ),
+ DCAF_DEFAULT = 0,
+};
+
+
+
+//-----------------------------------------------------------------------------
+// IDataCacheSection
+//
+// Purpose: Implements a sub-section of the global cache. Subsections are
+// areas of the cache with thier own memory constraints and common
+// management.
+//-----------------------------------------------------------------------------
+abstract_class IDataCacheSection
+{
+public:
+ //--------------------------------------------------------
+
+ virtual IDataCache *GetSharedCache() = 0;
+ virtual const char *GetName() = 0;
+
+ //--------------------------------------------------------
+ // Purpose: Controls cache size & options
+ //--------------------------------------------------------
+ virtual void SetLimits( const DataCacheLimits_t &limits ) = 0;
+ virtual void SetOptions( unsigned options ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Get the current state of the section
+ //--------------------------------------------------------
+ virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
+ //--------------------------------------------------------
+ virtual void EnsureCapacity( unsigned nBytes, unsigned nItems = 1 ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
+ //--------------------------------------------------------
+ virtual bool Add( DataCacheClientID_t clientId, const void *pItemData, unsigned size, DataCacheHandle_t *pHandle ) = 0;
+
+ //--------------------------------------------------------
+ // Purpose: Finds an item in the cache, returns NULL if item is not in cache. Not a cheap operation if section not configured for fast find.
+ //--------------------------------------------------------
+ virtual DataCacheHandle_t Find( DataCacheClientID_t clientId ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Get an item out of the cache and remove it. No callbacks are executed unless explicity specified.
+ //--------------------------------------------------------
+ virtual DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, const void **ppItemData, unsigned *pItemSize = NULL, bool bNotify = false ) = 0;
+ DataCacheRemoveResult_t Remove( DataCacheHandle_t handle, bool bNotify = false ) { return Remove( handle, NULL, NULL, bNotify ); }
+
+
+ //--------------------------------------------------------
+ // Purpose: Returns if the data is currently in memory, but does *not* change its location in the LRU
+ //--------------------------------------------------------
+ virtual bool IsPresent( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Lock an item in the cache, returns NULL if item is not in the cache.
+ //--------------------------------------------------------
+ virtual void *Lock( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Unlock a previous lock.
+ //--------------------------------------------------------
+ virtual int Unlock( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Get an item without locking it, returns NULL if item is not in the cache. Use with care!
+ //--------------------------------------------------------
+ virtual void *Get( DataCacheHandle_t handle, bool bFrameLock = false ) = 0;
+ virtual void *GetNoTouch( DataCacheHandle_t handle, bool bFrameLock = false ) = 0;
+
+ //--------------------------------------------------------
+ // Purpose: "Frame locking" (not game frame). A crude way to manage locks over relatively
+ // short periods. Does not affect normal locks/unlocks
+ //--------------------------------------------------------
+ virtual int BeginFrameLocking() = 0;
+ virtual bool IsFrameLocking() = 0;
+ virtual void *FrameLock( DataCacheHandle_t handle ) = 0;
+ virtual int EndFrameLocking() = 0;
+ virtual int *GetFrameUnlockCounterPtr() = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Lock management, not for the feint of heart
+ //--------------------------------------------------------
+ virtual int GetLockCount( DataCacheHandle_t handle ) = 0;
+ virtual int BreakLock( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Explicitly mark an item as "recently used"
+ //--------------------------------------------------------
+ virtual bool Touch( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Explicitly mark an item as "least recently used".
+ //--------------------------------------------------------
+ virtual bool Age( DataCacheHandle_t handle ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified
+ //--------------------------------------------------------
+ virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed
+ //--------------------------------------------------------
+ virtual unsigned Purge( unsigned nBytes ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Output the state of the section
+ //--------------------------------------------------------
+ virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT ) = 0;
+
+ //--------------------------------------------------------
+ // Purpose: Updates the size used by a specific item (locks the item, kicks
+ // other items out to make room as necessary, unlocks the item).
+ //--------------------------------------------------------
+ virtual void UpdateSize( DataCacheHandle_t handle, unsigned int nNewSize ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Access to the mutex. More explicit control during get-then-lock sequences
+ // to ensure object stays valid during "then"
+ //--------------------------------------------------------
+ virtual void LockMutex() = 0;
+ virtual void UnlockMutex() = 0;
+
+ //--------------------------------------------------------
+ // Purpose: Add an item to the cache. Purges old items if over budget, returns false if item was already in cache.
+ //--------------------------------------------------------
+ virtual bool AddEx( DataCacheClientID_t clientId, const void *pItemData, unsigned size, unsigned flags, DataCacheHandle_t *pHandle ) = 0;
+};
+
+
+//-----------------------------------------------------------------------------
+// IDataCacheClient
+//
+// Purpose: Connection between the cache and the owner of a cache section
+//
+//-----------------------------------------------------------------------------
+abstract_class IDataCacheClient
+{
+public:
+ //--------------------------------------------------------
+ //
+ //--------------------------------------------------------
+ virtual bool HandleCacheNotification( const DataCacheNotification_t ¬ification ) = 0;
+
+
+ //--------------------------------------------------------
+ //
+ //--------------------------------------------------------
+ virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen ) = 0;
+};
+
+//-------------------------------------
+
+class CDefaultDataCacheClient : public IDataCacheClient
+{
+public:
+ virtual bool HandleCacheNotification( const DataCacheNotification_t ¬ification )
+ {
+ switch ( notification.type )
+ {
+ case DC_AGE_DISCARD:
+ case DC_FLUSH_DISCARD:
+ case DC_REMOVED:
+ default:
+ Assert ( 0 );
+ return false;
+ }
+ return false;
+ }
+
+ virtual bool GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen )
+ {
+ return false;
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+// IDataCache
+//
+// Purpose: The global shared cache. Manages sections and overall budgets.
+//
+//-----------------------------------------------------------------------------
+abstract_class IDataCache : public IAppSystem
+{
+public:
+ //--------------------------------------------------------
+ // Purpose: Controls cache size.
+ //--------------------------------------------------------
+ virtual void SetSize( int nMaxBytes ) = 0;
+ virtual void SetOptions( unsigned options ) = 0;
+ virtual void SetSectionLimits( const char *pszSectionName, const DataCacheLimits_t &limits ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Get the current state of the cache
+ //--------------------------------------------------------
+ virtual void GetStatus( DataCacheStatus_t *pStatus, DataCacheLimits_t *pLimits = NULL ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Add a section to the cache
+ //--------------------------------------------------------
+ virtual IDataCacheSection *AddSection( IDataCacheClient *pClient, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Remove a section from the cache
+ //--------------------------------------------------------
+ virtual void RemoveSection( const char *pszClientName, bool bCallFlush = true ) = 0;
+ void RemoveSection( IDataCacheSection *pSection, bool bCallFlush = true ) { if ( pSection) RemoveSection( pSection->GetName() ); }
+
+
+ //--------------------------------------------------------
+ // Purpose: Find a section of the cache
+ //--------------------------------------------------------
+ virtual IDataCacheSection *FindSection( const char *pszClientName ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Dump the oldest items to free the specified amount of memory. Returns amount actually freed
+ //--------------------------------------------------------
+ virtual unsigned Purge( unsigned nBytes ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Empty the cache. Returns bytes released, will remove locked items if force specified
+ //--------------------------------------------------------
+ virtual unsigned Flush( bool bUnlockedOnly = true, bool bNotify = true ) = 0;
+
+
+ //--------------------------------------------------------
+ // Purpose: Output the state of the cache
+ //--------------------------------------------------------
+ virtual void OutputReport( DataCacheReportType_t reportType = DC_SUMMARY_REPORT, const char *pszSection = NULL ) = 0;
+};
+
+//-----------------------------------------------------------------------------
+// Helper class to support usage pattern similar to CDataManager
+//-----------------------------------------------------------------------------
+
+template< class STORAGE_TYPE, class CREATE_PARAMS, class LOCK_TYPE = STORAGE_TYPE * >
+class CManagedDataCacheClient : public CDefaultDataCacheClient
+{
+public:
+ typedef CManagedDataCacheClient<STORAGE_TYPE, CREATE_PARAMS, LOCK_TYPE> CCacheClientBaseClass;
+
+ CManagedDataCacheClient()
+ : m_pCache( NULL )
+ {
+ }
+
+ void Init( IDataCache *pSharedCache, const char *pszSectionName, const DataCacheLimits_t &limits = DataCacheLimits_t(), bool bSupportFastFind = false )
+ {
+ if ( !m_pCache )
+ {
+ m_pCache = pSharedCache->AddSection( this, pszSectionName, limits, bSupportFastFind );
+ }
+ }
+
+ void Shutdown()
+ {
+ if ( m_pCache )
+ {
+ m_pCache->GetSharedCache()->RemoveSection( m_pCache );
+ m_pCache = NULL;
+ }
+ }
+
+ LOCK_TYPE CacheGet( DataCacheHandle_t handle, bool bFrameLock = true )
+ {
+ return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Get( handle, bFrameLock ))->GetData());
+ }
+
+ LOCK_TYPE CacheGetNoTouch( DataCacheHandle_t handle )
+ {
+ return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->GetNoTouch( handle ))->GetData());
+ }
+
+ LOCK_TYPE CacheLock( DataCacheHandle_t handle )
+ {
+ return (LOCK_TYPE)(((STORAGE_TYPE *)m_pCache->Lock( handle ))->GetData());
+ }
+
+ int CacheUnlock( DataCacheHandle_t handle )
+ {
+ return m_pCache->Unlock( handle );
+ }
+
+ void CacheTouch( DataCacheHandle_t handle )
+ {
+ m_pCache->Touch( handle );
+ }
+
+ void CacheRemove( DataCacheHandle_t handle, bool bNotify = true )
+ {
+ m_pCache->Remove( handle, bNotify );
+ }
+
+ void CacheFlush()
+ {
+ m_pCache->Flush();
+ }
+
+ DataCacheHandle_t CacheCreate( const CREATE_PARAMS &createParams, unsigned flags = DCAF_DEFAULT )
+ {
+ m_pCache->EnsureCapacity(STORAGE_TYPE::EstimatedSize(createParams));
+ STORAGE_TYPE *pStore = STORAGE_TYPE::CreateResource( createParams );
+ DataCacheHandle_t handle;
+ m_pCache->AddEx( (DataCacheClientID_t)pStore, pStore, pStore->Size(), flags, &handle);
+ return handle;
+ }
+
+ void CacheLockMutex()
+ {
+ m_pCache->LockMutex();
+ }
+
+ void CacheUnlockMutex()
+ {
+ m_pCache->UnlockMutex();
+ }
+
+ bool HandleCacheNotification( const DataCacheNotification_t ¬ification )
+ {
+ switch ( notification.type )
+ {
+ case DC_AGE_DISCARD:
+ case DC_FLUSH_DISCARD:
+ case DC_REMOVED:
+ {
+ STORAGE_TYPE *p = (STORAGE_TYPE *)notification.clientId;
+ p->DestroyResource();
+ }
+ return true;
+ default:
+ return CDefaultDataCacheClient::HandleCacheNotification( notification );
+ }
+ }
+
+
+protected:
+
+ ~CManagedDataCacheClient()
+ {
+ Shutdown();
+ }
+
+ IDataCacheSection *GetCacheSection()
+ {
+ return m_pCache;
+ }
+
+private:
+ IDataCacheSection *m_pCache;
+
+};
+
+//-----------------------------------------------------------------------------
+
+#endif // IDataCache
|