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
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
......
......@@ -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
......
......@@ -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,
......
......@@ -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())
return false;
auto it = std::lower_bound(m_PropertiesList.begin(), m_PropertiesList.end(), rProperties, ComparePartial{rFamilyData});
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;
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;
}
......
......@@ -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() )
{
sal_uInt32 nIndex = 0;
while( bRet && nIndex < nCount )
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 )
{
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 )
bRet = ( rProp1.maValue == rProp2.maValue );
if ( rProp1.maValue != rProp2.maValue)
return false;
}
else
{
// complex type ( ask for compare-function )
bRet = mpImpl->mxPropMapper->GetPropertyHandler(
if (!mpImpl->mxPropMapper->GetPropertyHandler(
rProp1.mnIndex )->equals( rProp1.maValue,
rProp2.maValue );
rProp2.maValue ))
return false;
}
}
}
else
bRet = false;
nIndex++;
return true;
}
// 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
......
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