Kaydet (Commit) 34991944 authored tarafından Noel Grandin's avatar Noel Grandin

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: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst b2fc2ad7
...@@ -226,6 +226,17 @@ namespace comphelper ...@@ -226,6 +226,17 @@ namespace comphelper
return pComparator; 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 } // namespace comphelper
......
...@@ -205,6 +205,10 @@ namespace comphelper ...@@ -205,6 +205,10 @@ namespace comphelper
css::uno::Reference< css::i18n::XCollator > const & i_collator 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 } // namespace comphelper
......
...@@ -124,10 +124,14 @@ public: ...@@ -124,10 +124,14 @@ public:
std::vector<XMLPropertyState> FilterDefaults( std::vector<XMLPropertyState> FilterDefaults(
const css::uno::Reference<css::beans::XPropertySet>& rPropSet ) const; const css::uno::Reference<css::beans::XPropertySet>& rPropSet ) const;
/** Compare to arrays of XMLPropertyState */ /** Provides a partial ordering over two arrays of XMLPropertyState,
bool Equals( const ::std::vector< XMLPropertyState >& aProperties1, 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; 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( void exportXML(
SvXMLExport& rExport, SvXMLExport& rExport,
const ::std::vector< XMLPropertyState >& rProperties, const ::std::vector< XMLPropertyState >& rProperties,
......
...@@ -270,39 +270,39 @@ XMLAutoStylePoolParent::~XMLAutoStylePoolParent() ...@@ -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 // Adds a array of XMLPropertyState ( vector< XMLPropertyState > ) to list
// if not added, yet. // if not added, yet.
bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rName, bool bDontSeek ) bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rName, bool bDontSeek )
{ {
bool bAdded = false;
XMLAutoStylePoolProperties *pProperties = nullptr; XMLAutoStylePoolProperties *pProperties = nullptr;
sal_Int32 nProperties = rProperties.size(); auto [itBegin, itEnd] = std::equal_range(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
size_t i = 0; if (!bDontSeek)
for (size_t n = m_PropertiesList.size(); i < n; ++i) for (auto it = itBegin; it != itEnd; ++it)
{ if (rFamilyData.mxMapper->Equals((*it)->GetProperties(), rProperties))
XMLAutoStylePoolProperties *const pIS = m_PropertiesList[i].get(); pProperties = it->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;
}
}
if( !pProperties ) bool bAdded = false;
if( bDontSeek || !pProperties )
{ {
pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent ); pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent );
PropertiesListType::iterator it = m_PropertiesList.begin(); m_PropertiesList.insert(itBegin, std::unique_ptr<XMLAutoStylePoolProperties>(pProperties));
::std::advance( it, i );
m_PropertiesList.insert(it, std::unique_ptr<XMLAutoStylePoolProperties>(pProperties));
bAdded = true; bAdded = true;
} }
...@@ -319,35 +319,17 @@ bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector< ...@@ -319,35 +319,17 @@ bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vector<
bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, const OUString& rName ) bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, const OUString& rName )
{ {
bool bAdded = false; if (rFamilyData.maNameSet.find(rName) != rFamilyData.maNameSet.end())
sal_Int32 nProperties = rProperties.size(); return false;
size_t i = 0;
for (size_t n = m_PropertiesList.size(); i < n; ++i) auto it = std::lower_bound(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
{
XMLAutoStylePoolProperties *const pIS = m_PropertiesList[i].get(); std::unique_ptr<XMLAutoStylePoolProperties> pProperties(
if( nProperties > static_cast<sal_Int32>(pIS->GetProperties().size()) ) new XMLAutoStylePoolProperties(rFamilyData, rProperties, msParent));
{ // ignore the generated name
continue; pProperties->SetName( rName );
} m_PropertiesList.insert(it, std::move(pProperties));
else if( nProperties < static_cast<sal_Int32>(pIS->GetProperties().size()) ) return true;
{
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;
} }
...@@ -357,24 +339,10 @@ bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const ve ...@@ -357,24 +339,10 @@ bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, const ve
OUString XMLAutoStylePoolParent::Find( const XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) const OUString XMLAutoStylePoolParent::Find( const XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) const
{ {
OUString sName; OUString sName;
vector< XMLPropertyState>::size_type nItems = rProperties.size(); auto [itBegin,itEnd] = std::equal_range(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
for (const auto & i : m_PropertiesList) for (auto it = itBegin; it != itEnd; ++it)
{ if (rFamilyData.mxMapper->Equals((*it)->GetProperties(), rProperties))
const XMLAutoStylePoolProperties *const pIS = i.get(); sName = (*it)->GetName();
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;
}
}
return sName; return sName;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <com/sun/star/beans/XTolerantMultiPropertySet.hpp> #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
#include <com/sun/star/beans/TolerantPropertySetResultType.hpp> #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
#include <rtl/ustrbuf.hxx> #include <rtl/ustrbuf.hxx>
#include <comphelper/anycompare.hxx>
#include <cppuhelper/weakref.hxx> #include <cppuhelper/weakref.hxx>
#include <osl/diagnose.h> #include <osl/diagnose.h>
#include <list> #include <list>
...@@ -655,44 +656,90 @@ bool SvXMLExportPropertyMapper::Equals( ...@@ -655,44 +656,90 @@ bool SvXMLExportPropertyMapper::Equals(
const vector< XMLPropertyState >& aProperties1, const vector< XMLPropertyState >& aProperties1,
const vector< XMLPropertyState >& aProperties2 ) const 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(); sal_uInt32 nCount = aProperties1.size();
if( nCount == aProperties2.size() ) for (sal_uInt32 nIndex = 0; nIndex < nCount; ++nIndex)
{ {
sal_uInt32 nIndex = 0; const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
while( bRet && nIndex < nCount ) const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
{
const XMLPropertyState& rProp1 = aProperties1[ nIndex ];
const XMLPropertyState& rProp2 = aProperties2[ nIndex ];
// Compare index. If equal, compare value // Compare index. If equal, compare value
if( rProp1.mnIndex == rProp2.mnIndex ) 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 ) // simple type ( binary compare )
{ if ( rProp1.maValue != rProp2.maValue)
// Now compare values return false;
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 );
}
} }
else 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 /** fills the given attribute list with the items in the given set
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment