CBitmapCache Class Reference

#include <bitmapcache.h>

List of all members.

Public Member Functions

 CBitmapCache ()
void Initialise ()
 

void DeInitialise ()
 

void StoreBitmap (const CBitmapCacheKey &key, const CCachedBitmap &bitmap)
 Places a bitmap in the cache (making room if necessary by removing others).
CCachedBitmap RemoveBitmap (const CBitmapCacheKey &key)
 Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!!
BOOL RemoveAllOwnedBitmaps (const CBitmapCacheKey &key, const BOOL bOpaqueOnly=FALSE, const INT32 maxpriority=1000)
 Removes all bitmaps from the cache that have the owner specified in the key...
void RemoveLowPriorityBitmaps (const INT32 maxpriority=1000)
 

CCachedBitmap FindNextOwnedBitmap (CCacheKeyMap::iterator &pos, CBitmapCacheKey &key, const BOOL bOpaqueOnly=FALSE, const INT32 maxpriority=1000)
 Removes all bitmaps from the cache that have the owner specified in the key...
void SetMaximumDataSize (UINT64 maxsize)
 

UINT64 GetMaximumDataSize ()
 

UINT32 GetCurrentDataSize ()
 

BOOL Lookup (const CBitmapCacheKey &Key, CCachedBitmap &CachedBitmap)
CCacheKeyMap::iterator GetStartPosition ()

Static Public Member Functions

static UINT64 CalcRecommendedMaximumDataSize ()
 Work out how much RAM this machine can afford to devote to the bitmap cache. Never use more than 50% of physical RAM Never use more RAM than is free Use CachRAMPercent preference to decide percentage of free ram to grab.

Private Member Functions

CCachedBitmap RemoveRandomBitmap (const INT32 maxpriority=1000)
 Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!! NOTE! This routine only uses the primary association array of the hash table The chains of values stored in the same slot are ignored at first (but obviously will be considered later on if their head item has been removed).

Private Attributes

CCacheKeyMap m_map
UINT64 m_lMaxDataSize
UINT32 m_lCurrentDataSize
UINT32 m_lMaxHashTableLoad

Static Private Attributes

static INT32 CacheRAMPercent = 25
 How much RAM to devote to cacheing bitmaps.


Detailed Description

Definition at line 162 of file bitmapcache.h.


Constructor & Destructor Documentation

CBitmapCache::CBitmapCache  ) 
 

Definition at line 130 of file bitmapcache.cpp.

00131 {
00132     m_lMaxDataSize = 0;
00133     m_lCurrentDataSize = 0;
00134     m_lMaxHashTableLoad = 0;
00135 }


Member Function Documentation

UINT64 CBitmapCache::CalcRecommendedMaximumDataSize  )  [static]
 

Work out how much RAM this machine can afford to devote to the bitmap cache. Never use more than 50% of physical RAM Never use more RAM than is free Use CachRAMPercent preference to decide percentage of free ram to grab.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
Recommended max cache size in current memory environment

Errors: -

See also:
-

Definition at line 713 of file bitmapcache.cpp.

00714 {
00715     UINT64      ullPhysRAM = 0;
00716     UINT32      LoadPercentage = 0;
00717 
00718     GetMemoryStatus(&ullPhysRAM, &LoadPercentage);
00719 
00720     // Don't use more than 50% of physical ram in the Bitmap Cache
00721     if (LoadPercentage<50) LoadPercentage = 50;     // If <50% in use pretend that 50% is used (never use more than 50%)
00722     return ullPhysRAM * (100-LoadPercentage) * CacheRAMPercent / 10000;
00723 }

void CBitmapCache::DeInitialise  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 190 of file bitmapcache.cpp.

