diff options
author | Michael Meeks <michael.meeks@suse.com> | 2012-09-20 11:52:49 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2012-09-20 11:54:42 +0100 |
commit | 540ab389f2adb021a95b5ac52c55c97fc5db5c17 (patch) | |
tree | ea58d76cc1e721384ce3c3d236c77c63c21ea59a /sot | |
parent | f3b2fc9be23739cec600b349e6b28b71be9acc3d (diff) |
sot: memory savings to avoid duplicating the whole stream in RAM
re-work LRU cache to really be an 8 entry LRU cache.
only force dirty pages to stay in memory, hopefully huge reads
should now stream through memory.
Change-Id: I0bedc762086f5f02202795568743750aefaaa50b
Diffstat (limited to 'sot')
-rw-r--r-- | sot/source/sdstor/stgcache.cxx | 67 | ||||
-rw-r--r-- | sot/source/sdstor/stgcache.hxx | 19 |
2 files changed, 52 insertions, 34 deletions
diff --git a/sot/source/sdstor/stgcache.cxx b/sot/source/sdstor/stgcache.cxx index 06a0ee062273..e787c087640a 100644 --- a/sot/source/sdstor/stgcache.cxx +++ b/sot/source/sdstor/stgcache.cxx @@ -88,14 +88,17 @@ sal_Int32 lcl_GetPageCount( sal_uLong nFileSize, short nPageSize ) } StgCache::StgCache() + : nError( SVSTREAM_OK ) + , nPages( 0 ) + , nRef( 0 ) + , nReplaceIdx( 0 ) + , maLRUPages( 8 ) // entries in the LRU lookup + , nPageSize( 512 ) + , pStorageStream( NULL ) + , pStrm( NULL ) + , bMyStream( sal_False ) + , bFile( sal_False ) { - nRef = 0; - pStrm = NULL; - nPageSize = 512; - nError = SVSTREAM_OK; - bMyStream = sal_False; - bFile = sal_False; - pStorageStream = NULL; } StgCache::~StgCache() @@ -122,7 +125,7 @@ void StgCache::SetPhysPageSize( short n ) rtl::Reference< StgPage > StgCache::Create( sal_Int32 nPg ) { rtl::Reference< StgPage > xElem( StgPage::Create( nPageSize, nPg ) ); - maLRUCache[ xElem->GetPage() ] = xElem; + maLRUPages[ nReplaceIdx++ % maLRUPages.size() ] = xElem; return xElem; } @@ -131,8 +134,14 @@ rtl::Reference< StgPage > StgCache::Create( sal_Int32 nPg ) void StgCache::Erase( const rtl::Reference< StgPage > &xElem ) { OSL_ENSURE( xElem.is(), "The pointer should not be NULL!" ); - if ( xElem.is() ) - maLRUCache.erase( xElem->GetPage() ); + if ( xElem.is() ) { + for ( LRUList::iterator it = maLRUPages.begin(); it != maLRUPages.end(); it++ ) { + if ( it->is() && (*it)->GetPage() == xElem->GetPage() ) { + it->clear(); + break; + } + } + } } // remove all cache elements without flushing them @@ -140,16 +149,20 @@ void StgCache::Erase( const rtl::Reference< StgPage > &xElem ) void StgCache::Clear() { maDirtyPages.clear(); - maLRUCache.clear(); + for ( LRUList::iterator it = maLRUPages.begin(); it != maLRUPages.end(); it++ ) + it->clear(); } // Look for a cached page rtl::Reference< StgPage > StgCache::Find( sal_Int32 nPage ) { - IndexToStgPage::iterator aIt = maLRUCache.find( nPage ); - if( aIt != maLRUCache.end() ) - return (*aIt).second; + for ( LRUList::iterator it = maLRUPages.begin(); it != maLRUPages.end(); it++ ) + if ( it->is() && (*it)->GetPage() == nPage ) + return *it; + IndexToStgPage::iterator it2 = maDirtyPages.find( nPage ); + if ( it2 != maDirtyPages.end() ) + return it2->second; return rtl::Reference< StgPage >(); } @@ -199,18 +212,21 @@ rtl::Reference< StgPage > StgCache::Copy( sal_Int32 nNew, sal_Int32 nOld ) // continue that tradition. sal_Bool StgCache::Commit() { - std::vector< StgPage * > aToWrite; - for ( IndexToStgPage::iterator aIt = maDirtyPages.begin(); - aIt != maDirtyPages.end(); aIt++ ) - aToWrite.push_back( aIt->second.get() ); - - std::sort( aToWrite.begin(), aToWrite.end(), StgPage::IsPageGreater ); - for (std::vector< StgPage * >::iterator aWr = aToWrite.begin(); - aWr != aToWrite.end(); aWr++) + if ( Good() ) // otherwise Write does nothing { - const rtl::Reference< StgPage > &pPage = *aWr; - if ( !Write( pPage->GetPage(), pPage->GetData(), 1 ) ) - return sal_False; + std::vector< StgPage * > aToWrite; + for ( IndexToStgPage::iterator aIt = maDirtyPages.begin(); + aIt != maDirtyPages.end(); aIt++ ) + aToWrite.push_back( aIt->second.get() ); + + std::sort( aToWrite.begin(), aToWrite.end(), StgPage::IsPageGreater ); + for ( std::vector< StgPage * >::iterator aWr = aToWrite.begin(); + aWr != aToWrite.end(); aWr++) + { + const rtl::Reference< StgPage > &pPage = *aWr; + if ( !Write( pPage->GetPage(), pPage->GetData(), 1 ) ) + return sal_False; + } } maDirtyPages.clear(); @@ -259,6 +275,7 @@ void StgCache::SetStrm( UCBStorageStream* pStgStream ) void StgCache::SetDirty( const rtl::Reference< StgPage > &xPage ) { + assert( IsWritable() ); maDirtyPages[ xPage->GetPage() ] = xPage; } diff --git a/sot/source/sdstor/stgcache.hxx b/sot/source/sdstor/stgcache.hxx index 268784683922..e134e2576258 100644 --- a/sot/source/sdstor/stgcache.hxx +++ b/sot/source/sdstor/stgcache.hxx @@ -33,20 +33,21 @@ class StgPage; class StgDirEntry; class StorageBase; -typedef boost::unordered_map -< - sal_Int32, - rtl::Reference< StgPage >, - boost::hash< sal_Int32 >, - std::equal_to< sal_Int32 > -> IndexToStgPage; - class StgCache { + typedef boost::unordered_map + < + sal_Int32, rtl::Reference< StgPage >, + boost::hash< sal_Int32 >, std::equal_to< sal_Int32 > + > IndexToStgPage; + + typedef std::vector< rtl::Reference< StgPage > > LRUList; + sal_uLong nError; // error code sal_Int32 nPages; // size of data area in pages sal_uInt16 nRef; // reference count IndexToStgPage maDirtyPages; // hash of all dirty pages - IndexToStgPage maLRUCache; // hash of index to cached pages + int nReplaceIdx; // index into maLRUPages to replace next + LRUList maLRUPages; // list of last few non-dirty pages. short nPageSize; // page size of the file UCBStorageStream* pStorageStream; // holds reference to UCB storage stream |