From fb8b43dbce8bc310718614384297aeaabb9a3cbb Mon Sep 17 00:00:00 2001 From: Michael Krelin Date: Mon, 05 Jul 2004 01:53:09 +0000 Subject: initial commit into svn repository git-svn-id: http://svn.klever.net/kin/bigbrother/trunk@1 fe716a7a-6dde-0310-88d9-d003556173a8 --- (limited to 'shared-code/LRUCache.h') diff --git a/shared-code/LRUCache.h b/shared-code/LRUCache.h new file mode 100644 index 0000000..569e829 --- a/dev/null +++ b/shared-code/LRUCache.h @@ -0,0 +1,113 @@ +#ifndef __LRUCACHE_H +#define __LRUCACHE_H + +namespace Klever { + +template +class CLRUCache : public CObject { +public: + struct CacheEntry { + enum cacheState { + cacheClean, cacheDirty, cacheEmpty + }; + cacheState m_State; + UINT m_hits; + + IDX m_idx; + DATA* m_pData; + + CacheEntry() { m_State=cacheEmpty; VERIFY(m_pData=new DATA); m_hits=0; } + virtual ~CacheEntry() { delete m_pData; } + }; + typedef CMap CCacheMap; + typedef CList CCacheList; + + CCacheList m_Cache; + CCacheMap m_Map; + + CLRUCache(UINT cacheSize) { + for(int tmp=0;tmpm_hits++; + PopUp(rv); + return rv->m_pData; + } + if(!bLoad) + return NULL; + rv = m_Cache.GetTail(); + ASSERT(rv); + switch(rv->m_State){ + case CacheEntry::cacheDirty: + FlushEntry(rv); + case CacheEntry::cacheClean: + m_Map.RemoveKey(rv->m_idx); + rv->m_State=CacheEntry::cacheEmpty; + case CacheEntry::cacheEmpty: + break; + default: + ASSERT(FALSE); + } + if(!_ReadIn(idx,rv->m_pData)) + return NULL; + rv->m_hits=1; + rv->m_State=CacheEntry::cacheClean; + rv->m_idx=idx; + m_Map[idx]=rv; + PopUp(rv); + return rv->m_pData; + } + BOOL MakeDirty(ARGIDX idx) { + CacheEntry* pEntry; + if(m_Map.Lookup(idx,pEntry)){ + ASSERT(pEntry->m_State==CacheEntry::cacheClean || pEntry->m_State==CacheEntry::cacheDirty); + pEntry->m_State=CacheEntry::cacheDirty; + return TRUE; + } + return FALSE; + } + BOOL Flush() { + POSITION p = m_Cache.GetHeadPosition(); + while(p){ + CacheEntry* pEntry = m_Cache.GetNext(p); + ASSERT(pEntry); + FlushEntry(pEntry); + } + return TRUE; + } + BOOL FlushEntry(CacheEntry* pEntry) { + if(pEntry->m_State==CacheEntry::cacheDirty){ + BOOL rv = _WriteOut(pEntry->m_idx,pEntry->m_pData); + if(rv) + pEntry->m_State=CacheEntry::cacheClean; + } + return FALSE; + } + void PopUp(CacheEntry* pEntry) { + POSITION p = m_Cache.Find(pEntry); + ASSERT(p); + m_Cache.RemoveAt(p); + VERIFY(m_Cache.AddHead(pEntry)); + } + + virtual BOOL _ReadIn(ARGIDX idx,DATA* data) = 0; + virtual BOOL _WriteOut(ARGIDX idx,DATA* data) = 0; +}; + +}; + +#endif // __LRUCACHE_H -- cgit v0.9.0.2