diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-08-22 11:43:15 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2017-08-25 15:27:58 +0200 |
commit | c47eb8afd1b941a4dca832cfad85ba750c76635d (patch) | |
tree | 283e513b21840c9e8c5b82f9b71a5fcd0f143b21 | |
parent | 27bde9a6abf6c73d5345b0a85b81afc8470d25cf (diff) |
dynamic column container: more efficient loops over all cols
Create an ScColumnsRange class that returns a pair of (start,end)
iterators to go through the list of currently allocated columns.
This is a fairly thing wrapper around the underlying std::vector,
so it should be fairly efficient (two pointers, and pointer increment
for iteration).
If this style of iteration is acceptable, I'll go through the rest
of the code that does:
for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++)
type stuff, and change it to use ScColumnsRange.
Change-Id: I81501c69b7f5566c6204dde0d87a6fe0deb9743c
Reviewed-on: https://gerrit.libreoffice.org/41413
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | sc/inc/colcontainer.hxx | 3 | ||||
-rw-r--r-- | sc/inc/document.hxx | 4 | ||||
-rw-r--r-- | sc/inc/table.hxx | 13 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 17 | ||||
-rw-r--r-- | sc/source/core/data/drwlayer.cxx | 34 | ||||
-rw-r--r-- | sc/source/core/data/table1.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 9 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 13 | ||||
-rw-r--r-- | sc/source/core/data/table5.cxx | 4 |
9 files changed, 85 insertions, 26 deletions
diff --git a/sc/inc/colcontainer.hxx b/sc/inc/colcontainer.hxx index 3e97ed048f4d..bf2bd206850f 100644 --- a/sc/inc/colcontainer.hxx +++ b/sc/inc/colcontainer.hxx @@ -72,6 +72,9 @@ public: assert(aCols.size() > 0); return *aCols.back(); } + + ScColumnVector::const_iterator begin() const { return aCols.begin(); } + ScColumnVector::const_iterator end() const { return aCols.end(); } }; diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 6650c2e111ee..bc1f4ea2f5cf 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -198,6 +198,7 @@ class SvtBroadcaster; enum class ScDBDataPortion; enum class ScSheetEventId; class BitmapEx; +class ScColumnsRange; namespace sc { @@ -295,6 +296,7 @@ friend class sc::ColumnSpanSet; friend class sc::EditTextIterator; friend class sc::FormulaGroupAreaListener; friend class sc::TableColumnBlockPositionSet; +friend class ScDrawLayer; typedef std::vector<ScTable*> TableContainer; @@ -2383,6 +2385,8 @@ private: void EndListeningGroups( const std::vector<ScAddress>& rPosArray ); void SetNeedsListeningGroups( const std::vector<ScAddress>& rPosArray ); + + ScColumnsRange GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const; }; #endif diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index d64bc90b4f3b..d41d67d10a1c 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -117,6 +117,17 @@ class ScDBData; class ScDocumentImport; class ScHint; +class ScColumnsRange final +{ + typedef std::vector<ScColumn*>::const_iterator const_iterator; + const const_iterator maBegin; + const const_iterator maEnd; +public: + ScColumnsRange(const_iterator nBegin, const_iterator nEnd) : maBegin(nBegin), maEnd(nEnd) {} + const const_iterator & begin() { return maBegin; } + const const_iterator & end() { return maEnd; } +}; + class ScTable { private: @@ -1024,6 +1035,8 @@ public: */ static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow ); + ScColumnsRange GetColumnsRange(SCCOL begin, SCCOL end) const; + private: void FillFormulaVertical( diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 5f1278f8c268..6bb050d6dcf0 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2518,6 +2518,17 @@ const ScTable* ScDocument::FetchTable( SCTAB nTab ) const return maTabs[nTab]; } +ScColumnsRange ScDocument::GetColumnsRange( SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const +{ + if (!TableExists(nTab)) + { + std::vector<ScColumn*> aEmptyVector; + return ScColumnsRange(aEmptyVector.begin(), aEmptyVector.end()); + } + + return maTabs[nTab]->GetColumnsRange(nColBegin, nColEnd); +} + void ScDocument::MergeNumberFormatter(const ScDocument* pSrcDoc) { SvNumberFormatter* pThisFormatter = xPoolHelper->GetFormTable(); @@ -6580,8 +6591,9 @@ ScAddress ScDocument::GetNotePosition( size_t nIndex ) const { for (size_t nTab = 0; nTab < maTabs.size(); ++nTab) { - for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) + for (const ScColumn* pCol : GetColumnsRange(nTab, 0, MAXCOL)) { + SCCOL nCol = pCol->GetCol(); size_t nColNoteCount = GetNoteCount(nTab, nCol); if (!nColNoteCount) continue; @@ -6607,8 +6619,9 @@ ScAddress ScDocument::GetNotePosition( size_t nIndex ) const ScAddress ScDocument::GetNotePosition( size_t nIndex, SCTAB nTab ) const { - for (SCCOL nCol=0; nCol<MAXCOLCOUNT; nCol++) + for (const ScColumn * pCol : GetColumnsRange(nTab, 0, MAXCOL)) { + SCCOL nCol = pCol->GetCol(); size_t nColNoteCount = GetNoteCount(nTab, nCol); if (!nColNoteCount) continue; diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 2242a6d53744..ddf2cf41dfb6 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -70,6 +70,7 @@ #include "postit.hxx" #include "attrib.hxx" #include "charthelper.hxx" +#include "table.hxx" #include <basegfx/matrix/b2dhommatrix.hxx> #include <vcl/field.hxx> @@ -1064,17 +1065,36 @@ bool ScDrawLayer::GetPrintArea( ScRange& rRange, bool bSetHor, bool bSetVer ) co nStartX = HmmToTwips( nStartX ); nEndX = HmmToTwips( nEndX ); long nWidth; - SCCOL i; nWidth = 0; - for (i=0; i<=MAXCOL && nWidth<=nStartX; i++) - nWidth += pDoc->GetColWidth(i,nTab); - rRange.aStart.SetCol( i>0 ? (i-1) : 0 ); + rRange.aStart.SetCol( 0 ); + if (nWidth <= nStartX) + { + for (const ScColumn* pCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL)) + { + nWidth += pDoc->GetColWidth(pCol->GetCol(),nTab); + if (nWidth > nStartX) + { + rRange.aStart.SetCol( pCol->GetCol() ); + break; + } + } + } nWidth = 0; - for (i=0; i<=MAXCOL && nWidth<=nEndX; i++) //TODO: start at Start - nWidth += pDoc->GetColWidth(i,nTab); - rRange.aEnd.SetCol( i>0 ? (i-1) : 0 ); + rRange.aEnd.SetCol( 0 ); + if (nWidth <= nEndX) + { + for (const ScColumn* pCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL)) //TODO: start at Start + { + nWidth += pDoc->GetColWidth(pCol->GetCol(),nTab); + if (nWidth > nEndX) + { + rRange.aEnd.SetCol( pCol->GetCol() ); + break; + } + } + } } if (bSetVer) diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index ad1a50ee3828..c10100d4777b 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -1681,14 +1681,14 @@ void ScTable::UpdateReference( void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, ScDocument* pUndoDoc ) { - for ( SCCOL i=0; i<=MAXCOL; i++ ) - aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc ); + for (ScColumn* pCol : GetColumnsRange(0, MAXCOL)) + pCol->UpdateTranspose( rSource, rDest, pUndoDoc ); } void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ) { - for ( SCCOL i=0; i<=MAXCOL; i++ ) - aCol[i].UpdateGrow( rArea, nGrowX, nGrowY ); + for (ScColumn* pCol : GetColumnsRange(0, MAXCOL)) + pCol->UpdateGrow( rArea, nGrowX, nGrowY ); } void ScTable::UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt ) @@ -2383,4 +2383,10 @@ const ScConditionalFormatList* ScTable::GetCondFormList() const return mpCondFormatList.get(); } +ScColumnsRange ScTable::GetColumnsRange(SCCOL nColBegin, SCCOL nColEnd) const +{ + // because the range is inclusive, some code will pass nColEnd<nColBegin to indicate an empty range + return ScColumnsRange(aCol.begin() + nColBegin, nColEnd < nColBegin ? (aCol.begin() + nColBegin) : (aCol.begin() + nColEnd + 1)); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index b42959a46403..7871f04318fb 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1650,10 +1650,8 @@ CommentCaptionState ScTable::GetAllNoteCaptionsState(const ScRange& rRange, std: void ScTable::GetUnprotectedCells( ScRangeList& rRangeList ) const { - for (SCCOL nCol = 0; nCol < MAXCOL; ++nCol) - { - aCol[nCol].GetUnprotectedCells(0, MAXROW, rRangeList); - } + for (auto pCol : aCol) + pCol->GetUnprotectedCells(0, MAXROW, rRangeList); } bool ScTable::ContainsNotesInRange( const ScRange& rRange ) const @@ -2109,8 +2107,9 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC SCROW nY1 = pRowInfo[0].nRowNo; SCROW nY2 = pRowInfo[nArrCount-1].nRowNo; - for (SCCOL nCol=0; nCol<=MAXCOL; nCol++) + for (ScColumn* pCol : GetColumnsRange(0, MAXCOL)) { + SCCOL nCol = pCol->GetCol(); if (!ColHidden(nCol)) { SCSIZE nArrY = 0; diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 39eff62a2d87..926301cd4582 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -1849,15 +1849,16 @@ public: SCCOL nStartCol = mrParam.nCol1; SCCOL nEndCol = mrParam.nCol2; - for (SCCOL i = 0; i <= MAXCOL; ++i) + for (const ScColumn* pCol : mrTab.GetColumnsRange(0, nStartCol - 1)) { - if (nStartCol <= i && i <= nEndCol) - continue; - - if (mrTab.HasData(i, nRow)) + if (mrTab.HasData(pCol->GetCol(), nRow)) + return true; + } + for (const ScColumn* pCol : mrTab.GetColumnsRange(nEndCol + 1, MAXCOL)) + { + if (mrTab.HasData(pCol->GetCol(), nRow)) return true; } - return false; } }; diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index d6c7a8527e4b..46f36b11bba0 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -290,8 +290,8 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) if (nEndCol < MAXCOL) { SetColBreak(nEndCol+1, true, false); // AREABREAK - for (nX=nEndCol+2; nX<=MAXCOL; nX++) - RemoveColBreak(nX, true, false); + for (const ScColumn* pCol : GetColumnsRange(nEndCol + 2, MAXCOL)) + RemoveColBreak(pCol->GetCol(), true, false); } if (nEndRow < MAXROW) { |