Return-Path: X-Original-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-ooo-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3D085DFB8 for ; Fri, 14 Sep 2012 08:04:48 +0000 (UTC) Received: (qmail 88040 invoked by uid 500); 14 Sep 2012 08:04:48 -0000 Delivered-To: apmail-incubator-ooo-commits-archive@incubator.apache.org Received: (qmail 87817 invoked by uid 500); 14 Sep 2012 08:04:41 -0000 Mailing-List: contact ooo-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ooo-dev@incubator.apache.org Delivered-To: mailing list ooo-commits@incubator.apache.org Received: (qmail 87774 invoked by uid 99); 14 Sep 2012 08:04:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 14 Sep 2012 08:04:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 14 Sep 2012 08:04:36 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 6C23323888E4; Fri, 14 Sep 2012 08:03:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: ooo-commits@incubator.apache.org From: leiw@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120914080352.6C23323888E4@eris.apache.org> 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(rCmp).GetItemSet() ) && - StrCmp( GetStyleName(), static_cast(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(*this)).GetItemSet().QuickCompare( (const_cast(static_cast(rCmp))).GetItemSet())&& + StrCmp( GetStyleName(), static_cast(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(*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(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