incubator-ooo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l...@apache.org
Subject svn commit: r1384677 - in /incubator/ooo/trunk/main: sc/source/core/data/patattr.cxx svl/inc/svl/itemset.hxx svl/source/items/itemset.cxx
Date Fri, 14 Sep 2012 08:03:52 GMT
Author: leiw
Date: Fri Sep 14 08:03:51 2012
New Revision: 1384677

URL: http://svn.apache.org/viewvc?rev=1384677&view=rev
Log:
#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

Modified:
    incubator/ooo/trunk/main/sc/source/core/data/patattr.cxx
    incubator/ooo/trunk/main/svl/inc/svl/itemset.hxx
    incubator/ooo/trunk/main/svl/source/items/itemset.cxx

Modified: incubator/ooo/trunk/main/sc/source/core/data/patattr.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/sc/source/core/data/patattr.cxx?rev=1384677&r1=1384676&r2=1384677&view=diff
==============================================================================
--- incubator/ooo/trunk/main/sc/source/core/data/patattr.cxx (original)
+++ incubator/ooo/trunk/main/sc/source/core/data/patattr.cxx Fri Sep 14 08:03:51 2012
@@ -135,27 +135,17 @@ inline int StrCmp( const String* pStr1, 
 	return ( pStr1 ? ( pStr2 ? ( *pStr1 == *pStr2 ) : sal_False ) : ( pStr2 ? sal_False : sal_True
) );
 }
 
-inline bool EqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 )
-{
-    // #i62090# The SfxItemSet in the SfxSetItem base class always has the same ranges
-    // (single range from ATTR_PATTERN_START to ATTR_PATTERN_END), and the items are pooled,
-    // so it's enough to compare just the pointers (Count just because it's even faster).
-
-    if ( rSet1.Count() != rSet2.Count() )
-        return false;
 
-    SfxItemArray pItems1 = rSet1.GetItems_Impl();   // inline method of SfxItemSet
-    SfxItemArray pItems2 = rSet2.GetItems_Impl();
-
-    return ( 0 == memcmp( pItems1, pItems2, (ATTR_PATTERN_END - ATTR_PATTERN_START + 1) *
sizeof(pItems1[0]) ) );
-}
 
 int __EXPORT ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const
 {
     // #i62090# Use quick comparison between ScPatternAttr's ItemSets
 
-    return ( EqualPatternSets( GetItemSet(), static_cast<const ScPatternAttr&>(rCmp).GetItemSet()
) &&
-             StrCmp( GetStyleName(), static_cast<const ScPatternAttr&>(rCmp).GetStyleName()
) );
+   //optimize a comparing operation from 'memcmp' to 'hash compare' to improve xls loading
performance, i120575
+   //More quickly comparing method using hashkey.
+   //the const_cast here will then only change the HashKey of that SfxItemSet, so it's safe.
+	return ((const_cast<ScPatternAttr&>(*this)).GetItemSet().QuickCompare( (const_cast<ScPatternAttr&>(static_cast<const
ScPatternAttr&>(rCmp))).GetItemSet())&&
+		StrCmp( GetStyleName(), static_cast<const ScPatternAttr&>(rCmp).GetStyleName()
) );  
 }
 
 SfxPoolItem* __EXPORT ScPatternAttr::Create( SvStream& rStream, sal_uInt16 /* nVersion
*/ ) const

Modified: incubator/ooo/trunk/main/svl/inc/svl/itemset.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svl/inc/svl/itemset.hxx?rev=1384677&r1=1384676&r2=1384677&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svl/inc/svl/itemset.hxx (original)
+++ incubator/ooo/trunk/main/svl/inc/svl/itemset.hxx Fri Sep 14 08:03:51 2012
@@ -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 ------------------------

Modified: incubator/ooo/trunk/main/svl/source/items/itemset.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/svl/source/items/itemset.cxx?rev=1384677&r1=1384676&r2=1384677&view=diff
==============================================================================
--- incubator/ooo/trunk/main/svl/source/items/itemset.cxx (original)
+++ incubator/ooo/trunk/main/svl/source/items/itemset.cxx Fri Sep 14 08:03:51 2012
@@ -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& rPo
 	_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& rPo
 	_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& rPo
 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_uI
 			pPtr += 2;
 		}
 	}
+	InvalidateHashKey();	//i120575
 	return nDel;
 }
 
@@ -484,6 +490,7 @@ void SfxItemSet::ClearInvalidItems( sal_
 				}
 			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( cons
 				if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
 				{
 					*ppFnd = &_pPool->Put( rItem, nWhich );
+					InvalidateHashKey();	//i120575
 					return *ppFnd;
 				}
 
@@ -589,6 +598,7 @@ const SfxPoolItem* SfxItemSet::Put( cons
 				if( !rItem.Which() )
 				{
 					*ppFnd = rItem.Clone(_pPool);
+					InvalidateHashKey();	//i120575
 					return 0;
 				}
 				else
@@ -626,11 +636,14 @@ const SfxPoolItem* SfxItemSet::Put( cons
 			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_uI
 		_pWhichRanges = new sal_uInt16[ nCount ];
 		memcpy( _pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
 	}
+	InvalidateHashKey();	//i120575
 }
 
 // -----------------------------------------------------------------------
@@ -1137,6 +1151,7 @@ void SfxItemSet::Intersect( const SfxIte
 			pItem = aIter.NextItem();
 		}
 	}
+	InvalidateHashKey();	//i120575	
 }
 
 // -----------------------------------------------------------------------
@@ -1209,6 +1224,7 @@ void SfxItemSet::Differentiate( const Sf
 		}
 
 	}
+	InvalidateHashKey();	//i120575	
 }
 
 // -----------------------------------------------------------------------
@@ -1412,6 +1428,7 @@ void SfxItemSet::MergeValues( const SfxI
 				MergeValue( *pItem, bIgnoreDefaults );
 		}
 	}
+	InvalidateHashKey();	//i120575	
 }
 
 // -----------------------------------------------------------------------
@@ -1434,6 +1451,7 @@ void SfxItemSet::MergeValue( const SfxPo
 		ppFnd += *(pPtr+1) - *pPtr + 1;
 		pPtr += 2;
 	}
+	InvalidateHashKey();	//i120575	
 }
 
 // -----------------------------------------------------------------------
@@ -1468,6 +1486,7 @@ void SfxItemSet::InvalidateItem( sal_uIn
 		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 SfxPoolI
 					rItem.AddRef();
 			}
 
+			InvalidateHashKey();	//i120575
 			return sal_True;
 		}
 		ppFnd += *(pPtr+1) - *pPtr + 1;
@@ -2007,6 +2029,8 @@ const SfxPoolItem* SfxAllItemSet::Put( c
 
     if ( bIncrementCount )
         ++_nCount;
+	
+	InvalidateHashKey();	//i120575
 
 	return &rNew;
 }
@@ -2116,3 +2140,51 @@ SfxItemSet *SfxAllItemSet::Clone(sal_Boo
 		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



Mime
View raw message