diff options
author | Eike Rathke <erack@redhat.com> | 2014-10-14 23:47:40 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2014-10-15 02:20:09 +0200 |
commit | 268d5a7e3c5b31ad22bce7ff36a68c5d13fe7a40 (patch) | |
tree | 705c56143755a0c971ffd5f210a2a417a8a89edb /sc | |
parent | d2ccf8434aa1917409de1eb6d160092494224b2c (diff) |
speed up range list generation from multi marks, fdo#75486 related
Change-Id: Id2114652948d12c92b0e7be7afa304bfffc8fbe0
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/markarr.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/markarr.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/markdata.cxx | 17 |
3 files changed, 32 insertions, 1 deletions
diff --git a/sc/inc/markarr.hxx b/sc/inc/markarr.hxx index 5b15d4236529..2988fe4b74cb 100644 --- a/sc/inc/markarr.hxx +++ b/sc/inc/markarr.hxx @@ -47,6 +47,7 @@ public: void SetMarkArea( SCROW nStartRow, SCROW nEndRow, bool bMarked ); bool IsAllMarked( SCROW nStartRow, SCROW nEndRow ) const; bool HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const; + bool HasEqualRowsMarked( const ScMarkArray& rOther ) const; bool HasMarks() const { return ( nCount > 1 || ( nCount == 1 && pData[0].bMarked ) ); } diff --git a/sc/source/core/data/markarr.cxx b/sc/source/core/data/markarr.cxx index 00e3ce004540..407fad527fa9 100644 --- a/sc/source/core/data/markarr.cxx +++ b/sc/source/core/data/markarr.cxx @@ -274,6 +274,21 @@ bool ScMarkArray::HasOneMark( SCROW& rStartRow, SCROW& rEndRow ) const return bRet; } +bool ScMarkArray::HasEqualRowsMarked( const ScMarkArray& rOther ) const +{ + if (nCount != rOther.nCount) + return false; + + for (size_t i=0; i < nCount; ++i) + { + if (pData[i].bMarked != rOther.pData[i].bMarked || + pData[i].nRow != rOther.pData[i].nRow) + return false; + } + + return true; +} + void ScMarkArray::CopyMarksTo( ScMarkArray& rDestMarkArray ) const { delete[] rDestMarkArray.pData; diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index 482882e1e435..022a82002ca8 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -386,10 +386,23 @@ void ScMarkData::FillRangeListWithMarks( ScRangeList* pList, bool bClear ) const SCCOL nStartCol = aMultiRange.aStart.Col(); SCCOL nEndCol = aMultiRange.aEnd.Col(); for (SCCOL nCol=nStartCol; nCol<=nEndCol; nCol++) + { if (pMultiSel[nCol].HasMarks()) { + // Feeding column-wise fragments to ScRangeList::Join() is a + // huge bottleneck, speed this up for multiple columns + // consisting of identical row sets by building a column span + // first. This is usually the case for filtered data, for + // example. + SCCOL nToCol = nCol+1; + for ( ; nToCol <= nEndCol; ++nToCol) + { + if (!pMultiSel[nCol].HasEqualRowsMarked( pMultiSel[nToCol])) + break; + } + --nToCol; + ScRange aRange( nCol, 0, nTab, nToCol, 0, nTab ); SCROW nTop, nBottom; - ScRange aRange( nCol, 0, nTab ); ScMarkArrayIter aMarkIter( &pMultiSel[nCol] ); while ( aMarkIter.Next( nTop, nBottom ) ) { @@ -397,7 +410,9 @@ void ScMarkData::FillRangeListWithMarks( ScRangeList* pList, bool bClear ) const aRange.aEnd.SetRow( nBottom ); pList->Join( aRange ); } + nCol = nToCol; } + } } if ( bMarked ) |