[Libreoffice-commits] core.git: comphelper/source include/comphelper include/xmloff xmloff/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Mon May 13 11:23:40 UTC 2019


 comphelper/source/misc/anycompare.cxx |   11 +++
 include/comphelper/anycompare.hxx     |    4 +
 include/xmloff/xmlexppr.hxx           |    8 +-
 xmloff/source/style/impastpl.cxx      |  110 ++++++++++++----------------------
 xmloff/source/style/xmlexppr.cxx      |  101 ++++++++++++++++++++++---------
 5 files changed, 134 insertions(+), 100 deletions(-)

New commits:
commit 349919440b1454eda2de783a0c3e6bd3bae4542b
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Sat May 11 09:00:32 2019 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon May 13 13:23:00 2019 +0200

    tdf#107592 Impress PPS save to ODP slow
    
    Takes the time from 20s to 5s on my PC.
    
    Change-Id: Iea7a94ee9fbe068b69a770fd9201e73646be59b9
    Reviewed-on: https://gerrit.libreoffice.org/72140
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/comphelper/source/misc/anycompare.cxx b/comphelper/source/misc/anycompare.cxx
index 5a7859514ac9..f4d2a8b5d260 100644
--- a/comphelper/source/misc/anycompare.cxx
+++ b/comphelper/source/misc/anycompare.cxx
@@ -226,6 +226,17 @@ namespace comphelper
         return pComparator;
     }
 
+    bool anyLess( css::uno::Any const & lhs, css::uno::Any const & rhs)
+    {
+        auto lhsTypeClass = lhs.getValueType().getTypeClass();
+        auto rhsTypeClass = rhs.getValueType().getTypeClass();
+        if (lhsTypeClass != rhsTypeClass)
+            return lhsTypeClass < rhsTypeClass;
+        std::unique_ptr< IKeyPredicateLess > pred = getStandardLessPredicate( lhs.getValueType(), Reference< XCollator >() );
+        if (!pred) // type==VOID
+            return false;
+        return pred->isLess(lhs, rhs);
+    }
 
 } // namespace comphelper
 
diff --git a/include/comphelper/anycompare.hxx b/include/comphelper/anycompare.hxx
index dd92d2734ca2..8b5a941a781c 100644
--- a/include/comphelper/anycompare.hxx
+++ b/include/comphelper/anycompare.hxx
@@ -205,6 +205,10 @@ namespace comphelper
             css::uno::Reference< css::i18n::XCollator > const & i_collator
         );
 
+    /**
+        Compare two Anys.
+    */
+    bool COMPHELPER_DLLPUBLIC anyLess( css::uno::Any const & lhs, css::uno::Any const & rhs);
 
 } // namespace comphelper
 
diff --git a/include/xmloff/xmlexppr.hxx b/include/xmloff/xmlexppr.hxx
index 28be918474ee..84d2d60c2fb5 100644
--- a/include/xmloff/xmlexppr.hxx
+++ b/include/xmloff/xmlexppr.hxx
@@ -124,10 +124,14 @@ public:
     std::vector<XMLPropertyState> FilterDefaults(
         const css::uno::Reference<css::beans::XPropertySet>& rPropSet ) const;
 