00191 {
00192     // Get rid of all cached bitmaps...
00193 /*  POSITION pos = GetStartPosition();
00194     while (pos)
00195     {
00196         CBitmapCacheKey key;
00197         CCachedBitmap bitmap;
00198         GetNextAssoc(pos, key, bitmap);
00199 
00200         RemoveKey(key);
00201         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00202         FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00203     }
00204 */  CCacheKeyMap::iterator pos;
00205     for ( pos=m_map.begin() ; pos!=m_map.end() ; pos++ )
00206     {
00207         CBitmapCacheKey key = pos->first;
00208         CCachedBitmap bitmap = pos->second;
00209 //      m_map.erase(key);
00210         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00211         FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00212     }
00213     m_map.clear();
00214 }

CCachedBitmap CBitmapCache::FindNextOwnedBitmap CCacheKeyMap::iterator &  pos,
CBitmapCacheKey key,
const BOOL  bOpaqueOnly = FALSE,
const INT32  maxpriority = 1000
 

Removes all bitmaps from the cache that have the owner specified in the key...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
key [INPUTS]
- [OUTPUTS]
Returns:
TRUE is removed one or more bitmap associated with the owner of this key FALSE otherwise

Errors: -

See also:
-

Definition at line 577 of file bitmapcache.cpp.

00581 {
00582 //  BOOL bRemovedSome = FALSE;
00583     CCachedBitmap abitmap;
00584 
00585     if (!key.IsValid())
00586         return abitmap;
00587 
00588     if (m_map.size()==0)
00589         return abitmap;
00590 
00591     // Use the owner information stored in the keys to find all bitmap entries
00592     // in the hash table with the same owner...
00593 /*  while (pos)
00594     {
00595         CBitmapCacheKey akey;
00596         GetNextAssoc(pos, akey, abitmap);
00597 
00598         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00599         {
00600             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00601             {
00602                 key = akey;         // Return the key we found
00603                 return abitmap;     // along with the bitmap we found
00604             }
00605         }
00606     }
00607 */
00608     while (pos!=m_map.end())
00609     {
00610         CBitmapCacheKey akey = pos->first;
00611         CCachedBitmap abitmap = pos->second;
00612         pos++;
00613         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00614         {
00615             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00616             {
00617                 key = akey;         // Return the key we found
00618                 return abitmap;     // along with the bitmap we found
00619             }
00620         }
00621     }
00622 
00623     return CCachedBitmap();
00624 }

UINT32 CBitmapCache::GetCurrentDataSize  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 687 of file bitmapcache.cpp.

00688 {
00689     return m_lCurrentDataSize;
00690 }

UINT64 CBitmapCache::GetMaximumDataSize  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 665 of file bitmapcache.cpp.

00666 {
00667     return m_lMaxDataSize;
00668 }

CCacheKeyMap::iterator CBitmapCache::GetStartPosition  )  [inline]
 

Definition at line 203 of file bitmapcache.h.

00203 {return m_map.begin();}

void CBitmapCache::Initialise  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 154 of file bitmapcache.cpp.

00155 {
00156     // Declare the section that the magnetic options will live in
00157     BOOL Worked = Camelot.DeclareSection(TEXT("Cache"), 2);
00158 
00159     // declare the 2 prefs that there are
00160     if (Worked) Camelot.DeclarePref(TEXT("Cache"), TEXT("CacheRAMPercent"), &CacheRAMPercent, 0, 200);
00161 
00162     // Set up the default maximum cache size
00163     m_lMaxDataSize = CalcRecommendedMaximumDataSize();
00164 TRACEUSER( "Phil", _T("Recommended Cache Size = %I64d\n"), m_lMaxDataSize);
00165 
00166     // Make the hash table big enough for however many average 80*80*32BPP pixel bitmaps
00167     // will fit into the configured maximum cache size. Make the hash table twice that size
00168     // to keep it sparse and thus running more efficiently and ensure that it's prime.
00169     m_lMaxHashTableLoad = (UINT32) m_lMaxDataSize/(80*80*4);
00170 //  InitHashTable(PrimeAbove(m_lMaxHashTableLoad*2), TRUE);
00171 }

BOOL CBitmapCache::Lookup const CBitmapCacheKey Key,
CCachedBitmap CachedBitmap
[inline]
 

Definition at line 193 of file bitmapcache.h.

