[Libreoffice-commits] core.git: sc/inc sc/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Tue May 14 20:08:14 UTC 2019


 sc/inc/cellform.hxx               |    4 ++--
 sc/inc/cellvalue.hxx              |    4 ++--
 sc/inc/column.hxx                 |   16 ++++++++++++++--
 sc/inc/table.hxx                  |    2 +-
 sc/source/core/data/cellvalue.cxx |    4 ++--
 sc/source/core/data/column2.cxx   |    5 +++++
 sc/source/core/data/column3.cxx   |    7 ++-----
 sc/source/core/data/table6.cxx    |   31 ++++++++++++++++++++-----------
 sc/source/core/tool/cellform.cxx  |    4 ++--
 9 files changed, 50 insertions(+), 27 deletions(-)

New commits:
commit fce7c123203c91f62b45447f45e1d1f1b45d5b48
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue May 14 15:59:29 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue May 14 22:06:44 2019 +0200

    cache cell positions when searching in calc (tdf#108347)
    
    The document has a large number of rows, and mdds normally always searches
    from the first item when looking up the container position, which leads
    to a quadratic cost when searching the entire sheet. GetCellValue()
    already has a variant that caches the last position, so just use it
    (and make sure to invalidate if it's search&replace and something changes).
    
    Change-Id: I26da60cebf641e10ed92e548fe5f9016900d3cf0
    Reviewed-on: https://gerrit.libreoffice.org/72290
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/sc/inc/cellform.hxx b/sc/inc/cellform.hxx
index 618ad7146220..6a21b525defa 100644
--- a/sc/inc/cellform.hxx
+++ b/sc/inc/cellform.hxx
@@ -34,7 +34,7 @@ class SC_DLLPUBLIC ScCellFormat
 public:
 
     static void GetString(
-        ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString,
+        const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString,
         Color** ppColor, SvNumberFormatter& rFormatter, const ScDocument* pDoc, bool bNullVals = true,
         bool bFormula  = false, bool bUseStarFormat = false );
 
@@ -44,7 +44,7 @@ public:
         bool bFormula  = false );
 
     static void GetInputString(
-        ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter,
+        const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter,
         const ScDocument* pDoc );
 
     static OUString GetOutputString(
diff --git a/sc/inc/cellvalue.hxx b/sc/inc/cellvalue.hxx
index 153411c2b63e..7b6e3aad5794 100644
--- a/sc/inc/cellvalue.hxx
+++ b/sc/inc/cellvalue.hxx
@@ -78,7 +78,7 @@ struct SC_DLLPUBLIC ScCellValue
 
     void release( ScColumn& rColumn, SCROW nRow, sc::StartListeningType eListenType = sc::SingleCellListening );
 
-    OUString getString( const ScDocument* pDoc );
+    OUString getString( const ScDocument* pDoc ) const;
 
     bool isEmpty() const;
 
@@ -156,7 +156,7 @@ struct SC_DLLPUBLIC ScRefCellValue
      *          specific fields can not be resolved. See
      *          ScEditUtil::GetString().
      */
-    OUString getString( const ScDocument* pDoc );
+    OUString getString( const ScDocument* pDoc ) const;
 
     /**
      * Retrieve a string value without modifying the states of any objects in
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index bb218ea37c72..023e77427e01 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -22,6 +22,7 @@
 
 #include "global.hxx"
 #include "address.hxx"
+#include "cellvalue.hxx"
 #include "rangelst.hxx"
 #include "types.hxx"
 #include "mtvelements.hxx"
@@ -355,9 +356,16 @@ public:
     void SetValue( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, double fVal, bool bBroadcast = true );
     void        SetError( SCROW nRow, const FormulaError nError);
 
-    void        GetString( SCROW nRow, OUString& rString, const ScInterpreterContext* pContext = nullptr ) const;
+    void        GetString( SCROW nRow, OUString& rString, const ScInterpreterContext* pContext = nullptr ) const
+        { return GetString( GetCellValue( nRow ), nRow, rString, pContext ); }
+    void        GetString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
+                           OUString& rString, const ScInterpreterContext* pContext = nullptr ) const
+        { return GetString( GetCellValue( rBlockPos, nRow ), nRow, rString, pContext ); }
     double* GetValueCell( SCROW nRow );
-    void        GetInputString( SCROW nRow, OUString& rString ) const;
+    void        GetInputString( SCROW nRow, OUString& rString ) const
+        { return GetInputString( GetCellValue( nRow ), nRow, rString ); }
+    void        GetInputString( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow, OUString& rString ) const
+        { return GetInputString( GetCellValue( rBlockPos, nRow ), nRow, rString ); }
     double      GetValue( SCROW nRow ) const;
     const EditTextObject* GetEditText( SCROW nRow ) const;
     void RemoveEditTextCharAttribs( SCROW nRow, const ScPatternAttr& rAttr );
@@ -599,6 +607,7 @@ public:
     // cell notes
     ScPostIt* GetCellNote( SCROW nRow );
     const ScPostIt* GetCellNote( SCROW nRow ) const;
+    ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow );
     const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
     void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership );
     bool HasCellNotes() const;
@@ -729,6 +738,9 @@ private:
         sc::CellStoreType::const_iterator& itPos, SCROW nRow, bool bForward) const;
     SCROW FindNextVisibleRow(SCROW nRow, bool bForward) const;
 
+    void GetString( const ScRefCellValue& cell, SCROW nRow, OUString& rString, const ScInterpreterContext* pContext = nullptr ) const;
+    void GetInputString( const ScRefCellValue& cell, SCROW nRow, OUString& rString ) const;
+
     /**
      * Called whenever the state of cell array gets modified i.e. new cell
      * insertion, cell removal or relocation, cell value update and so on.
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index dbbf7b57d831..547d9936e44b 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1106,7 +1106,7 @@ private:
                                 const ScPatternAttr& rAttr, sal_uInt16 nFormatNo);
     void        GetAutoFormatAttr(SCCOL nCol, SCROW nRow, sal_uInt16 nIndex, ScAutoFormatData& rData);
     void        GetAutoFormatFrame(SCCOL nCol, SCROW nRow, sal_uInt16 nFlags, sal_uInt16 nIndex, ScAutoFormatData& rData);
-    bool        SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
+    bool        SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
                            const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc);
     bool        Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
                        const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc);
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index b131debdb7a2..7fffc669ee6c 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -491,7 +491,7 @@ void ScCellValue::release( ScColumn& rColumn, SCROW nRow, sc::StartListeningType
     mfValue = 0.0;
 }
 
-OUString ScCellValue::getString( const ScDocument* pDoc )
+OUString ScCellValue::getString( const ScDocument* pDoc ) const
 {
     return getStringImpl(*this, pDoc);
 }
@@ -647,7 +647,7 @@ double ScRefCellValue::getRawValue() const
     return 0.0;
 }
 
-OUString ScRefCellValue::getString( const ScDocument* pDoc )
+OUString ScRefCellValue::getString( const ScDocument* pDoc ) const
 {
     return getStringImpl(*this, pDoc);
 }
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index d1654ac7e49e..bea0497e4c84 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1904,6 +1904,11 @@ const ScPostIt* ScColumn::GetCellNote( sc::ColumnBlockConstPosition& rBlockPos,
     return sc::cellnote_block::at(*aPos.first->data, aPos.second);
 }
 
+ScPostIt* ScColumn::GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow )
+{
+    return const_cast<ScPostIt*>(const_cast<const ScColumn*>(this)->GetCellNote( rBlockPos, nRow ));
+}
+
 void ScColumn::SetCellNote(SCROW nRow, std::unique_ptr<ScPostIt> pNote)
 {
     //pNote->UpdateCaptionPos(ScAddress(nCol, nRow, nTab)); // TODO notes useful ? slow import with many notes
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a760f1428336..26847a3a6126 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2822,10 +2822,8 @@ void ScColumn::SetValue(
         BroadcastNewCell(nRow);
 }
 
-void ScColumn::GetString( SCROW nRow, OUString& rString, const ScInterpreterContext* pContext ) const
+void ScColumn::GetString( const ScRefCellValue& aCell, SCROW nRow, OUString& rString, const ScInterpreterContext* pContext ) const
 {
-    ScRefCellValue aCell = GetCellValue(nRow);
-
     // ugly hack for ordering problem with GetNumberFormat and missing inherited formats
     if (aCell.meType == CELLTYPE_FORMULA)
         aCell.mpFormula->MaybeInterpret();
@@ -2849,9 +2847,8 @@ double* ScColumn::GetValueCell( SCROW nRow )
     return &sc::numeric_block::at(*it->data, aPos.second);
 }
 
-void ScColumn::GetInputString( SCROW nRow, OUString& rString ) const
+void ScColumn::GetInputString( const ScRefCellValue& aCell, SCROW nRow, OUString& rString ) const
 {
-    ScRefCellValue aCell = GetCellValue(nRow);
     sal_uLong nFormat = GetNumberFormat(GetDoc()->GetNonThreadedContext(), nRow);
     ScCellFormat::GetInputString(aCell, nFormat, rString, *(GetDoc()->GetFormatTable()), GetDoc());
 }
diff --git a/sc/source/core/data/table6.cxx b/sc/source/core/data/table6.cxx
index 728a86ee744b..4daeb308bfd7 100644
--- a/sc/source/core/data/table6.cxx
+++ b/sc/source/core/data/table6.cxx
@@ -47,7 +47,7 @@ bool lcl_GetTextWithBreaks( const EditTextObject& rData, ScDocument* pDoc, OUStr
 
 }
 
-bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRow,
+bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow,
                          const ScMarkData& rMark, OUString& rUndoStr, ScDocument* pUndoDoc)
 {
     if ( !IsColRowValid( nCol, nRow ) )
@@ -69,13 +69,13 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
     ScPostIt* pNote;
     if (rSearchItem.GetCellType() == SvxSearchCellType::NOTE)
     {
-        pNote = aCol[nCol].GetCellNote(nRow);
+        pNote = aCol[nCol].GetCellNote(rBlockPos, nRow);
         if (!pNote)
             return false;
     }
     else
     {
-        aCell = aCol[nCol].GetCellValue(nRow);
+        aCell = aCol[nCol].GetCellValue(rBlockPos, nRow);
         if (aCell.isEmpty())
             return false;
         pNote = nullptr;
@@ -94,9 +94,9 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
             else
             {
                 if( !bSearchFormatted )
-                    aCol[nCol].GetInputString( nRow, aString );
+                    aCol[nCol].GetInputString( rBlockPos, nRow, aString );
                 else
-                    aCol[nCol].GetString( nRow, aString );
+                    aCol[nCol].GetString( rBlockPos, nRow, aString );
             }
             break;
         }
@@ -106,9 +106,9 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
             else
             {
                 if( !bSearchFormatted )
-                    aCol[nCol].GetInputString( nRow, aString );
+                    aCol[nCol].GetInputString( rBlockPos, nRow, aString );
                 else
-                    aCol[nCol].GetString( nRow, aString );
+                    aCol[nCol].GetString( rBlockPos, nRow, aString );
             }
             break;
         case SvxSearchCellType::NOTE:
@@ -262,6 +262,7 @@ bool ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
         else
             aCol[nCol].SetString(nRow, nTab, aString, pDocument->GetAddressConvention());
         // pCell is invalid now (deleted)
+        aCol[nCol].InitBlockPosition( rBlockPos ); // invalidate also the cached position
     }
     return bFound;
 }
@@ -326,6 +327,10 @@ bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
 
     bool bSkipFiltered = !rSearchItem.IsSearchFiltered();
     bool bSearchNotes = (rSearchItem.GetCellType() == SvxSearchCellType::NOTE);
+    // We need to cache sc::ColumnBlockConstPosition per each column.
+    std::vector< sc::ColumnBlockConstPosition > blockPos( nLastCol + 1 );
+    for( SCCOL i = 0; i <= nLastCol; ++i )
+        aCol[ i ].InitBlockPosition( blockPos[ i ] );
     if (!bAll && rSearchItem.GetBackward())
     {
         SCROW nLastNonFilteredRow = MAXROW + 1;
@@ -341,7 +346,8 @@ bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
 
                 while (!bFound && (nCol >= 0))
                 {
-                    bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                    bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ], nRow,
+                                        rMark, rUndoStr, pUndoDoc);
                     if (!bFound)
                     {
                         bool bIsEmpty;
@@ -378,7 +384,8 @@ bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
                     if (bSkipFiltered)
                         SkipFilteredRows(nRow, nLastNonFilteredRow, false);
 
-                    bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                    bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
+                                        nRow, rMark, rUndoStr, pUndoDoc);
                     if (!bFound)
                     {
                         if (bSearchNotes)
@@ -430,7 +437,8 @@ bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
 
                 while (!bFound && (nCol <= nLastCol))
                 {
-                    bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                    bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
+                                        nRow, rMark, rUndoStr, pUndoDoc);
                     if (!bFound)
                     {
                         nCol++;
@@ -456,7 +464,8 @@ bool ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
                     if (bSkipFiltered)
                         SkipFilteredRows(nRow, nLastNonFilteredRow, true);
 
-                    bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                    bFound = SearchCell(rSearchItem, nCol, blockPos[ nCol ],
+                                        nRow, rMark, rUndoStr, pUndoDoc);
                     if (!bFound)
                     {
                         if (bSearchNotes)
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index 858097ed8357..e7e004471c0c 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -30,7 +30,7 @@
 #include <sc.hrc>
 #include <editutil.hxx>
 
-void ScCellFormat::GetString( ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString,
+void ScCellFormat::GetString( const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString,
                               Color** ppColor, SvNumberFormatter& rFormatter, const ScDocument* pDoc,
                               bool bNullVals, bool bFormula, bool bUseStarFormat )
 {
@@ -118,7 +118,7 @@ OUString ScCellFormat::GetString(
 }
 
 void ScCellFormat::GetInputString(
-    ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument* pDoc )
+    const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument* pDoc )
 {
     switch (rCell.meType)
     {


More information about the Libreoffice-commits mailing list