sc/inc/column.hxx                  |    9 ++++++++-
 sc/inc/table.hxx                   |    8 ++++----
 sc/source/core/data/column.cxx     |    7 ++++---
 sc/source/core/data/document10.cxx |    2 +-
 sc/source/core/data/table1.cxx     |    5 +++--
 sc/source/core/data/table2.cxx     |   27 ++++++++++++++++-----------
 sc/source/core/data/table3.cxx     |   20 +++++++++++++-------
 sc/source/core/data/table7.cxx     |    2 +-
 8 files changed, 50 insertions(+), 30 deletions(-)

New commits:
commit 8466499595e899ff7db737729bb4ecea17e30a04
Author:     Luboš Luňák <[email protected]>
AuthorDate: Wed May 18 18:05:31 2022 +0200
Commit:     Luboš Luňák <[email protected]>
CommitDate: Thu May 19 06:52:05 2022 +0200

    ScTable::TestInsertRow() does not need to allocate all columns
    
    Change-Id: Ic213997edf6838282a38e444a638713a72397fb4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134549
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Luboš Luňák <[email protected]>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index fb6cb5ac8f6f..7797e58c2f76 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -169,6 +169,8 @@ public:
 
     void        ClearSelectionItems( const sal_uInt16* pWhich, const 
ScMarkData& rMark, SCCOL nCol );
     void        ChangeSelectionIndent( bool bIncrement, const ScMarkData& 
rMark, SCCOL nCol );
+
+    bool        TestInsertRow( SCSIZE nSize ) const;
 };
 
 // Use protected inheritance to prevent publishing some internal ScColumnData
@@ -1031,4 +1033,9 @@ inline void 
ScColumnData::SetAttrEntries(std::vector<ScAttrEntry> && vNewData)
     pAttrArray->SetAttrEntries( std::move( vNewData ));
 }
 
+inline bool ScColumnData::TestInsertRow( SCSIZE nSize ) const
+{
+    return pAttrArray->TestInsertRow( nSize );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 752b5c391e3b..f42d35f7bb61 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -134,15 +134,20 @@ void ScTable::SetCalcNotification( bool bSet )
 
 bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, 
SCSIZE nSize ) const
 {
-    bool bTest = true;
-
     if ( nStartCol==0 && nEndCol==rDocument.MaxCol() && pOutlineTable )
-        bTest = pOutlineTable->TestInsertRow(nSize);
+        if (!pOutlineTable->TestInsertRow(nSize))
+            return false;
+
+    SCCOL maxCol = ClampToAllocatedColumns(nEndCol);
+    for (SCCOL i=nStartCol; i<=maxCol; i++)
+        if (!aCol[i].TestInsertRow(nStartRow, nSize))
+            return false;
 
-    for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
-        bTest = 
const_cast<ScTable*>(this)->CreateColumnIfNotExists(i).TestInsertRow(nStartRow, 
nSize);
+    if( maxCol != nEndCol )
+        if (!aDefaultColData.TestInsertRow(nSize))
+            return false;
 
-    return bTest;
+    return true;
 }
 
 void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, 
SCSIZE nSize )
commit 109db286d6a74cd4775d7ad724f86d9e29e052a0
Author:     Luboš Luňák <[email protected]>
AuthorDate: Tue May 17 19:59:09 2022 +0200
Commit:     Luboš Luňák <[email protected]>
CommitDate: Thu May 19 06:51:52 2022 +0200

    make CreateColumnIfNotExists() non-const
    
    Generally const functions should not modify the data, so this
    generally should not be needed. Those functions that need to allocate
    a column because they can't/don't handle default values for
    non-existent columns well should go with const_cast, being
    an exception to the rule.
    
    Change-Id: I62706da5b447019542d6775f14064fa15b71f3c1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134488
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134548
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 5658915007a1..fb6cb5ac8f6f 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -376,7 +376,7 @@ public:
     bool       TestCopyScenarioTo( const ScColumn& rDestCol ) const;
     void        MarkScenarioIn( ScMarkData& rDestMark ) const;
 
-    void        CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) 
const;
+    void        CopyUpdated( const ScColumn* pPosCol, ScColumn& rDestCol ) 
const;
 
     void        SwapCol(ScColumn& rCol);
     void        MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol);
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 4e4e9d8d00c3..302803966a58 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -157,7 +157,7 @@ class ScTable
 private:
     typedef ::std::vector< ScRange > ScRangeVec;
 
-    mutable ScColContainer aCol;
+    ScColContainer aCol;
 
     OUString aName;
     OUString aCodeName;
@@ -284,14 +284,14 @@ public:
 
     ScOutlineTable* GetOutlineTable()               { return 
pOutlineTable.get(); }
 
-    ScColumn& CreateColumnIfNotExists( const SCCOL nScCol ) const
+    ScColumn& CreateColumnIfNotExists( const SCCOL nScCol )
     {
         if ( nScCol >= aCol.size() )
             CreateColumnIfNotExistsImpl(nScCol);
         return aCol[nScCol];
     }
     // out-of-line the cold part of the function
-    void CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const;
+    void CreateColumnIfNotExistsImpl( const SCCOL nScCol );
     sal_uInt64      GetCellCount() const;
     sal_uInt64      GetWeightedCount() const;
     sal_uInt64      GetWeightedCount(SCROW nStartRow, SCROW nEndRow) const;
@@ -581,7 +581,7 @@ public:
                             SCCOL nDestCol, SCROW nDestRow, SCTAB nDestTab );
 
     void        CopyScenarioFrom( const ScTable* pSrcTab );
-    void        CopyScenarioTo( const ScTable* pDestTab ) const;
+    void        CopyScenarioTo( ScTable* pDestTab ) const;
     bool        TestCopyScenarioTo( const ScTable* pDestTab ) const;
     void        MarkScenarioIn(ScMarkData& rMark, ScScenarioFlags nNeededBits) 
const;
     bool        HasScenarioRange( const ScRange& rRange ) const;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c98ef7ef3de1..a6293094f9a5 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1679,14 +1679,15 @@ void ScColumn::UndoToColumn(
         CopyToColumn(rCxt, nRow2+1, GetDoc().MaxRow(), 
InsertDeleteFlags::FORMULA, false, rColumn);
 }
 
-void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
+void ScColumn::CopyUpdated( const ScColumn* pPosCol, ScColumn& rDestCol ) const
 {
     // Copy cells from this column to the destination column only for those
-    // rows that are present in the position column (rPosCol).
+    // rows that are present in the position column (pPosCol).
 
     // First, mark all the non-empty cell ranges from the position column.
     sc::SingleColumnSpanSet aRangeSet(GetDoc().GetSheetLimits());
-    aRangeSet.scan(rPosCol);
+    if(pPosCol)
+        aRangeSet.scan(*pPosCol);
 
     // Now, copy cells from this column to the destination column for those
     // marked row ranges.
diff --git a/sc/source/core/data/document10.cxx 
b/sc/source/core/data/document10.cxx
index 2ceeb4954fd5..bcbc692e21ae 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -978,7 +978,7 @@ std::optional<sc::ColumnIterator> 
ScDocument::GetColumnIterator( SCTAB nTab, SCC
 
 void ScDocument::CreateColumnIfNotExists( SCTAB nTab, SCCOL nCol )
 {
-    const ScTable* pTab = FetchTable(nTab);
+    ScTable* pTab = FetchTable(nTab);
     if (!pTab)
         return;
 
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 71985c0475e7..a3003677d431 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2592,8 +2592,9 @@ void ScTable::DeleteBroadcasters(
 void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL 
nCol2, SCROW nRow2, svl::SharedStringPool* pPool ) const
 {
     size_t nMatCol = 0;
+    nCol2 = ClampToAllocatedColumns(nCol2);
     for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol, ++nMatCol)
-        CreateColumnIfNotExists(nCol).FillMatrix(rMat, nMatCol, nRow1, nRow2, 
pPool);
+        aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2, pPool);
 }
 
 void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, 
SCROW nRow2 )
@@ -2716,7 +2717,7 @@ ScColumnsRange ScTable::GetColumnsRange(SCCOL nColBegin, 
SCCOL nColEnd) const
 }
 
 // out-of-line the cold part of the CreateColumnIfNotExists function
-void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol ) const
+void ScTable::CreateColumnIfNotExistsImpl( const SCCOL nScCol )
 {
     // When doing multi-threaded load of, e.g. XLS files, we can hit this, 
which calls
     // into SfxItemPool::Put, in parallel with other code that calls into 
SfxItemPool::Put,
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 19707dff4403..752b5c391e3b 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -140,7 +140,7 @@ bool ScTable::TestInsertRow( SCCOL nStartCol, SCCOL 
nEndCol, SCROW nStartRow, SC
         bTest = pOutlineTable->TestInsertRow(nSize);
 
     for (SCCOL i=nStartCol; (i<=nEndCol) && bTest; i++)
-        bTest = CreateColumnIfNotExists(i).TestInsertRow(nStartRow, nSize);
+        bTest = 
const_cast<ScTable*>(this)->CreateColumnIfNotExists(i).TestInsertRow(nStartRow, 
nSize);
 
     return bTest;
 }
@@ -1531,10 +1531,9 @@ void ScTable::UndoToTable(
 
 void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const
 {
-    pPosTab->CreateColumnIfNotExists(aCol.size()-1);
     pDestTab->CreateColumnIfNotExists(aCol.size()-1);
     for (SCCOL i=0; i < aCol.size(); i++)
-        aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] );
+        aCol[i].CopyUpdated( pPosTab->FetchColumn(i), pDestTab->aCol[i] );
 }
 
 void ScTable::InvalidateTableArea()
@@ -1548,7 +1547,7 @@ void ScTable::InvalidatePageBreaks()
     mbPageBreaksValid = false;
 }
 
-void ScTable::CopyScenarioTo( const ScTable* pDestTab ) const
+void ScTable::CopyScenarioTo( ScTable* pDestTab ) const
 {
     OSL_ENSURE( bScenario, "bScenario == FALSE" );
 
@@ -2816,9 +2815,10 @@ void ScTable::MergeSelectionPattern( 
ScMergePatternState& rState, const ScMarkDa
 
     for (const sc::ColRowSpan & rSpan : aSpans)
     {
-        for (SCCOLROW i = rSpan.mnStart; i <= rSpan.mnEnd; ++i)
+        SCCOL maxCol = ClampToAllocatedColumns(rSpan.mnEnd);
+        for (SCCOL i = rSpan.mnStart; i <= maxCol; ++i)
         {
-            CreateColumnIfNotExists(i).MergeSelectionPattern( rState, rMark, 
bDeep );
+            aCol[i].MergeSelectionPattern( rState, rMark, bDeep );
         }
     }
 }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index c99bc9f8c7ce..139569a1012d 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1740,20 +1740,26 @@ short ScTable::Compare(SCCOLROW nIndex1, SCCOLROW 
nIndex2) const
         do
         {
             SCCOL nCol = 
static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField);
-            CreateColumnIfNotExists(nCol);
-            ScRefCellValue aCell1 = aCol[nCol].GetCellValue(nIndex1);
-            ScRefCellValue aCell2 = aCol[nCol].GetCellValue(nIndex2);
-            nRes = CompareCell(nSort, aCell1, nCol, nIndex1, aCell2, nCol, 
nIndex2);
+            nRes = 0;
+            if(nCol < GetAllocatedColumnsCount())
+            {
+                ScRefCellValue aCell1 = aCol[nCol].GetCellValue(nIndex1);
+                ScRefCellValue aCell2 = aCol[nCol].GetCellValue(nIndex2);
+                nRes = CompareCell(nSort, aCell1, nCol, nIndex1, aCell2, nCol, 
nIndex2);
+            }
         } while ( nRes == 0 && ++nSort < nMaxSorts && 
aSortParam.maKeyState[nSort].bDoSort );
     }
     else
     {
-        CreateColumnIfNotExists(std::max(nIndex1, nIndex2));
         do
         {
             SCROW nRow = aSortParam.maKeyState[nSort].nField;
-            ScRefCellValue aCell1 = aCol[nIndex1].GetCellValue(nRow);
-            ScRefCellValue aCell2 = aCol[nIndex2].GetCellValue(nRow);
+            ScRefCellValue aCell1;
+            ScRefCellValue aCell2;
+            if(nIndex1 < GetAllocatedColumnsCount())
+                aCell1 = aCol[nIndex1].GetCellValue(nRow);
+            if(nIndex2 < GetAllocatedColumnsCount())
+                aCell2 = aCol[nIndex2].GetCellValue(nRow);
             nRes = CompareCell( nSort, aCell1, static_cast<SCCOL>(nIndex1),
                     nRow, aCell2, static_cast<SCCOL>(nIndex2), nRow );
         } while ( nRes == 0 && ++nSort < nMaxSorts && 
aSortParam.maKeyState[nSort].bDoSort );
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 30788b0daca7..f7576361c8a1 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -427,7 +427,7 @@ std::optional<sc::ColumnIterator> 
ScTable::GetColumnIterator( SCCOL nCol, SCROW
     if (!ValidCol(nCol))
         return {};
 
-    return CreateColumnIfNotExists(nCol).GetColumnIterator(nRow1, nRow2);
+    return 
const_cast<ScTable*>(this)->CreateColumnIfNotExists(nCol).GetColumnIterator(nRow1,
 nRow2);
 }
 
 bool ScTable::EnsureFormulaCellResults( const SCCOL nCol1, SCROW nRow1, const 
SCCOL nCol2, SCROW nRow2, bool bSkipRunning )

Reply via email to