sot/source/sdstor/stgcache.cxx |   67 +++++++++++++++++++++++++----------------
 sot/source/sdstor/stgcache.hxx |   19 ++++++-----
 2 files changed, 52 insertions(+), 34 deletions(-)

New commits:
commit 540ab389f2adb021a95b5ac52c55c97fc5db5c17
Author: Michael Meeks <michael.me...@suse.com>
Date:   Thu Sep 20 11:52:49 2012 +0100

    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

diff --git a/sot/source/sdstor/stgcache.cxx b/sot/source/sdstor/stgcache.cxx
index 06a0ee0..e787c08 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 2687846..e134e25 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
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to