00194     {
00195         CCacheKeyMap::iterator iter = m_map.find( Key );
00196         if( m_map.end() == iter )
00197             return false;
00198         
00199         CachedBitmap = iter->second;
00200         return true;
00201     }

BOOL CBitmapCache::RemoveAllOwnedBitmaps const CBitmapCacheKey key,
const BOOL  bOpaqueOnly = FALSE,
const INT32  maxpriority = 1000
 

Removes all bitmaps from the cache that have the owner specified in the key...

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
key [INPUTS]
- [OUTPUTS]
Returns:
TRUE if removed one or more bitmap associated with the owner of this key FALSE otherwise

Errors: -

See also:
-

Definition at line 502 of file bitmapcache.cpp.

00505 {
00506     BOOL bRemovedSome = FALSE;
00507     CCachedBitmap abitmap;
00508 
00509     if (!key.IsValid())
00510         return FALSE;
00511 
00512     if (m_map.size()==0)
00513         return FALSE;
00514 
00515     // Use the owner information stored in the keys to find all bitmap entries
00516     // in the hash table with the same owner...
00517 /*  POSITION pos = GetStartPosition();
00518     while (pos)
00519     {
00520         CBitmapCacheKey akey;
00521         GetNextAssoc(pos, akey, abitmap);
00522 
00523         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00524         {
00525             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00526             {
00527                 RemoveKey(akey);
00528                 m_lCurrentDataSize -= abitmap.GetBitmapSize();
00529                 FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits);
00530                 bRemovedSome = TRUE;
00531             }
00532         }
00533     }
00534 */  CCacheKeyMap::iterator pos;
00535     for ( pos=m_map.begin() ; pos!=m_map.end() ; )
00536     {
00537         CBitmapCacheKey akey = pos->first;
00538         CCachedBitmap abitmap = pos->second;
00539         pos++;
00540         if (akey.pOwner == key.pOwner && abitmap.nPriority <= maxpriority)
00541         {
00542             if (bOpaqueOnly==FALSE || !abitmap.IsTransparent())
00543             {
00544                 m_map.erase(akey);
00545                 m_lCurrentDataSize -= abitmap.GetBitmapSize();
00546                 FreeDIB(abitmap.pbmpInfo, abitmap.pbmpBits);
00547                 bRemovedSome = TRUE;
00548             }
00549         }
00550     }
00551 
00552     return bRemovedSome;
00553 }

CCachedBitmap CBitmapCache::RemoveBitmap const CBitmapCacheKey key  ) 
 

Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!!

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
key [INPUTS]
- [OUTPUTS]
Returns:
Pointer to bitmap or NULL if not found

Errors: -

See also:
-

Definition at line 359 of file bitmapcache.cpp.

00360 {
00361     CCachedBitmap bitmap;
00362 
00363     if (m_map.size()==0)
00364             return bitmap;
00365 
00366     if (key.IsValid())
00367     {
00368         // Then we must remove the specified bitmap from the cache
00369         if (Lookup(key, bitmap))
00370         {
00371             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00372             m_map.erase(key);
00373 //          RemoveKey(key);
00374         }
00375     }
00376 
00377     return bitmap;
00378 }

void CBitmapCache::RemoveLowPriorityBitmaps const INT32  maxpriority = 1000  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/09/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 233 of file bitmapcache.cpp.

00234 {
00235     // Get rid of all cached bitmaps...
00236 /*  POSITION pos = GetStartPosition();
00237     while (pos)
00238     {
00239         CBitmapCacheKey key;
00240         CCachedBitmap bitmap;
00241         GetNextAssoc(pos, key, bitmap);
00242 
00243         if (bitmap.nPriority <= maxpriority)
00244         {
00245             RemoveKey(key);
00246             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00247             FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00248         }
00249     }
00250 */  CCacheKeyMap::iterator pos;
00251     for ( pos=m_map.begin() ; pos!=m_map.end() ; )
00252     {
00253         CBitmapCacheKey key = pos->first;
00254         CCachedBitmap bitmap = pos->second;
00255         pos++;
00256         if (bitmap.nPriority <= maxpriority)
00257         {
00258             m_map.erase(key);
00259             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00260             FreeDIB(bitmap.pbmpInfo, bitmap.pbmpBits);
00261         }
00262     }
00263 }

