Listing 2: Implementation of cache manager
/* mru.cpp
* Copyright (c) 1995 T.W. Nelson. Permission
* is hereby granted to use this code in any
* manner provided the user display this
* copyright notice in the source
*/
#include "mru.h"
MruCache::MruCache(int nn, int objsz)
{
Cm = new TIGenDoubleList
<CacheNode,StdAlloc>;
Itr = new TIGenDoubleListIterator
<CacheNode,StdAlloc>(*Cm);
_nodes = nn;
if( _nodes < 3 )
_nodes = 3; /* adjust to at least
3 nodes */
for( int i = _nodes; i; i-- )
Cm->PutHead( new CacheNode(objsz) );
Mru = Cm->PeekHead();
Lru = Cm->PeekTail();
#if defined( TESTING )
_hits = _miss = _adds = 0;
#endif
}
MruCache::~MruCache()
{
Cm->Flush(1); /* destroy all
cache nodes */
delete Cm;
delete Itr;
}
void MruCache::Flush()
{ /* Free all nodes for re-use. */
CacheNode * p;
Itr->Restart();
while( (p = (*Itr)++) != 0 )
{ if( p->_stat == CacheNode::Mark )
Proc(p); /* process the node */
p->_stat = CacheNode::Release;
}
}
CacheNode *MruCache::Search(ulong tag)
{
CacheNode * p;
Itr->Restart();
while( (p = (*Itr)++) != 0 )
{ if( p->_tag == tag )
{
#if defined( TESTING )
_hits++; /* found it */
#endif
/* make it mru */
return make_mru( p );
}
}
#if defined( TESTING )
_miss++; /* missed again */
#endif
/* return not found */
return (CacheNode *) 0;
}
CacheNode *MruCache::make_mru(CacheNode *p)
{
if( p == Mru )
return p; /* already MRU, OK */
Cm->Unlink( p ); /* Disconnect node
at 'p' */
if( p == Lru )
/* LRU = prev node */
Lru = Cm->PeekTail();
/* re-connect 'p' as new MRU ...... */
Cm->PutHead( p );
Mru = p;
return p;
CacheNode *MruCache::AddNew( ulong tag )
{
CacheNode *p = Lru;
if( p->_stat == CacheNode::Mark )
Proc(p); /* process the node */
p->_stat = CacheNode::Release;
#if defined( TESTING )
_adds++;
#endif
p->_tag = tag; /* re-number it */
return make_mru(p);
}
CacheNode *
MruCache::Mark( ulong tag,
CacheNode::Status flag )
{
CacheNode * p;
Itr->Restart();
while( (p = (*Itr)++) != 0 )
{ if( p->_tag == tag )
{ p->_stat = flag;
return p;
}
}
return (CacheNode *) 0;
}
//End of File