tdf#129228 speedup opening of xlsx file with lots of comments

by avoid some of the EqualPatternSets memcmp cost by using a
hashcode, memcmp with lots of large and similar arrays ends up
blowing the L1/L2 cache

Takes the time from 64s to 59s for me.

Change-Id: I6961aa34f4e7457a70cb75a37dfae50d5f328589
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85918
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85948
diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx
index 19c4df0..c0e7c39 100644
--- a/sc/inc/patattr.hxx
+++ b/sc/inc/patattr.hxx
@@ -52,6 +52,7 @@
class SC_DLLPUBLIC ScPatternAttr final : public SfxSetItem
{
    boost::optional<OUString>  pName;
    mutable boost::optional<size_t> mxHashCode;
    ScStyleSheet*              pStyle;
    sal_uInt64                 mnKey;
public:
@@ -143,6 +144,9 @@

    void                    SetKey(sal_uInt64 nKey);
    sal_uInt64              GetKey() const;

private:
    void                    CalcHashCode() const;
};

#endif
diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx
index f7e4010..1538ab6 100644
--- a/sc/source/core/data/patattr.cxx
+++ b/sc/source/core/data/patattr.cxx
@@ -61,6 +61,7 @@
#include <validat.hxx>
#include <scmod.hxx>
#include <fillinfo.hxx>
#include <boost/functional/hash.hpp>

using sc::HMMToTwips;
using sc::TwipsToHMM;
@@ -139,9 +140,17 @@
{
    // #i62090# Use quick comparison between ScPatternAttr's ItemSets

    return SfxPoolItem::operator==(rCmp) &&
            EqualPatternSets( GetItemSet(), static_cast<const ScPatternAttr&>(rCmp).GetItemSet() ) &&
            StrCmp( GetStyleName(), static_cast<const ScPatternAttr&>(rCmp).GetStyleName() );
    if (!SfxPoolItem::operator==(rCmp) )
        return false;
    if (!mxHashCode)
        CalcHashCode();
    auto const & rOther = static_cast<const ScPatternAttr&>(rCmp);
    if (!rOther.mxHashCode)
        rOther.CalcHashCode();
    if (*mxHashCode != *rOther.mxHashCode)
        return false;
    return EqualPatternSets( GetItemSet(), rOther.GetItemSet() ) &&
            StrCmp( GetStyleName(), rOther.GetStyleName() );
}

SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet )
@@ -880,8 +889,10 @@

void ScPatternAttr::GetFromEditItemSet( const SfxItemSet* pEditSet )
{
    if( pEditSet )
        GetFromEditItemSet( GetItemSet(), *pEditSet );
    if( !pEditSet )
        return;
    GetFromEditItemSet( GetItemSet(), *pEditSet );
    mxHashCode.reset();
}

void ScPatternAttr::FillEditParaItems( SfxItemSet* pEditSet ) const
@@ -922,13 +933,19 @@
            {
                //  item is set in OldAttrs (or its parent) -> compare pointers
                if ( pThisItem == pOldItem )
                {
                    rThisSet.ClearItem( nSubWhich );
                    mxHashCode.reset();
                }
            }
            else if ( eOldState != SfxItemState::DONTCARE )
            {
                //  not set in OldAttrs -> compare item value to default item
                if ( *pThisItem == rThisSet.GetPool()->GetDefaultItem( nSubWhich ) )
                {
                    rThisSet.ClearItem( nSubWhich );
                    mxHashCode.reset();
                }
            }
        }
    }
@@ -948,6 +965,7 @@
    SfxItemSet& rSet = GetItemSet();
    for (sal_uInt16 i=0; pWhich[i]; i++)
        rSet.ClearItem(pWhich[i]);
    mxHashCode.reset();
}

static SfxStyleSheetBase* lcl_CopyStyleToPool
@@ -1345,4 +1363,10 @@
    return mnKey;
}

void ScPatternAttr::CalcHashCode() const
{
    auto const & rSet = GetItemSet();
    mxHashCode = boost::hash_range(rSet.GetItems_Impl(), rSet.GetItems_Impl() + rSet.Count());
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */