summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-12-09 14:48:36 +0100
committerEike Rathke <erack@redhat.com>2014-12-09 14:54:44 +0100
commitb1d4a2ae3d1b461bc52768ed62f354558596fa39 (patch)
tree0188553d58fb67c267ba0d05afedfb2459d20d97 /sc
parent3397cb614205c6954915c88005276ba38fbae5ce (diff)
introduce BroadcastBroadcasters() to speedup BroadcastCells()
Iterating over a range and attempting to get a broadcaster for each cell position is a performance bottle neck. Take advantage of the column's existing maBroadcasters structure instead. Change-Id: I5467a64ee3c0b5f430be1f0c4b940d3f71874827
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx8
-rw-r--r--sc/inc/table.hxx8
-rw-r--r--sc/source/core/data/column.cxx27
-rw-r--r--sc/source/core/data/documen7.cxx23
-rw-r--r--sc/source/core/data/table2.cxx10
5 files changed, 49 insertions, 27 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f7223bb634e6..bef0d0511780 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -101,6 +101,7 @@ struct ScFormulaCellGroup;
struct ScRefCellValue;
struct ScCellValue;
class ScDocumentImport;
+class ScHint;
struct ScNeededSizeOptions
{
@@ -381,6 +382,13 @@ public:
void CompileAll( sc::CompileFormulaContext& rCxt );
void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );
+ /** Broadcast single broadcasters in range, without explicitly setting
+ anything dirty, not doing area broadcasts.
+ @param rHint address is modified to adapt to the actual broadcasted
+ position on each iteration and upon return points to the last
+ position broadcasted. */
+ bool BroadcastBroadcasters( SCROW nRow1, SCROW nRow2, ScHint& rHint );
+
bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
void ResetChanged( SCROW nStartRow, SCROW nEndRow );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 7661fdace7a7..89a9a495b2d2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -112,6 +112,7 @@ struct ScColWidthParam;
class ScRangeName;
class ScDBData;
class ScDocumentImport;
+class ScHint;
class ScTable : boost::noncopyable
{
@@ -541,6 +542,13 @@ public:
void CompileAll( sc::CompileFormulaContext& rCxt );
void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress );
+ /** Broadcast single broadcasters in range, without explicitly setting
+ anything dirty, not doing area broadcasts.
+ @param rHint address is modified to adapt to the actual broadcasted
+ position on each iteration and upon return points to the last
+ position broadcasted. */
+ bool BroadcastBroadcasters( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScHint& rHint );
+
bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
void UpdateReference(
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 8d873af4eebe..77c51eaf38eb 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -3059,21 +3059,34 @@ namespace {
class BroadcastBroadcastersHandler
{
- ScHint maHint;
+ ScHint& mrHint;
+ ScAddress& mrAddress;
+ bool mbBroadcasted;
public:
- BroadcastBroadcastersHandler( SCCOL nCol, SCTAB nTab, sal_uLong nHint ) :
- maHint( nHint, ScAddress( nCol, 0, nTab)) {}
+ explicit BroadcastBroadcastersHandler( ScHint& rHint ) :
+ mrHint(rHint), mrAddress(mrHint.GetAddress()) {}
void operator() ( size_t nRow, SvtBroadcaster* pBroadcaster )
{
- maHint.GetAddress().SetRow(nRow);
- pBroadcaster->Broadcast(maHint);
+ mrAddress.SetRow(nRow);
+ pBroadcaster->Broadcast(mrHint);
+ mbBroadcasted = true;
}
+
+ bool wasBroadcasted() { return mbBroadcasted; }
};
}
+bool ScColumn::BroadcastBroadcasters( SCROW nRow1, SCROW nRow2, ScHint& rHint )
+{
+ rHint.GetAddress().SetCol(nCol);
+ BroadcastBroadcastersHandler aBroadcasterHdl( rHint);
+ sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aBroadcasterHdl);
+ return aBroadcasterHdl.wasBroadcasted();
+}
+
void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode )
{
// broadcasts everything within the range, with FormulaTracking
@@ -3115,8 +3128,8 @@ void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode )
SetDirtyOnRangeHandler aHdl(*this);
sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl);
// Broadcast all broadcasters in range.
- BroadcastBroadcastersHandler aBroadcasterHdl( nCol, nTab, SC_HINT_DATACHANGED);
- sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aBroadcasterHdl);
+ ScHint aHint( SC_HINT_DATACHANGED, ScAddress( nCol, nRow1, nTab));
+ BroadcastBroadcasters( nRow1, nRow2, aHint);
}
break;
}
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 64fc158cb36f..af7337eb0aa2 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -110,9 +110,6 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB
SCCOL nCol1 = rRange.aStart.Col();
SCCOL nCol2 = rRange.aEnd.Col();
- ScHint aHint(nHint, ScAddress());
- ScAddress& rPos = aHint.GetAddress();
-
if (!bHardRecalcState)
{
ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
@@ -120,29 +117,15 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB
if (bBroadcastSingleBroadcasters)
{
+ ScHint aHint(nHint, ScAddress());
+
for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
{
ScTable* pTab = FetchTable(nTab);
if (!pTab)
continue;
- rPos.SetTab(nTab);
- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
- {
- rPos.SetCol(nCol);
- /* TODO: to speed-up things a per column iterator to
- * cell-broadcast in a range of rows would come handy. */
- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
- {
- SvtBroadcaster* pBC = pTab->GetBroadcaster( nCol, nRow);
- if (pBC)
- {
- rPos.SetRow(nRow);
- pBC->Broadcast(aHint);
- bIsBroadcasted = true;
- }
- }
- }
+ bIsBroadcasted |= pTab->BroadcastBroadcasters( nCol1, nRow1, nCol2, nRow2, aHint);
}
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index c462d6162731..938639b54bb7 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1729,6 +1729,16 @@ void ScTable::BroadcastRecalcOnRefMove()
aCol[i].BroadcastRecalcOnRefMove();
}
+bool ScTable::BroadcastBroadcasters( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScHint& rHint )
+{
+ bool bBroadcasted = false;
+ sc::AutoCalcSwitch aSwitch(*pDocument, false);
+ rHint.GetAddress().SetTab(nTab);
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ bBroadcasted |= aCol[nCol].BroadcastBroadcasters( nRow1, nRow2, rHint);
+ return bBroadcasted;
+}
+
void ScTable::TransferListeners(
ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCCOL nColDelta, SCROW nRowDelta )