[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