[Libreoffice-commits] core.git: 3 commits - sc/inc sc/source
Eike Rathke
erack at redhat.com
Tue Oct 14 17:20:48 PDT 2014
sc/inc/markarr.hxx | 1
sc/inc/rangelst.hxx | 1
sc/source/core/data/markarr.cxx | 15 ++++++
sc/source/core/data/markdata.cxx | 17 +++++++
sc/source/core/tool/rangelst.cxx | 49 ++++++++++++++++++++--
sc/source/ui/Accessibility/AccessibleDocument.cxx | 4 -
6 files changed, 78 insertions(+), 9 deletions(-)
New commits:
commit defa080e585fb351bc4049b2f280d2e7e5256f6e
Author: Eike Rathke <erack at redhat.com>
Date: Wed Oct 15 02:03:09 2014 +0200
remove duplicated call to mpChildrenShapes->SelectionChanged()
Found when investigating performance bottlenecks of fdo#75486, after the
selection is completed ScTabViewObj::getSelection() is called multiple
times, each creating a ScCellRangesObj of the range list of filtered
ranges, which then is used for
ScChildrenShapes::FindSelectedShapesChanges()
The duplicated call was introduced with
b41332475783c31136673fb44cf4c411bb0148f8
but IMHO does not make any sense at all unless it has obscure side
effects, it only slows down things even more.
Change-Id: I3cee2e3e62c24ad72efb8cc2021e74d0afc70b69
diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx
index 975dfc7..751a9fe 100644
--- a/sc/source/ui/Accessibility/AccessibleDocument.cxx
+++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx
@@ -1691,10 +1691,6 @@ void SAL_CALL ScAccessibleDocument::selectionChanged( const lang::EventObject& /
CommitChange(aEvent);
}
- if(mpChildrenShapes )
- {
- mpChildrenShapes->SelectionChanged();
- }
}
//===== XInterface =====================================================
commit 94efc482d514bf9c6c4edb149f86084d672b724f
Author: Eike Rathke <erack at redhat.com>
Date: Tue Oct 14 23:50:24 2014 +0200
speed up simple range list joins that could be appends, fdo#75486 related
Change-Id: I734ff88bc4c0633875c9e9c19a817b8b08511c83
diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx
index 897bb97..4a10eed 100644
--- a/sc/inc/rangelst.hxx
+++ b/sc/inc/rangelst.hxx
@@ -93,6 +93,7 @@ public:
private:
::std::vector<ScRange*> maRanges;
+ SCROW mnMaxRowUsed;
typedef std::vector<ScRange*>::iterator iterator;
typedef std::vector<ScRange*>::const_iterator const_iterator;
};
diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx
index 6e276bc..ab5653f5 100644
--- a/sc/source/core/tool/rangelst.cxx
+++ b/sc/source/core/tool/rangelst.cxx
@@ -229,6 +229,37 @@ void ScRangeList::Join( const ScRange& r, bool bIsInList )
SCROW nRow2 = r.aEnd.Row();
SCTAB nTab2 = r.aEnd.Tab();
+ // One common usage is to join ranges that actually are top to bottom
+ // appends but the caller doesn't exactly know about it, e.g. when invoked
+ // by ScMarkData::FillRangeListWithMarks(), check for this special case
+ // first and speed up things by not looping over all ranges for each range
+ // to be joined. We don't remember the exact encompassing range that would
+ // have to be updated on refupdates and insertions and deletions, instead
+ // remember just the maximum row used, even independently of the sheet.
+ // This satisfies most use cases.
+
+ if (!bIsInList)
+ {
+ if (nRow1 > mnMaxRowUsed + 1)
+ {
+ Append( r );
+ return;
+ }
+ else if (nRow1 == mnMaxRowUsed + 1)
+ {
+ // Check if we can simply enlarge the last range.
+ ScRange* p = maRanges.back();
+ if (p->aEnd.Row() + 1 == nRow1 &&
+ p->aStart.Col() == nCol1 && p->aEnd.Col() == nCol2 &&
+ p->aStart.Tab() == nTab1 && p->aEnd.Tab() == nTab2)
+ {
+ p->aEnd.SetRow( nRow2 );
+ mnMaxRowUsed = nRow2;
+ return;
+ }
+ }
+ }
+
ScRange* pOver = (ScRange*) &r; // fies aber wahr wenn bInList
size_t nOldPos = 0;
if ( bIsInList )
@@ -403,6 +434,8 @@ bool ScRangeList::UpdateReference(
bChanged = true;
pR->aStart.Set( theCol1, theRow1, theTab1 );
pR->aEnd.Set( theCol2, theRow2, theTab2 );
+ if (mnMaxRowUsed < theRow2)
+ mnMaxRowUsed = theRow2;
}
}
@@ -435,6 +468,8 @@ void ScRangeList::InsertRow( SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW n
SCROW nNewRangeEndRow = nRowPos + nSize - 1;
aNewRanges.push_back(ScRange(nNewRangeStartCol, nNewRangeStartRow, nTab, nNewRangeEndCol,
nNewRangeEndRow, nTab));
+ if (mnMaxRowUsed < nNewRangeEndRow)
+ mnMaxRowUsed = nNewRangeEndRow;
}
}
}
@@ -983,16 +1018,19 @@ ScRange* ScRangeList::Find( const ScAddress& rAdr )
return itr == maRanges.end() ? NULL : *itr;
}
-ScRangeList::ScRangeList() {}
+ScRangeList::ScRangeList() : mnMaxRowUsed(-1) {}
ScRangeList::ScRangeList( const ScRangeList& rList ) :
- SvRefBase()
+ SvRefBase(),
+ mnMaxRowUsed(-1)
{
maRanges.reserve(rList.maRanges.size());
for_each(rList.maRanges.begin(), rList.maRanges.end(), AppendToList(maRanges));
+ mnMaxRowUsed = rList.mnMaxRowUsed;
}
-ScRangeList::ScRangeList( const ScRange& rRange )
+ScRangeList::ScRangeList( const ScRange& rRange ) :
+ mnMaxRowUsed(-1)
{
maRanges.reserve(1);
Append(rRange);
@@ -1003,13 +1041,14 @@ ScRangeList& ScRangeList::operator=(const ScRangeList& rList)
RemoveAll();
maRanges.reserve(rList.maRanges.size());
for_each(rList.maRanges.begin(), rList.maRanges.end(), AppendToList(maRanges));
+ mnMaxRowUsed = rList.mnMaxRowUsed;
return *this;
}
void ScRangeList::Append( const ScRange& rRange )
{
ScRange* pR = new ScRange( rRange );
- maRanges.push_back( pR );
+ push_back( pR );
}
bool ScRangeList::Intersects( const ScRange& rRange ) const
@@ -1126,6 +1165,8 @@ const ScRange* ScRangeList::back() const
void ScRangeList::push_back(ScRange* p)
{
maRanges.push_back(p);
+ if (mnMaxRowUsed < p->aEnd.Row())
+ mnMaxRowUsed = p->aEnd.Row();
}
ScAddress ScRangeList::GetTopLeftCorner() const
commit 268d5a7e3c5b31ad22bce7ff36a68c5d13fe7a40
Author: Eike Rathke <erack at redhat.com>
Date: Tue Oct 14 23:47:40 2014 +0200
speed up range list generation from multi marks, fdo#75486 related
Change-Id: Id2114652948d12c92b0e7be7afa304bfffc8fbe0
diff --git a/sc/inc/markarr.hxx b/sc/inc/markarr.hxx
index 5b15d42..2988fe4 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 00e3ce0..407fad5 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 482882e..022a820 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 )
More information about the Libreoffice-commits
mailing list