[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