summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-08-22 11:43:15 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-08-25 15:27:58 +0200
commitc47eb8afd1b941a4dca832cfad85ba750c76635d (patch)
tree283e513b21840c9e8c5b82f9b71a5fcd0f143b21
parent27bde9a6abf6c73d5345b0a85b81afc8470d25cf (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.hxx3
-rw-r--r--sc/inc/document.hxx4
-rw-r--r--sc/inc/table.hxx13
-rw-r--r--sc/source/core/data/document.cxx17
-rw-r--r--sc/source/core/data/drwlayer.cxx34
-rw-r--r--sc/source/core/data/table1.cxx14
-rw-r--r--sc/source/core/data/table2.cxx9
-rw-r--r--sc/source/core/data/table3.cxx13
-rw-r--r--sc/source/core/data/table5.cxx4
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)
{