summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-05-11 09:00:32 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-05-13 13:23:00 +0200
commit349919440b1454eda2de783a0c3e6bd3bae4542b (patch)
treeb342e251509c1dc7fbee7971b98e21362b83b9af
parentb2fc2ad7beceaff660de684435a5c37d69cf8ae9 (diff)
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@collabora.co.uk>
-rw-r--r--comphelper/source/misc/anycompare.cxx11
-rw-r--r--include/comphelper/anycompare.hxx4
-rw-r--r--include/xmloff/xmlexppr.hxx8
-rw-r--r--xmloff/source/style/impastpl.cxx110
-rw-r--r--xmloff/source/style/xmlexppr.cxx101
5 files changed, 134 insertions, 100 deletions
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