Kaydet (Commit) b1d4a2ae authored tarafından Eike Rathke's avatar Eike Rathke

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
üst 3397cb61
...@@ -101,6 +101,7 @@ struct ScFormulaCellGroup; ...@@ -101,6 +101,7 @@ struct ScFormulaCellGroup;
struct ScRefCellValue; struct ScRefCellValue;
struct ScCellValue; struct ScCellValue;
class ScDocumentImport; class ScDocumentImport;
class ScHint;
struct ScNeededSizeOptions struct ScNeededSizeOptions
{ {
...@@ -381,6 +382,13 @@ public: ...@@ -381,6 +382,13 @@ public:
void CompileAll( sc::CompileFormulaContext& rCxt ); void CompileAll( sc::CompileFormulaContext& rCxt );
void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); 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 ); bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
void ResetChanged( SCROW nStartRow, SCROW nEndRow ); void ResetChanged( SCROW nStartRow, SCROW nEndRow );
......
...@@ -112,6 +112,7 @@ struct ScColWidthParam; ...@@ -112,6 +112,7 @@ struct ScColWidthParam;
class ScRangeName; class ScRangeName;
class ScDBData; class ScDBData;
class ScDocumentImport; class ScDocumentImport;
class ScHint;
class ScTable : boost::noncopyable class ScTable : boost::noncopyable
{ {
...@@ -541,6 +542,13 @@ public: ...@@ -541,6 +542,13 @@ public:
void CompileAll( sc::CompileFormulaContext& rCxt ); void CompileAll( sc::CompileFormulaContext& rCxt );
void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); 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 ); bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode );
void UpdateReference( void UpdateReference(
......
...@@ -3059,21 +3059,34 @@ namespace { ...@@ -3059,21 +3059,34 @@ namespace {
class BroadcastBroadcastersHandler class BroadcastBroadcastersHandler
{ {
ScHint maHint; ScHint& mrHint;
ScAddress& mrAddress;
bool mbBroadcasted;
public: public:
BroadcastBroadcastersHandler( SCCOL nCol, SCTAB nTab, sal_uLong nHint ) : explicit BroadcastBroadcastersHandler( ScHint& rHint ) :
maHint( nHint, ScAddress( nCol, 0, nTab)) {} mrHint(rHint), mrAddress(mrHint.GetAddress()) {}
void operator() ( size_t nRow, SvtBroadcaster* pBroadcaster ) void operator() ( size_t nRow, SvtBroadcaster* pBroadcaster )
{ {
maHint.GetAddress().SetRow(nRow); mrAddress.SetRow(nRow);
pBroadcaster->Broadcast(maHint); 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 ) void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode )
{ {
// broadcasts everything within the range, with FormulaTracking // broadcasts everything within the range, with FormulaTracking
...@@ -3115,8 +3128,8 @@ void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode ) ...@@ -3115,8 +3128,8 @@ void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode )
SetDirtyOnRangeHandler aHdl(*this); SetDirtyOnRangeHandler aHdl(*this);
sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl); sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl);
// Broadcast all broadcasters in range. // Broadcast all broadcasters in range.
BroadcastBroadcastersHandler aBroadcasterHdl( nCol, nTab, SC_HINT_DATACHANGED); ScHint aHint( SC_HINT_DATACHANGED, ScAddress( nCol, nRow1, nTab));
sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aBroadcasterHdl); BroadcastBroadcasters( nRow1, nRow2, aHint);
} }
break; break;
} }
......
...@@ -110,9 +110,6 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB ...@@ -110,9 +110,6 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB
SCCOL nCol1 = rRange.aStart.Col(); SCCOL nCol1 = rRange.aStart.Col();
SCCOL nCol2 = rRange.aEnd.Col(); SCCOL nCol2 = rRange.aEnd.Col();
ScHint aHint(nHint, ScAddress());
ScAddress& rPos = aHint.GetAddress();
if (!bHardRecalcState) if (!bHardRecalcState)
{ {
ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
...@@ -120,29 +117,15 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB ...@@ -120,29 +117,15 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB
if (bBroadcastSingleBroadcasters) if (bBroadcastSingleBroadcasters)
{ {
ScHint aHint(nHint, ScAddress());
for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab) for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
{ {
ScTable* pTab = FetchTable(nTab); ScTable* pTab = FetchTable(nTab);
if (!pTab) if (!pTab)
continue; continue;
rPos.SetTab(nTab); bIsBroadcasted |= pTab->BroadcastBroadcasters( nCol1, nRow1, nCol2, nRow2, aHint);
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;
}
}
}
} }
} }
......
...@@ -1729,6 +1729,16 @@ void ScTable::BroadcastRecalcOnRefMove() ...@@ -1729,6 +1729,16 @@ void ScTable::BroadcastRecalcOnRefMove()
aCol[i].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( void ScTable::TransferListeners(
ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCCOL nColDelta, SCROW nRowDelta ) SCCOL nColDelta, SCROW nRowDelta )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment