diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-01-07 12:43:48 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-01-09 15:43:53 +0100 |
commit | dd6ff1fd7fea0cfae75e5f65afed9d5f871d1313 (patch) | |
tree | 929b067780680b173ce7592c0042b493ef66fb83 /svx | |
parent | 9ba45189c76373d0464cc06902270914888162a3 (diff) |
implement anyToHash() and use it for SdrCustomShapeGeometryItem
Using anyLess() still has quite some cost with bsc#1183308, this
makes the cost almost unnoticeable.
Since some values of Any are not handled, return empty std::optional
for those cases.
Change-Id: Ib45a81441e8bb456c4749f9bc53a981f09bbb1a5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128109
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/source/items/customshapeitem.cxx | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/svx/source/items/customshapeitem.cxx b/svx/source/items/customshapeitem.cxx index 0bba5ca6eb33..3ba698a3c158 100644 --- a/svx/source/items/customshapeitem.cxx +++ b/svx/source/items/customshapeitem.cxx @@ -21,6 +21,7 @@ #include <o3tl/any.hxx> #include <comphelper/anycompare.hxx> +#include <comphelper/anytohash.hxx> #include <svx/sdasitm.hxx> #include <com/sun/star/beans/PropertyValue.hpp> @@ -128,6 +129,7 @@ void SdrCustomShapeGeometryItem::SetPropertyValue( const css::beans::PropertyVal aPropHashMap[ rPropVal.Name ] = nIndex; } + InvalidateHash(); } void SdrCustomShapeGeometryItem::SetPropertyValue( const OUString& rSequenceName, const css::beans::PropertyValue& rPropVal ) @@ -176,6 +178,7 @@ void SdrCustomShapeGeometryItem::SetPropertyValue( const OUString& rSequenceName } } } + InvalidateHash(); } void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString& rPropName ) @@ -212,6 +215,7 @@ void SdrCustomShapeGeometryItem::ClearPropertyValue( const OUString& rPropName ) aPropSeq.realloc( nLength - 1 ); } aPropHashMap.erase( aHashIter ); // removing property from hashmap + InvalidateHash(); } SdrCustomShapeGeometryItem::~SdrCustomShapeGeometryItem() @@ -224,13 +228,15 @@ bool SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const return false; const SdrCustomShapeGeometryItem& other = static_cast<const SdrCustomShapeGeometryItem&>(rCmp); // This is called often by SfxItemPool, and comparing uno sequences is relatively slow. - // Optimize by checking the list of properties that this class keeps for the sequence, - // if the sizes are different, the sequences are different too, which should allow a cheap - // return for many cases. - if( aPropHashMap.size() != other.aPropHashMap.size()) + // So keep a hash of the sequence and if either of the sequences has a usable hash, + // compare using that. + UpdateHash(); + other.UpdateHash(); + if( aHashState != other.aHashState ) return false; - if( aPropPairHashMap.size() != other.aPropPairHashMap.size()) + if( aHashState == HashState::Valid && aHash != other.aHash ) return false; + return aPropSeq == other.aPropSeq; } @@ -238,16 +244,38 @@ bool SdrCustomShapeGeometryItem::operator<( const SfxPoolItem& rCmp ) const { assert(dynamic_cast<const SdrCustomShapeGeometryItem*>( &rCmp )); const SdrCustomShapeGeometryItem& other = static_cast<const SdrCustomShapeGeometryItem&>(rCmp); - // Again, optimize by checking the list of properties and compare by their count if different - // (this is operator< for sorting purposes, so the ordering can be somewhat arbitrary). - if( aPropHashMap.size() != other.aPropHashMap.size()) - return aPropHashMap.size() < other.aPropHashMap.size(); - if( aPropPairHashMap.size() != other.aPropPairHashMap.size()) - return aPropPairHashMap.size() < other.aPropPairHashMap.size(); + // Again, try to optimize by checking hashes first (this is operator< for sorting purposes, + // so the ordering can be somewhat arbitrary). + UpdateHash(); + other.UpdateHash(); + if( aHashState != other.aHashState ) + return aHashState < other.aHashState; + if( aHashState == HashState::Valid ) + return aHash < other.aHash; + return comphelper::anyLess( css::uno::makeAny( aPropSeq ), css::uno::makeAny( other.aPropSeq )); } +void SdrCustomShapeGeometryItem::UpdateHash() const +{ + if( aHashState != HashState::Unknown ) + return; + std::optional< size_t > hash = comphelper::anyToHash( css::uno::makeAny( aPropSeq )); + if( hash.has_value()) + { + aHash = *hash; + aHashState = HashState::Valid; + } + else + aHashState = HashState::Unusable; +} + +void SdrCustomShapeGeometryItem::InvalidateHash() +{ + aHashState = HashState::Unknown; +} + bool SdrCustomShapeGeometryItem::GetPresentation( SfxItemPresentation ePresentation, MapUnit /*eCoreMetric*/, MapUnit /*ePresentationMetric*/, OUString &rText, const IntlWrapper&) const @@ -313,6 +341,7 @@ void SdrCustomShapeGeometryItem::SetPropSeq( const css::uno::Sequence< css::bean } } } + InvalidateHash(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |