summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-10-14 23:47:40 +0200
committerEike Rathke <erack@redhat.com>2014-10-15 02:20:09 +0200
commit268d5a7e3c5b31ad22bce7ff36a68c5d13fe7a40 (patch)
tree705c56143755a0c971ffd5f210a2a417a8a89edb /sc
parentd2ccf8434aa1917409de1eb6d160092494224b2c (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.hxx1
-rw-r--r--sc/source/core/data/markarr.cxx15
-rw-r--r--sc/source/core/data/markdata.cxx17
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 )