CCachedBitmap CBitmapCache::RemoveRandomBitmap const INT32  maxpriority = 1000  )  [private]
 

Removes either the specified bitmap from the cache or a selected bitmap according to the removal policy NOTE! It's up to the caller to delete the bitmap returned!!! NOTE! This routine only uses the primary association array of the hash table The chains of values stored in the same slot are ignored at first (but obviously will be considered later on if their head item has been removed).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
key [INPUTS]
- [OUTPUTS]
Returns:
Pointer to bitmap or NULL if not found

Errors: -

See also:
-

Definition at line 403 of file bitmapcache.cpp.

00404 {
00405 //  ENSURE(m_nHashTableSize!=0, "Zero-sized hash table found in RemoveRandomBitmap\n");
00406 /*
00407     // Implement cache removal policy - remove a random bitmap
00408     //
00409     // Select a bitmap of our choosing for removal
00410     // The removal policy is random (ish)
00411     // Must be Order(0) complexity
00412     //
00413     CCachedBitmap bitmap;
00414 
00415 
00416     UINT32 startitem = rand() % m_nHashTableSize;
00417     UINT32 item = startitem;
00418     CAssoc* pAssoc = NULL;
00419     do
00420     {
00421         pAssoc = m_pHashTable[item];
00422         item++;
00423         if (item==m_nHashTableSize)
00424             item = 0;
00425 
00426         // If we have found a value, check whether it's of equal or lesser "value"
00427         // than the one we're trying to store before throwing it out...
00428         if (pAssoc)
00429         {
00430 //          bitmap = (CCachedBitmap)pAssoc->value;      // Get value in a form we can use
00431             if (((CCachedBitmap)pAssoc->value).nPriority <= maxpriority)        // Check whether value's priority is <= priority limit
00432                 break;                                  // If so, we'll get rid of this one
00433             else
00434                 pAssoc = NULL;
00435         }
00436     }
00437     while (item != startitem);
00438 
00439     if (pAssoc)
00440     {
00441         // Remove the bitmap that we found from the cache...
00442         bitmap = (CCachedBitmap)pAssoc->value;
00443         m_lCurrentDataSize -= bitmap.GetBitmapSize();
00444         RemoveKey(pAssoc->key);
00445     }
00446 
00447     return bitmap;
00448 */
00449     // Implement cache removal policy - remove a random bitmap
00450     //
00451     // Select a bitmap of our choosing for removal
00452     // The removal policy is random (ish)
00453     // Must be Order(0) complexity
00454     //
00455     // Pick a random start point iterate
00456     // through the map from there...
00457     //
00458     srand((unsigned)time(NULL));
00459     UINT32 item = rand()%(UINT32)m_map.size();
00460     CCacheKeyMap::iterator pos;
00461     for ( pos=m_map.begin() ; item-- ; pos++ )
00462         ;
00463     CCacheKeyMap::iterator spos = pos;
00464     do
00465     {
00466         if ( pos==m_map.end() )
00467             pos = m_map.begin() ;
00468         CBitmapCacheKey key = pos->first;
00469         CCachedBitmap bitmap = pos->second;
00470         if ( bitmap.nPriority<=maxpriority )        // Check whether value's priority is <= priority limit
00471         {
00472             m_lCurrentDataSize -= bitmap.GetBitmapSize();
00473             m_map.erase(key);
00474             return bitmap;
00475         }
00476         pos++;
00477     } while ( pos!=spos );
00478     return m_map.begin()->second;
00479 }

void CBitmapCache::SetMaximumDataSize UINT64  maxsize  ) 
 

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 643 of file bitmapcache.cpp.

00644 {
00645     m_lMaxDataSize = maxsize;
00646 }

void CBitmapCache::StoreBitmap const CBitmapCacheKey key,
const CCachedBitmap bitmap
 

