summaryrefslogtreecommitdiff
path: root/sot
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@suse.com>2012-09-20 11:52:49 +0100
committerMichael Meeks <michael.meeks@suse.com>2012-09-20 11:54:42 +0100
commit540ab389f2adb021a95b5ac52c55c97fc5db5c17 (patch)
treeea58d76cc1e721384ce3c3d236c77c63c21ea59a /sot
parentf3b2fc9be23739cec600b349e6b28b71be9acc3d (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.cxx67
-rw-r--r--sot/source/sdstor/stgcache.hxx19
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