summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-12-05 22:54:41 +0100
committerAndras Timar <andras.timar@collabora.com>2015-01-24 16:54:35 +0100
commit6059081586acec91ac2b3df8edc7fba4a2d3465e (patch)
tree42da170940b30cba4be9733793fce43c99c4ea6c /sc
parentd09ff964173ae4349d668092af21302ee5bf5b1b (diff)
Ctrl+A and Data Sort took ages to broadcast ALL cells, fdo#81501 related
Noticed when investigating fdo#81501 Squashed commits: Fix high memory usage when sorting cells in Calc. (fdo#81501) Empty columns were being unnecessarily included in the sorting range which caused extra allocation. This happens when you select the entire sheet to sort. There was already code to skip empty trailing cells in rows but not to skip empty columns. Reviewed-on: https://gerrit.libreoffice.org/13294 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com> (cherry picked from commit c50d8bf596f527bb53b86dd04da652ed72f2c549) actually use identical code for both byRow and byCol, fdo#81501 follow-up (cherry picked from commit 1e4235f8b2dc693b0fb1edade9db25a631bdbf94) trim also empty leading column ranges, fdo#81501 follow-up (cherry picked from commit c7b57c6c2b15a4b9f65dafb642e3f1da402e62ca) Ctrl+A and Data Sort took ages to broadcast ALL cells ... now that also empty cells are to be broadcasted. Set dirty and broadcast only the effective data range as determined by Sort. This is more a workaround, a cleaner solution would be to refactor the SetDirty() algorithm to iterate only through broadcasters and use AreaBroadcast() to notify area listeners. However, this can also be easily backported to 4-3. (cherry picked from commit 9a568c41ccd1ccf6073758973da5914a44f629d2) 982e03a12dd80be0787f22dce4495065775e7de0 eaeea85149e4b6d263b112205bb17c155e2d12be 6d68ca0088cec6a8328a3e93364ac928ef69babe Change-Id: Ieac22647bb13165cbf66cb1a93f567e5169fff6a Reviewed-on: https://gerrit.libreoffice.org/13323 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/document.hxx6
-rw-r--r--sc/inc/table.hxx6
-rw-r--r--sc/source/core/data/documen3.cxx2
-rw-r--r--sc/source/core/data/table3.cxx25
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx1
5 files changed, 26 insertions, 14 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f37bfa2e0961..31da4707a8b6 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1678,8 +1678,12 @@ public:
SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
+ /** Sort a range of data.
+ @param rSortParam may get adjusted to the actual range used if it did
+ encompass leading or trailing empty blocks
+ */
void Sort(
- SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
+ SCTAB nTab, ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
ScProgress* pProgress, sc::ReorderParam* pUndo );
void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 49b8571c7e8c..8a01b9e9f35c 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -825,8 +825,12 @@ public:
void StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
void ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+ /** Sort a range of data.
+ @param rSortParam may get adjusted to the actual range used if it did
+ encompass leading or trailing empty blocks
+ */
void Sort(
- const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
+ ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
ScProgress* pProgress, sc::ReorderParam* pUndo );
void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index ef39f334f552..3cb62a9526bb 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1366,7 +1366,7 @@ bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, b
}
void ScDocument::Sort(
- SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
+ SCTAB nTab, ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
ScProgress* pProgress, sc::ReorderParam* pUndo )
{
if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index fd22eadde1d9..65e3c37e3837 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1402,10 +1402,9 @@ void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 )
}
void ScTable::Sort(
- const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
+ ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
ScProgress* pProgress, sc::ReorderParam* pUndo )
{
- aSortParam = rSortParam;
InitSortCollator( rSortParam );
bGlobalKeepQuery = bKeepQuery;
@@ -1419,14 +1418,21 @@ void ScTable::Sort(
pUndo->mbHasHeaders = rSortParam.bHasHeader;
}
+ // Trim empty leading and trailing column ranges.
+ while (rSortParam.nCol1 < rSortParam.nCol2 && aCol[rSortParam.nCol1].IsEmptyBlock(rSortParam.nRow1, rSortParam.nRow2))
+ ++rSortParam.nCol1;
+ while (rSortParam.nCol1 < rSortParam.nCol2 && aCol[rSortParam.nCol2].IsEmptyBlock(rSortParam.nRow1, rSortParam.nRow2))
+ --rSortParam.nCol2;
+
if (rSortParam.bByRow)
{
SCROW nLastRow = 0;
- for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; nCol++)
+ for (SCCOL nCol = rSortParam.nCol1; nCol <= rSortParam.nCol2; nCol++)
nLastRow = std::max(nLastRow, aCol[nCol].GetLastDataPos());
- nLastRow = std::min(nLastRow, aSortParam.nRow2);
+ rSortParam.nRow2 = nLastRow = std::min(nLastRow, rSortParam.nRow2);
SCROW nRow1 = (rSortParam.bHasHeader ?
- aSortParam.nRow1 + 1 : aSortParam.nRow1);
+ rSortParam.nRow1 + 1 : rSortParam.nRow1);
+ aSortParam = rSortParam; // must be assigned before calling IsSorted()
if (!IsSorted(nRow1, nLastRow))
{
if(pProgress)
@@ -1449,13 +1455,10 @@ void ScTable::Sort(
}
else
{
- SCCOL nLastCol;
- for (nLastCol = aSortParam.nCol2;
- (nLastCol > aSortParam.nCol1) && aCol[nLastCol].IsEmptyBlock(aSortParam.nRow1, aSortParam.nRow2); nLastCol--)
- {
- }
+ SCCOL nLastCol = rSortParam.nCol2;
SCCOL nCol1 = (rSortParam.bHasHeader ?
- aSortParam.nCol1 + 1 : aSortParam.nCol1);
+ rSortParam.nCol1 + 1 : rSortParam.nCol1);
+ aSortParam = rSortParam; // must be assigned before calling IsSorted()
if (!IsSorted(nCol1, nLastCol))
{
if(pProgress)
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index a1920eb70170..c4e81bcbcbf7 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -518,6 +518,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
bool bUpdateRefs = aInputOption.GetSortRefUpdate();
ScProgress aProgress(&rDocShell, ScGlobal::GetRscString(STR_PROGRESS_SORTING), 0);
+ // aLocalParam range now may get adapted to exclude empty edges
pDoc->Sort(nTab, aLocalParam, bRepeatQuery, bUpdateRefs, &aProgress, &aUndoParam);
}