summaryrefslogtreecommitdiff
path: root/svl
diff options
context:
space:
mode:
authorWang Lei <leiw@apache.org>2012-09-14 07:03:51 +0000
committerWang Lei <leiw@apache.org>2012-09-14 07:03:51 +0000
commitb39f169896005a4ab3f2a0cfdb116de947dda207 (patch)
treea2521142e65f9dc0d18e07f0f06a8a0d3a178717 /svl
parent45fc638e2fcb644aa4df5b1a62c4ddccac111802 (diff)
#i120575 optimize a comparing operation from 'memcmp' to 'hash compare' to improve xls loading performance
Patch by: li zhang (lizh.fee@gmail.com) Review by: Wang Lei
Notes
reject: We have implemented different way to speed up styles import from xls
Diffstat (limited to 'svl')
-rw-r--r--svl/inc/svl/itemset.hxx26
-rw-r--r--svl/source/items/itemset.cxx82
2 files changed, 102 insertions, 6 deletions
diff --git a/svl/inc/svl/itemset.hxx b/svl/inc/svl/itemset.hxx
index c1611189a019..4da844eecaf9 100644
--- a/svl/inc/svl/itemset.hxx
+++ b/svl/inc/svl/itemset.hxx
@@ -78,6 +78,16 @@ class SVL_DLLPUBLIC SfxItemSet
sal_uInt16* _pWhichRanges; // Array von Which-Bereichen
sal_uInt16 _nCount; // Anzahl Items
+ //optimize a comparing operation from 'memcmp' to 'hash compare' to improve xls loading performance, i120575
+ sal_Int32 _aHashKey; //hash result of array of points: _aItems.
+
+ void UpdateHashKey();
+ //Need invlidate the hashkey at every possible place where the array _aItems may be changed.
+ //thread safe : there is always solarmutex outter, so no need to add mutex here.
+ void InvalidateHashKey() { _aHashKey = 0;} //treat '0' as an invalidate key.
+ sal_Bool IsValidateHashKey() const { return (0!=_aHashKey);}
+ sal_Int32 GetHashKey() const { return _aHashKey; }
+ //end:i120575
//---------------------------------------------------------------------
#ifndef _SFXITEMS_HXX
@@ -91,7 +101,14 @@ private:
SVL_DLLPRIVATE void InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2);
public:
- SfxItemArray GetItems_Impl() const { return _aItems; }
+ //optimize a comparing operation from 'memcmp' to 'hash compare' to improve xls loading performance, i120575
+ //Make this method public is dangerous, may disrupt the item array. so invalidate the hash key here.
+ //currently this method is never called, pls also do not do it in future.
+ SfxItemArray GetItems_Impl() const
+ {
+ const_cast<SfxItemSet &>(*this).InvalidateHashKey();
+ return _aItems;
+ }//end:i120575
#endif
//---------------------------------------------------------------------
@@ -169,6 +186,13 @@ public:
virtual SvStream & Store( SvStream &, FASTBOOL bDirect = sal_False ) const;
virtual int operator==(const SfxItemSet &) const;
+
+ //optimize a comparing operation from 'memcmp' to 'hash compare' to improve xls loading performance, i120575
+ //in some situation (e.g.. ScPatternAttr::operator== ),
+ //two sfxitemset can be compared 'quickly' by the Hashkey only.
+ //may also update the hashkey in this method.
+ sal_Bool QuickCompare( SfxItemSet & rCmp);
+ //end:i120575
};
// --------------- Inline Implementierungen ------------------------
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 0cbd01a0daa3..762464798da6 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -134,7 +134,8 @@ SfxItemSet::SfxItemSet
: _pPool( &rPool ),
_pParent( 0 ),
- _nCount( 0 )
+ _nCount( 0 ),
+ _aHashKey( 0 ) //i120575
{
DBG_CTOR(SfxItemSet, DbgCheckItemSet);
DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
@@ -163,7 +164,8 @@ SfxItemSet::SfxItemSet
SfxItemSet::SfxItemSet( SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich2 ):
_pPool( &rPool ),
_pParent( 0 ),
- _nCount( 0 )
+ _nCount( 0 ),
+ _aHashKey( 0 ) //i120575
{
DBG_CTOR(SfxItemSet, DbgCheckItemSet);
DBG_ASSERT( nWhich1 <= nWhich2, "Ungueltiger Bereich" );
@@ -205,7 +207,8 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool,
_pPool( &rPool ),
_pParent( 0 ),
_pWhichRanges( 0 ),
- _nCount( 0 )
+ _nCount( 0 ),
+ _aHashKey( 0 ) //i120575
{
DBG_CTOR(SfxItemSet, DbgCheckItemSet);
DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
@@ -256,7 +259,8 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable ):
_pPool( &rPool ),
_pParent( 0 ),
_pWhichRanges(0),
- _nCount( 0 )
+ _nCount( 0 ),
+ _aHashKey( 0 ) //i120575
{
DBG_CTOR(SfxItemSet, 0);
DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
@@ -272,7 +276,8 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable ):
SfxItemSet::SfxItemSet( const SfxItemSet& rASet ):
_pPool( rASet._pPool ),
_pParent( rASet._pParent ),
- _nCount( rASet._nCount )
+ _nCount( rASet._nCount ),
+ _aHashKey( 0 ) //i120575
{
DBG_CTOR(SfxItemSet, DbgCheckItemSet);
DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
@@ -455,6 +460,7 @@ sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
pPtr += 2;
}
}
+ InvalidateHashKey(); //i120575
return nDel;
}
@@ -484,6 +490,7 @@ void SfxItemSet::ClearInvalidItems( sal_Bool bHardDefault )
}
pPtr += 2;
}
+ InvalidateHashKey(); //i120575
}
//------------------------------------------------------------------------
@@ -495,6 +502,7 @@ void SfxItemSet::InvalidateAllItems()
DBG_ASSERT( !_nCount, "Es sind noch Items gesetzt" );
memset( (void*)_aItems, -1, ( _nCount = TotalCount() ) * sizeof( SfxPoolItem*) );
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -582,6 +590,7 @@ const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich
if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
{
*ppFnd = &_pPool->Put( rItem, nWhich );
+ InvalidateHashKey(); //i120575
return *ppFnd;
}
@@ -589,6 +598,7 @@ const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich
if( !rItem.Which() )
{
*ppFnd = rItem.Clone(_pPool);
+ InvalidateHashKey(); //i120575
return 0;
}
else
@@ -626,11 +636,14 @@ const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich
SFX_ASSERT( !_pPool->IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
rItem.ISA(SfxSetItem) || **ppFnd == rItem,
nWhich, "putted Item unequal" );
+
+ InvalidateHashKey(); //i120575
return *ppFnd;
}
ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ InvalidateHashKey(); //i120575
return 0;
}
@@ -864,6 +877,7 @@ void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
_pWhichRanges = new sal_uInt16[ nCount ];
memcpy( _pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1137,6 +1151,7 @@ void SfxItemSet::Intersect( const SfxItemSet& rSet )
pItem = aIter.NextItem();
}
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1209,6 +1224,7 @@ void SfxItemSet::Differentiate( const SfxItemSet& rSet )
}
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1412,6 +1428,7 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet, sal_Bool bIgnoreDefaults )
MergeValue( *pItem, bIgnoreDefaults );
}
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1434,6 +1451,7 @@ void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, sal_Bool bIgnoreDefaults
ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1468,6 +1486,7 @@ void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
ppFnd += *(pPtr+1) - *pPtr + 1;
pPtr += 2;
}
+ InvalidateHashKey(); //i120575
}
// -----------------------------------------------------------------------
@@ -1629,6 +1648,8 @@ SvStream &SfxItemSet::Load
}
}
+
+ InvalidateHashKey(); //i120575
return rStream;
}
@@ -1768,6 +1789,7 @@ int SfxItemSet::PutDirect(const SfxPoolItem &rItem)
rItem.AddRef();
}
+ InvalidateHashKey(); //i120575
return sal_True;
}
ppFnd += *(pPtr+1) - *pPtr + 1;
@@ -2008,6 +2030,8 @@ const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhi
if ( bIncrementCount )
++_nCount;
+ InvalidateHashKey(); //i120575
+
return &rNew;
}
@@ -2116,3 +2140,51 @@ SfxItemSet *SfxAllItemSet::Clone(sal_Bool bItems, SfxItemPool *pToPool ) const
return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*_pPool);
}
+//for i120575
+//align with the rtl_hash, return signed int result and input len limited to 2G.
+//can be replaced with other hash function in future for better performance, e.g. fnv hash.
+inline sal_Int32 myhash(void * buf, sal_Int32 buf_len)
+{
+ return rtl_str_hashCode_WithLength( reinterpret_cast<const sal_Char *>(buf), buf_len);
+}
+
+inline void SfxItemSet::UpdateHashKey()
+{
+ _aHashKey= myhash(_aItems,TotalCount()* sizeof(_aItems[0]));
+
+ //always treat '0' as invalidate hash key, not using addtional bool data field for saving space.
+ if (!IsValidateHashKey() )
+ {
+ _aHashKey = 1;
+ }
+}
+
+sal_Bool SfxItemSet::QuickCompare( SfxItemSet & rCmp)
+{
+ if ( _pParent != rCmp._pParent ||
+ _pPool != rCmp._pPool ||
+ Count() != rCmp.Count() )
+ return sal_False;
+
+ if ((0==Count())&&(0==rCmp.Count()))
+ return sal_True;
+
+ if (!IsValidateHashKey())
+ {
+ UpdateHashKey();
+ }
+ if (!rCmp.IsValidateHashKey())
+ {
+ rCmp.UpdateHashKey();
+ }
+
+ //improved performance here, in most cases, the hashkey is not equal.
+ if (GetHashKey() != rCmp.GetHashKey())
+ return sal_False;
+
+ if ( 0 == memcmp( _aItems, rCmp._aItems, TotalCount() * sizeof(_aItems[0]) ) )
+ return sal_True;
+ else
+ return sal_False;
+}
+//end: i120575