Places a bitmap in the cache (making room if necessary by removing others).

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
11/06/2004
Parameters:
key [INPUTS] Bitmap
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 283 of file bitmapcache.cpp.

00284 {
00285 /*
00286 #if _DEBUG
00287     if ((UINT32)m_nCount >= m_lMaxHashTableLoad)
00288     {
00289         TRACE( _T("BitmapCache hash table moving into inefficient zone!\n"));
00290 //      ERROR3("BitmapCache hash table moving into inefficient zone\n");
00291     }
00292 #endif
00293 */
00294 //  ENSURE(bitmap.rectCachedRect.IsValid(), "Invalid rect in CBitmapCache::StoreBitmap");
00295     ENSURE(bitmap.pbmpInfo->bmiHeader.biCompression==BI_RGB || bitmap.pbmpInfo->bmiHeader.biCompression==0x80000001,
00296             "Invalid compression type in StoreBitmap");
00297 
00298     // Remove the previous entry for this key, if there was one...
00299     CCachedBitmap cbmp = RemoveBitmap(key);                                 // Watch out - doesn't release bitmap memory!
00300     if (bitmap.pbmpBits!=cbmp.pbmpBits && bitmap.pbmpInfo!=cbmp.pbmpInfo)   // Only release the bitmap if we're not still using it
00301         cbmp.Release();                                                     // But this does!
00302 
00303     UINT32 newitemsize = bitmap.GetBitmapSize();
00304     UINT32 priority = bitmap.nPriority;
00305     while ((UINT64)(m_lCurrentDataSize+newitemsize) > m_lMaxDataSize)
00306     {
00307         CCachedBitmap cbmp = RemoveRandomBitmap(priority);                  // Remove random bitmap from cache
00308         if (cbmp.IsValid())
00309         {
00310             ERROR3IF(bitmap.pbmpInfo==cbmp.pbmpInfo || bitmap.pbmpBits==cbmp.pbmpBits,
00311                      "RemoveRandomBitmap found the same bitmap we're trying to Store! Something's gone horribly wrong!\n");
00312             TRACE( _T("Removing bitmap to make room in cache!\n") );
00313             cbmp.Release();
00314         }
00315         else
00316         {
00317             // We have run out of room in the cache for this priority level
00318             TRACEUSER( "Phil", _T("Changing priority to make room in cache\n"));
00319             if (priority < CACHEPRIORITY_TEMPBITMAP_HIGH)
00320             {
00321                 // We can try to remove higher-priority temp bitmaps...
00322                 // (But not the very highest, permanent bitmaps...)
00323                 priority = CACHEPRIORITY_TEMPBITMAP_HIGH;
00324             }
00325             else
00326             {
00327                 // We have no more room to remove any temporary bitmaps
00328                 // ARGH!!!! Now what?
00329                 ERROR3("Bitmap Cache is full!");
00330                 break;                  // Just gobble up the user's memory!
00331             }
00332         }
00333     }
00334 
00335     m_lCurrentDataSize += newitemsize;
00336 //  SetAt(key, (CCachedBitmap)bitmap);
00337     m_map.insert(pair<CBitmapCacheKey, CCachedBitmap>(key,(CCachedBitmap)bitmap));
00338 }


Member Data Documentation

INT32 CBitmapCache::CacheRAMPercent = 25 [static, private]
 

How much RAM to devote to cacheing bitmaps.

Preference: Percentage of RAM devoted to cache Section: Cacheing Range: 0 - 100 (although greater values are acceptable)

See also:
-

Definition at line 223 of file bitmapcache.h.

UINT32 CBitmapCache::m_lCurrentDataSize [private]
 

Definition at line 219 of file bitmapcache.h.

UINT64 CBitmapCache::m_lMaxDataSize [private]
 

Definition at line 218 of file bitmapcache.h.

UINT32 CBitmapCache::m_lMaxHashTableLoad [private]
 

Definition at line 220 of file bitmapcache.h.

CCacheKeyMap CBitmapCache::m_map [private]
 

Definition at line 216 of file bitmapcache.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:51:56 2007 for Camelot by  doxygen 1.4.4