sc/source/core/data/column3.cxx |   37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

New commits:
commit c315a2f7b99fc1dfbc3fc834590d22fbe41ea70f
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Mon Apr 4 16:30:58 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Fri Apr 22 14:19:19 2022 +0200

    limit Interpret() for dirty cells only to the given row range (bsc#1197497)
    
    ScColumn::InterpretDirtyCells() already takes a row range, and Interpret()
    can take a range inside a formula group, so don't lose the information
    in DirtyCellInterpreter, otherwise a whole large formula could be
    interpreted when just a subset would be enough.
    
    Change-Id: I93e5a7a212976be6fd588de6f68204cd1a271348
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133305
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 8d5a9363a02a..3c75230b5c69 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -103,13 +103,46 @@ void ScColumn::BroadcastRows( SCROW nStartRow, SCROW 
nEndRow, SfxHintId nHint )
 
 namespace {
 
-struct DirtyCellInterpreter
+class DirtyCellInterpreter
 {
+public:
     void operator() (size_t, ScFormulaCell* p)
     {
-        if (p->GetDirty())
+        if(!p->GetDirty())
+            return;
+        // Interpret() takes a range in a formula group, so group those 
together.
+        if( firstCell != nullptr && p->GetCellGroup() == p->GetCellGroup()
+            && p->aPos.Row() == lastPos.Row() + 1 )
+        {
+            assert( p->aPos.Tab() == lastPos.Tab() && p->aPos.Col() == 
lastPos.Col());
+            lastPos = p->aPos; // Extend range.
+            return;
+        }
+        flushPending();
+        if( !p->GetCellGroup())
+        {
             p->Interpret();
+            return;
+        }
+        firstCell = p;
+        lastPos = p->aPos;
+
+    }
+    ~DirtyCellInterpreter()
+    {
+        flushPending();
+    }
+private:
+    void flushPending()
+    {
+        if(firstCell == nullptr)
+            return;
+        SCROW firstRow = firstCell->GetCellGroup()->mpTopCell->aPos.Row();
+        firstCell->Interpret(firstCell->aPos.Row() - firstRow, lastPos.Row() - 
firstRow);
+        firstCell = nullptr;
     }
+    ScFormulaCell* firstCell = nullptr;
+    ScAddress lastPos;
 };
 
 }

Reply via email to