Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


fdo#48932 is a large 7000 page document which reacts very slowly on text
input and scrolling around. It appears to be mostly managing the
header/footer and page break indicators which makes it sluggish

b63766b3dd453a82f59db505c736d861f662cc0f make it fast again, and seem to
have no side efforts. Though I'd like to have someone else verify that.

Attached is a backport to 3-5 to apply cleanly.

C.
From 4bada122523dfaf4441341e0f86b1ba98b5ce3b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Thu, 24 May 2012 08:57:17 +0100
Subject: [PATCH] Resolves: fdo#48932 super slow typing and scrolling in large
 documents

AFAICS it appears that theres a one to one mapping from a SwFrameControl to
a SwFrm, so in any of the three given classes of Page, Footer or Header a
SwFrm will have zero or one SwFrameControls and a SwFrameControl doesn't
get rebound to a different SwFrm or anything like that, so we can use
a map and index off the SwFrm* to find them rather than constantly
looping over vectors to find the right one.

Maybe could move the SwFrameControl directly in the SwPageFrm's
themselves.

Change-Id: I4de0a34f657143ef2d4409b604cc8e114dad132f
---
 sw/source/ui/docvw/FrameControlsManager.cxx |  110 ++++++++-------------------
 sw/source/ui/inc/FrameControlsManager.hxx   |    6 +-
 2 files changed, 37 insertions(+), 79 deletions(-)

diff --git a/sw/source/ui/docvw/FrameControlsManager.cxx 
b/sw/source/ui/docvw/FrameControlsManager.cxx
index 5c00b58..1413942 100644
--- a/sw/source/ui/docvw/FrameControlsManager.cxx
+++ b/sw/source/ui/docvw/FrameControlsManager.cxx
@@ -37,21 +37,6 @@
 
 using namespace std;
 
-namespace
-{
-    class FramePredicate
-    {
-        const SwFrm* m_pToMatch;
-
-        public:
-            FramePredicate( const SwFrm* pFrm ) : m_pToMatch( pFrm ) { };
-            virtual ~FramePredicate() {};
-
-            virtual bool operator()( SwFrameControlPtr pToCheck )
-                { return m_pToMatch == pToCheck->GetFrame(); };
-    };
-}
-
 SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
     m_pEditWin( pEditWin ),
     m_aControls( )
@@ -60,14 +45,6 @@ SwFrameControlsManager::SwFrameControlsManager( SwEditWin* pEditWin ) :
 
 SwFrameControlsManager::~SwFrameControlsManager()
 {
-    map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
-
-    while ( pIt != m_aControls.end() )
-    {
-        pIt->second.clear( );
-        ++pIt;
-    }
-    m_aControls.clear();
 }
 
 SwFrameControlsManager::SwFrameControlsManager( const SwFrameControlsManager& rCopy ) :
