[Libreoffice-commits] core.git: sw/inc sw/source

Michael Meeks michael.meeks at collabora.com
Wed Jul 2 02:52:37 PDT 2014


 sw/inc/docstyle.hxx               |    6 ++++-
 sw/source/uibase/app/docstyle.cxx |   40 +++++++++++++++++++++++++++-----------
 2 files changed, 34 insertions(+), 12 deletions(-)

New commits:
commit 64b1566e55677217c9c0dd13e5fbf8faf40810f9
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Wed Jul 2 10:14:15 2014 +0100

    fdo#76260 - switch O(N^2) lookup in SwStyleSheetIterator to O(N)
    
    The SwStyleSheetIterator is called a lot on import of DOCX;
    potentially another N times - so this change saves 15%+ of load time,
    81bn cycles of 457bn to startup and load the document.
    
    Change-Id: I70ef0f1ebd3f4e05519be68c8a67f65b00f54719

diff --git a/sw/inc/docstyle.hxx b/sw/inc/docstyle.hxx
index 63a30e0..0862077 100644
--- a/sw/inc/docstyle.hxx
+++ b/sw/inc/docstyle.hxx
@@ -25,6 +25,7 @@
 #include <svl/style.hxx>
 #include <svl/itemset.hxx>
 #include "swdllapi.h"
+#include <boost/unordered_map.hpp>
 
 #include <vector>
 
@@ -141,10 +142,13 @@ class SwStyleSheetIterator : public SfxStyleSheetIterator, public SfxListener
     class SwPoolFmtList
     {
         std::vector<OUString> maImpl;
+        typedef boost::unordered_map<OUString, sal_uInt32, OUStringHash> UniqueHash;
+        UniqueHash maUnique;
+        void rehash();
     public:
         SwPoolFmtList() {}
         void Append( char cChar, const OUString& rStr );
-        void Erase() { maImpl.clear(); }
+        void clear() { maImpl.clear(); maUnique.clear(); }
         size_t size() { return maImpl.size(); }
         bool empty() { return maImpl.empty(); }
         sal_uInt32 FindName(SfxStyleFamily eFam, const OUString &rName);
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index 146022b..3f09c0f 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -321,31 +321,49 @@ sal_uInt32 SwStyleSheetIterator::SwPoolFmtList::FindName(SfxStyleFamily eFam,
             break;
         }
         const OUString sSrch = OUString(cStyle) + rName;
-        for(size_t i = 0; i < maImpl.size(); ++i)
-            if(maImpl[i] == sSrch)
-                return i;
+
+        UniqueHash::const_iterator it = maUnique.find(sSrch);
+        if (it != maUnique.end())
+        {
+            sal_uInt32 nIdx = it->second;
+            assert (nIdx < maImpl.size());
+            assert (maImpl.size() == maUnique.size());
+            return nIdx;
+        }
     }
     return SAL_MAX_UINT32;
 }
 
+void SwStyleSheetIterator::SwPoolFmtList::rehash()
+{
+    maUnique.clear();
+    for (size_t i = 0; i < maImpl.size(); i++)
+        maUnique[maImpl[i]] = i;
+    assert (maImpl.size() == maUnique.size());
+}
+
 void SwStyleSheetIterator::SwPoolFmtList::RemoveName(SfxStyleFamily eFam,
                                                      const OUString &rName)
 {
     sal_uInt32 nTmpPos = FindName( eFam, rName );
     if( nTmpPos < maImpl.size() )
         maImpl.erase(maImpl.begin() + nTmpPos);
+
+    // assumption: this seldom occurs, the iterator is built, then emptied.
+    rehash();
+    assert (maImpl.size() == maUnique.size());
 }
 
 // Add Strings to the list of templates
 void SwStyleSheetIterator::SwPoolFmtList::Append( char cChar, const OUString& rStr )
 {
     const OUString aStr = OUString(cChar) + rStr;
-    for(std::vector<OUString>::const_iterator i = maImpl.begin();
-        i != maImpl.end(); ++i)
-    {
-        if(*i == aStr)
-            return;
-    }
+
+    UniqueHash::const_iterator it = maUnique.find(aStr);
+    if (it != maUnique.end())
+        return;
+
+    maUnique[aStr] = (sal_uInt32)maImpl.size();
     maImpl.push_back(aStr);
 }
 
@@ -2553,7 +2571,7 @@ SfxStyleSheetBase*  SwStyleSheetIterator::First()
     // Delete old list
     bFirstCalled = true;
     nLastPos = 0;
-    aLst.Erase();
+    aLst.clear();
 
     // Delete current
     mxIterSheet->Reset();
@@ -3010,7 +3028,7 @@ void SwStyleSheetIterator::InvalidateIterator()
     // this iterator not use a map?
     bFirstCalled = false;
     nLastPos = 0;
-    aLst.Erase();
+    aLst.clear();
 }
 
 void SwStyleSheetIterator::Notify( SfxBroadcaster&, const SfxHint& rHint )


More information about the Libreoffice-commits mailing list