[Libreoffice-commits] core.git: 2 commits - sc/inc sc/source
Eike Rathke
erack at redhat.com
Tue Dec 9 05:55:15 PST 2014
sc/inc/column.hxx | 8 ++++++++
sc/inc/table.hxx | 8 ++++++++
sc/source/core/data/column.cxx | 27 ++++++++++++++++++++-------
sc/source/core/data/documen7.cxx | 23 +++--------------------
sc/source/core/data/document.cxx | 4 ++++
sc/source/core/data/table2.cxx | 10 ++++++++++
6 files changed, 53 insertions(+), 27 deletions(-)
New commits:
commit b1d4a2ae3d1b461bc52768ed62f354558596fa39
Author: Eike Rathke <erack at redhat.com>
Date: Tue Dec 9 14:48:36 2014 +0100
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
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index f7223bb..bef0d05 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 7661fda..89a9a49 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 8d873af..77c51ea 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 64fc158..af7337e 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 c462d61..938639b 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 )
commit 3397cb614205c6954915c88005276ba38fbae5ce
Author: Eike Rathke <erack at redhat.com>
Date: Tue Dec 9 14:45:45 2014 +0100
add a comment about side effects and whether we want them or not
Change-Id: I9cebe8f7979fd0b502fb23e7048b24a5b9ceb5d4
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 248cc9d..311f7b7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3630,6 +3630,10 @@ void ScDocument::SetDirty( const ScRange& rRange, bool bIncludeEmptyCells )
if (maTabs[i]) maTabs[i]->SetDirty( rRange,
(bIncludeEmptyCells ? ScColumn::BROADCAST_BROADCASTERS : ScColumn::BROADCAST_DATA_POSITIONS));
+ /* TODO: this now also notifies conditional formatting and does an UNO
+ * broadcast, which wasn't done here before. Is that an actually
+ * desired side effect, or should we come up with a method that
+ * doesn't? */
if (bIncludeEmptyCells)
BroadcastCells( rRange, SC_HINT_DATACHANGED, false);
}
More information about the Libreoffice-commits
mailing list