@@ -85,75 +62,66 @@ const SwFrameControlsManager& SwFrameControlsManager::operator=( const SwFrameCo
 
 SwFrameControlPtr SwFrameControlsManager::GetControl( FrameControlType eType, const SwFrm* pFrm )
 {
-    SwFrameControlPtr pControl;
-
-    vector< SwFrameControlPtr >& aControls = m_aControls[eType];
+    SwFrameControlPtrMap& rControls = m_aControls[eType];
 
-    vector< SwFrameControlPtr >::iterator pIt = find_if(
-            aControls.begin(), aControls.end( ), FramePredicate( pFrm ) );
+    SwFrameControlPtrMap::iterator aIt = rControls.find(pFrm);
 
-    if ( pIt != aControls.end() )
-        pControl = *pIt;
+    if (aIt != rControls.end())
+        return aIt->second;
 
-    return pControl;
+    return SwFrameControlPtr();
 }
 
-std::vector< SwFrameControlPtr >& SwFrameControlsManager::GetControls( FrameControlType eType )
+SwFrameControlPtrMap& SwFrameControlsManager::GetControls( FrameControlType eType )
 {
     return m_aControls[eType];
 }
 
 void SwFrameControlsManager::AddControl( FrameControlType eType, SwFrameControlPtr pControl )
 {
-    m_aControls[eType].push_back( pControl );
+    m_aControls[eType].insert(make_pair(pControl->GetFrame(), pControl));
 }
 
 void SwFrameControlsManager::RemoveControls( const SwFrm* pFrm )
 {
-    map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
+    map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
 
     while ( pIt != m_aControls.end() )
     {
-        vector< SwFrameControlPtr >& aVect = pIt->second;
-        aVect.erase( remove_if( aVect.begin(),
-                                aVect.end(),
-                                FramePredicate( pFrm ) ), aVect.end() );
+        SwFrameControlPtrMap& rMap = pIt->second;
+        rMap.erase(pFrm);
         ++pIt;
     }
 }
 
 void SwFrameControlsManager::RemoveControlsByType( FrameControlType eType, const SwFrm* pFrm )
 {
-    vector< SwFrameControlPtr >& aVect = m_aControls[eType];
-    aVect.erase( remove_if( aVect.begin(),
-                            aVect.end(),
-                            FramePredicate( pFrm ) ), aVect.end() );
+    SwFrameControlPtrMap& rMap = m_aControls[eType];
+    rMap.erase(pFrm);
 }
 
-
 void SwFrameControlsManager::HideControls( FrameControlType eType )
 {
-    vector< SwFrameControlPtr >::iterator pIt = m_aControls[eType].begin();
+    SwFrameControlPtrMap::iterator pIt = m_aControls[eType].begin();
     while ( pIt != m_aControls[eType].end() )
     {
-        ( *pIt )->ShowAll( false );
-        pIt++;
+        pIt->second->ShowAll( false );
+        ++pIt;
     }
 }
 
 void SwFrameControlsManager::SetReadonlyControls( bool bReadonly )
 {
-    map< FrameControlType, vector< SwFrameControlPtr > >::iterator pIt = m_aControls.begin();
+    map< FrameControlType, SwFrameControlPtrMap >::iterator pIt = m_aControls.begin();
 
     while ( pIt != m_aControls.end() )
     {
-        vector< SwFrameControlPtr >::iterator pVectIt = pIt->second.begin();
-        while ( pVectIt != pIt->second.end() )
+        SwFrameControlPtrMap::iterator aCtrlIt = pIt->second.begin();
+        while ( aCtrlIt != pIt->second.end() )
         {
-            ( *pVectIt )->SetReadonly( bReadonly );
-            ++pVectIt;
+            aCtrlIt->second->SetReadonly( bReadonly );
+            ++aCtrlIt;
         }
-        ++pIt;
     }
 }
 
@@ -165,30 +133,24 @@ void SwFrameControlsManager::SetHeaderFooterControl( const SwPageFrm* 
pPageFrm,
     SwFrameControlPtr pControl;
     const bool bHeader = ( eType == Header );
 
-    vector< SwFrameControlPtr >& aControls = m_aControls[eType];
+    SwFrameControlPtrMap& rControls = m_aControls[eType];
 
-    vector< SwFrameControlPtr >::iterator pIt = aControls.begin();
-    while ( pIt != aControls.end() && !pControl.get() )
-    {
-        SwHeaderFooterWin* pToTest = dynamic_cast< SwHeaderFooterWin* >( pIt->get() );
-        if ( pToTest->GetPageFrame( ) == pPageFrm &&
-             pToTest->IsHeader( ) == bHeader )
-            pControl = *pIt;
-        pIt++;
-    }
-
-    if ( !pControl.get() )
+    SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+    if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+        pControl = lb->second;
+    else
     {
         SwFrameControlPtr pNewControl( new SwHeaderFooterWin( m_pEditWin, pPageFrm, bHeader ) );
         const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
         pNewControl->SetReadonly( pViewOpt->IsReadonly() );
-        AddControl( eType, pNewControl );
+        rControls.insert(lb, make_pair(pPageFrm, pNewControl));
         pControl.swap( pNewControl );
     }
 
     Rectangle aPageRect = m_pEditWin->LogicToPixel( pPageFrm->Frm().SVRect() );
 
     SwHeaderFooterWin* pHFWin = dynamic_cast< SwHeaderFooterWin* >( pControl.get() );
+    assert(pHFWin->IsHeader() == bHeader);
     pHFWin->SetOffset( aOffset, aPageRect.Left(), aPageRect.Right() );
 
     if ( !pHFWin->IsVisible() )
@@ -200,23 +162,17 @@ void SwFrameControlsManager::SetPageBreakControl( const SwPageFrm* pPageFrm )
     // Check if we already have the control
     SwFrameControlPtr pControl;
 
-    vector< SwFrameControlPtr >& aControls = m_aControls[PageBreak];
-
-    vector< SwFrameControlPtr >::iterator pIt = aControls.begin();
-    while ( pIt != aControls.end() && !pControl.get() )
-    {
-        SwPageBreakWin* pToTest = dynamic_cast< SwPageBreakWin* >( pIt->get() );
-        if ( pToTest->GetPageFrame( ) == pPageFrm )
-            pControl = *pIt;
-        pIt++;
-    }
+    SwFrameControlPtrMap& rControls = m_aControls[PageBreak];
 
-    if ( !pControl.get() )
+    SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pPageFrm);
+    if (lb != rControls.end() && !(rControls.key_comp()(pPageFrm, lb->first)))
+        pControl = lb->second;
+    else
     {
         SwFrameControlPtr pNewControl( new SwPageBreakWin( m_pEditWin, pPageFrm ) );
         const SwViewOption* pViewOpt = m_pEditWin->GetView().GetWrtShell().GetViewOptions();
         pNewControl->SetReadonly( pViewOpt->IsReadonly() );
-        AddControl( PageBreak, pNewControl );
+        rControls.insert(lb, make_pair(pPageFrm, pNewControl));
         pControl.swap( pNewControl );
     }
 
diff --git a/sw/source/ui/inc/FrameControlsManager.hxx b/sw/source/ui/inc/FrameControlsManager.hxx
index 06e618c..d007362 100644
--- a/sw/source/ui/inc/FrameControlsManager.hxx
+++ b/sw/source/ui/inc/FrameControlsManager.hxx
@@ -42,13 +42,15 @@ class SwEditWin;
 
 typedef boost::shared_ptr< SwFrameControl > SwFrameControlPtr;
 
+typedef std::map<const SwFrm*, SwFrameControlPtr> SwFrameControlPtrMap;
+
 /** A container for the Header/Footer, or PageBreak controls.
 */
 class SwFrameControlsManager
 {
     private:
         SwEditWin* m_pEditWin;
-        std::map< FrameControlType, std::vector< SwFrameControlPtr > > m_aControls;
+        std::map< FrameControlType, SwFrameControlPtrMap > m_aControls;
 
     public:
         SwFrameControlsManager( SwEditWin* pEditWin );
@@ -58,7 +60,7 @@ class SwFrameControlsManager
         const SwFrameControlsManager& operator=( const SwFrameControlsManager& rCopy );
 
         SwFrameControlPtr GetControl( FrameControlType eType, const SwFrm* pFrm );
-        std::vector< SwFrameControlPtr >& GetControls( FrameControlType eType );
+        SwFrameControlPtrMap& GetControls( FrameControlType eType );
         void AddControl( FrameControlType eType, SwFrameControlPtr pControl );
         void RemoveControls( const SwFrm* pFrm );
         void RemoveControlsByType( FrameControlType eType, const SwFrm* pFrm );
-- 
1.7.7.6


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.