-    /** Compare to arrays of XMLPropertyState */
-    bool Equals( const ::std::vector< XMLPropertyState >& aProperties1,
+    /** Provides a partial ordering over two arrays of XMLPropertyState,
+       Partial because implementing a full order requires quite a lot of code. */
+    bool LessPartial( const ::std::vector< XMLPropertyState >& aProperties1,
                      const ::std::vector< XMLPropertyState >& aProperties2 ) const;
 
+    /** Compare two arrays of XMLPropertyState */
+    bool Equals( const ::std::vector< XMLPropertyState >& aProperties1,
+                     const ::std::vector< XMLPropertyState >& aProperties2 ) const;
     void exportXML(
             SvXMLExport& rExport,
             const ::std::vector< XMLPropertyState >& rProperties,
diff --git a/xmloff/source/style/impastpl.cxx b/xmloff/source/style/impastpl.cxx
index 1b574adc8b97..c64a35d26141 100644
--- a/xmloff/source/style/impastpl.cxx
+++ b/xmloff/source/style/impastpl.cxx
@@ -270,39 +270,39 @@ XMLAutoStylePoolParent::~XMLAutoStylePoolParent()
 {
 }
 
+struct ComparePartial
+{
+    const XMLAutoStyleFamily& rFamilyData;
+
+    bool operator()(const vector< XMLPropertyState >& lhs,
+                    const std::unique_ptr<XMLAutoStylePoolProperties>& rhs) const
+    {
+        return rFamilyData.mxMapper->LessPartial(lhs, rhs->GetProperties());
+    }
+    bool operator()(const std::unique_ptr<XMLAutoStylePoolProperties>& lhs,
+                    const vector< XMLPropertyState >& rhs ) const
+    {
+        return rFamilyData.mxMapper->LessPartial(lhs->GetProperties(), rhs);
+    }
+};
+
 // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
 // if not added, yet.
 
 bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rName, bool bDontSeek )
 {
-    bool bAdded = false;
     XMLAutoStylePoolProperties *pProperties = nullptr;
-    sal_Int32 nProperties = rProperties.size();
-    size_t i = 0;
-    for (size_t n = m_PropertiesList.size(); i < n; ++i)
-    {
-        XMLAutoStylePoolProperties *const pIS = m_PropertiesList[i].get();
-        if( nProperties > static_cast<sal_Int32>(pIS->GetProperties().size()) )
-        {
-            continue;
-        }
-        else if( nProperties < static_cast<sal_Int32>(pIS->GetProperties().size()) )
-        {
-            break;
-        }
-        else if( !bDontSeek && rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
-        {
-            pProperties = pIS;
-            break;
-        }
-    }
+    auto [itBegin, itEnd] = std::equal_range(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
+    if (!bDontSeek)
+        for (auto it = itBegin; it != itEnd; ++it)
+            if (rFamilyData.mxMapper->Equals((*it)->GetProperties(), rProperties))
+                pProperties = it->get();
 
-    if( !pProperties )
+    bool bAdded = false;
+    if( bDontSeek || !pProperties )
     {
         pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
-        PropertiesListType::iterator it = m_PropertiesList.begin();
-        ::std::advance( it, i );
-        m_PropertiesList.insert(it, std::unique_ptr<XMLAutoStylePoolProperties>(pProperties));
+        m_PropertiesList.insert(itBegin, std::unique_ptr<XMLAutoStylePoolProperties>(pProperties));
         bAdded = true;
     }
 
@@ -319,35 +319,17 @@ bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector<
 
 bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, const OUString& rName )
 {
-    bool bAdded = false;
-    sal_Int32 nProperties = rProperties.size();
-    size_t i = 0;
-    for (size_t n = m_PropertiesList.size(); i < n; ++i)
-    {
-        XMLAutoStylePoolProperties *const pIS = m_PropertiesList[i].get();
-        if( nProperties > static_cast<sal_Int32>(pIS->GetProperties().size()) )
-        {
-            continue;
-        }
-        else if( nProperties < static_cast<sal_Int32>(pIS->GetProperties().size()) )
-        {
-            break;
-        }
-    }
-
-    if (rFamilyData.maNameSet.find(rName) == rFamilyData.maNameSet.end())
-    {
-        std::unique_ptr<XMLAutoStylePoolProperties> pProperties(
-            new XMLAutoStylePoolProperties(rFamilyData, rProperties, msParent));
-        // ignore the generated name
-        pProperties->SetName( rName );
-        PropertiesListType::iterator it = m_PropertiesList.begin();
-        ::std::advance( it, i );
-        m_PropertiesList.insert(it, std::move(pProperties));
-        bAdded = true;
-    }
-
-    return bAdded;
+    if (rFamilyData.maNameSet.find(rName) != rFamilyData.maNameSet.end())
+        return false;
+    
+    auto it = std::lower_bound(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
+
+    std::unique_ptr<XMLAutoStylePoolProperties> pProperties(
+        new XMLAutoStylePoolProperties(rFamilyData, rProperties, msParent));
+    // ignore the generated name
+    pProperties->SetName( rName );
+    m_PropertiesList.insert(it, std::move(pProperties));
+    return true;
 }
 
 
@@ -357,24 +339,10 @@ bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const ve
 OUString XMLAutoStylePoolParent::Find( const XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) const
 {
     OUString sName;
-    vector< XMLPropertyState>::size_type nItems = rProperties.size();
-    for (const auto & i : m_PropertiesList)
-    {
-        const XMLAutoStylePoolProperties *const pIS = i.get();
-        if( nItems > pIS->GetProperties().size() )
-        {
-            continue;
-        }
-        else if( nItems < pIS->GetProperties().size() )
-        {
-            break;
-        }
-        else if( rFamilyData.mxMapper->Equals( pIS->GetProperties(), rProperties ) )
-        {
-            sName = pIS->GetName();
-            break;
-        }
-    }
+    auto [itBegin,itEnd] = std::equal_range(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
+    for (auto it = itBegin; it != itEnd; ++it)
+        if (rFamilyData.mxMapper->Equals((*it)->GetProperties(), rProperties))
+            sName = (*it)->GetName();
 
     return sName;
 }
diff --git a/xmloff/source/style/xmlexppr.cxx b/xmloff/source/style/xmlexppr.cxx
index 63994492afbc..aa465016bb7f 100644
--- a/xmloff/source/style/xmlexppr.cxx
+++ b/xmloff/source/style/xmlexppr.cxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
 #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
 #include <rtl/ustrbuf.hxx>
+#include <comphelper/anycompare.hxx>
 #include <cppuhelper/weakref.hxx>
 #include <osl/diagnose.h>
 #include <list>
@@ -655,44 +656,90 @@ bool SvXMLExportPropertyMapper::Equals(
         const vector< XMLPropertyState >& aProperties1,
         const vector< XMLPropertyState >& aProperties2 ) const
 {
-    bool bRet = true;
+    if (aProperties1.size() < aProperties2.size())
+        return true;
+    if (aProperties1.size() > aProperties2.size())
+        return false;
+
     sal_uInt32 nCount = aProperties1.size();
 
-    if( nCount == aProperties2.size() )
+    for (sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex)
     {
-        sal_uInt32 nIndex = 0;
-        while( bRet && nIndex < nCount )
-        {
-            const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
-            const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
+        const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
+        const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
 
-            // Compare index. If equal, compare value
-            if( rProp1.mnIndex == rProp2.mnIndex )
+        // Compare index. If equal, compare value
+        if( rProp1.mnIndex < rProp2.mnIndex )
+            return true;
+        if( rProp1.mnIndex > rProp2.mnIndex )
+            return false;
+
+        if( rProp1.mnIndex != -1 )
+        {
+            // Now compare values
+            if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
+                  XML_TYPE_BUILDIN_CMP ) != 0 )
             {
-                if( rProp1.mnIndex != -1 )
-                {
-                    // Now compare values
-                    if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
-                          XML_TYPE_BUILDIN_CMP ) != 0 )
-                        // simple type ( binary compare )
-                        bRet = ( rProp1.maValue == rProp2.maValue );
-                    else
-                        // complex type ( ask for compare-function )
-                        bRet = mpImpl->mxPropMapper->GetPropertyHandler(
-                                    rProp1.mnIndex )->equals( rProp1.maValue,
-                                                              rProp2.maValue );
-                }
+                // simple type ( binary compare )
+                if ( rProp1.maValue != rProp2.maValue)
+                    return false;
             }
             else
-                bRet = false;
+            {
+                // complex type ( ask for compare-function )
+                if (!mpImpl->mxPropMapper->GetPropertyHandler(
+                            rProp1.mnIndex )->equals( rProp1.maValue,
+                                                      rProp2.maValue ))
+                    return false;
+            }
+        }
+    }
+
+    return true;
+}
 
-            nIndex++;
+// Compares two Sequences of XMLPropertyState:
+//  1.Number of elements equal ?
+//  2.Index of each element equal ? (So I know whether the propertynames are the same)
+//  3.Value of each element equal ?
+bool SvXMLExportPropertyMapper::LessPartial(
+        const vector< XMLPropertyState >& aProperties1,
+        const vector< XMLPropertyState >& aProperties2 ) const
+{
+    if (aProperties1.size() < aProperties2.size())
+        return true;
+    if (aProperties1.size() > aProperties2.size())
+        return false;
+
+    sal_uInt32 nCount = aProperties1.size();
+
+    for (sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex)
+    {
+        const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
+        const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
+
+        // Compare index. If equal, compare value
+        if( rProp1.mnIndex < rProp2.mnIndex )
+            return true;
+        if( rProp1.mnIndex > rProp2.mnIndex )
+            return false;
+
+        if( rProp1.mnIndex != -1 )
+        {
+            // Now compare values
+            if ( (mpImpl->mxPropMapper->GetEntryType( rProp1.mnIndex ) &
+                  XML_TYPE_BUILDIN_CMP ) != 0 )
+            {
+                // simple type ( binary compare )
+                if ( comphelper::anyLess(rProp1.maValue, rProp2.maValue) )
+                    return true;
+                if ( comphelper::anyLess(rProp2.maValue, rProp1.maValue ) )
+                    return false;
+            }
         }
     }
-    else
-        bRet = false;
 
-    return bRet;
+    return false;
 }
 
 /** fills the given attribute list with the items in the given set


More information about the Libreoffice-commits mailing list