diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-01-14 10:55:02 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-01-15 17:36:24 +0000 |
commit | adce7994e9cecf761381c87bc8ff77320077f894 (patch) | |
tree | d3b0ad41a03443b833a2e4fb7171c746585f32e8 | |
parent | 7ed845ae5682fdafb3390df85144388e240ccb89 (diff) |
fdo#73606: Avoid excessive and unnecessary heap allocation of array objects.
This is a leftover from the 1 million row conversion we did years ago.
Change-Id: Ib50819ed51c7017bcc559bfc8b6062ff46615d09
(cherry picked from commit df9243626b39742a9a148bea95796f8824fee68a)
Reviewed-on: https://gerrit.libreoffice.org/7425
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r-- | sc/inc/columnspanset.hxx | 18 | ||||
-rw-r--r-- | sc/inc/markdata.hxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/columnspanset.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/markdata.cxx | 21 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 24 | ||||
-rw-r--r-- | sc/source/ui/view/viewfunc.cxx | 2 |
8 files changed, 59 insertions, 28 deletions
diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx index 98533e240f37..62e96a8a41bd 100644 --- a/sc/inc/columnspanset.hxx +++ b/sc/inc/columnspanset.hxx @@ -25,6 +25,14 @@ namespace sc { struct ColumnBlockConstPosition; +struct RowSpan +{ + SCROW mnRow1; + SCROW mnRow2; + + RowSpan(SCROW nRow1, SCROW nRow2); +}; + /** * Structure that stores segments of boolean flags per column, and perform * custom action on those segments. @@ -85,15 +93,7 @@ class SingleColumnSpanSet public: typedef mdds::flat_segment_tree<SCROW, bool> ColumnSpansType; - struct Span - { - SCROW mnRow1; - SCROW mnRow2; - - Span(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {} - }; - - typedef std::vector<Span> SpansType; + typedef std::vector<RowSpan> SpansType; SingleColumnSpanSet(); diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx index 75937edde3e3..943419d62308 100644 --- a/sc/inc/markdata.hxx +++ b/sc/inc/markdata.hxx @@ -26,6 +26,12 @@ #include <set> +namespace sc { + +struct RowSpan; + +} + class ScMarkArray; class ScRangeList; @@ -103,6 +109,8 @@ public: SCCOLROW GetMarkColumnRanges( SCCOLROW* pRanges ); SCCOLROW GetMarkRowRanges( SCCOLROW* pRanges ); + void GetMarkedRowSpans( SCTAB nTab, std::vector<sc::RowSpan>& rSpans ); + bool IsColumnMarked( SCCOL nCol ) const; bool IsRowMarked( SCROW nRow ) const; bool IsAllMarked( const ScRange& rRange ) const; // Multi diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 2adf63c83271..ad16dd49d225 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -618,7 +618,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth( } else // "Select" the entire column if no selection exists. - aMarkedSpans.push_back(sc::SingleColumnSpanSet::Span(0, MAXROW)); + aMarkedSpans.push_back(sc::RowSpan(0, MAXROW)); sal_uInt16 nWidth = static_cast<sal_uInt16>(nOldWidth*nPPTX); bool bFound = false; diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 850a904e6fa2..7675271eec02 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -198,7 +198,7 @@ public: mrDoc(rDoc), maHint(SC_HINT_DATACHANGED, ScAddress(nCol, 0, nTab)) {} - void operator() (const sc::SingleColumnSpanSet::Span& rSpan) + void operator() (const sc::RowSpan& rSpan) { SCROW nRow1 = rSpan.mnRow1, nRow2 = rSpan.mnRow2; maHint.GetAddress().SetRow(nRow1); @@ -556,7 +556,7 @@ public: EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn) : mrColumn(rColumn), mrPos(rPos) {} - void operator() (const sc::SingleColumnSpanSet::Span& rSpan) + void operator() (const sc::RowSpan& rSpan) { sc::CellStoreType& rCells = mrColumn.GetCellStore(); @@ -651,7 +651,7 @@ bool ScColumn::InitBlockPosition( sc::ColumnBlockConstPosition& rBlockPos ) cons namespace { -class CopyAttrArrayByRange : std::unary_function<sc::SingleColumnSpanSet::Span, void> +class CopyAttrArrayByRange : std::unary_function<sc::RowSpan, void> { ScAttrArray& mrDestAttrArray; ScAttrArray& mrSrcAttrArray; @@ -660,7 +660,7 @@ public: CopyAttrArrayByRange(ScAttrArray& rDestAttrArray, ScAttrArray& rSrcAttrArray, long nRowOffset) : mrDestAttrArray(rDestAttrArray), mrSrcAttrArray(rSrcAttrArray), mnRowOffset(nRowOffset) {} - void operator() (const sc::SingleColumnSpanSet::Span& rSpan) + void operator() (const sc::RowSpan& rSpan) { mrDestAttrArray.CopyAreaSafe( rSpan.mnRow1+mnRowOffset, rSpan.mnRow2+mnRowOffset, mnRowOffset, mrSrcAttrArray); diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx index f8c7813daf03..efa51b5a2707 100644 --- a/sc/source/core/data/columnspanset.cxx +++ b/sc/source/core/data/columnspanset.cxx @@ -20,6 +20,8 @@ namespace sc { +RowSpan::RowSpan(SCROW nRow1, SCROW nRow2) : mnRow1(nRow1), mnRow2(nRow2) {} + ColumnSpanSet::ColumnType::ColumnType(SCROW nStart, SCROW nEnd, bool bInit) : maSpans(nStart, nEnd+1, bInit), miPos(maSpans.begin()) {} @@ -270,7 +272,7 @@ void SingleColumnSpanSet::getSpans(SpansType& rSpans) const bool bThisVal = it->second; if (bLastVal) - aSpans.push_back(Span(nLastRow, nThisRow-1)); + aSpans.push_back(RowSpan(nLastRow, nThisRow-1)); nLastRow = nThisRow; bLastVal = bThisVal; diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index a4232f89168a..556df504ca3a 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -20,6 +20,7 @@ #include "markdata.hxx" #include "markarr.hxx" #include "rangelst.hxx" +#include <columnspanset.hxx> // STATIC DATA ----------------------------------------------------------- @@ -547,6 +548,26 @@ SCCOLROW ScMarkData::GetMarkRowRanges( SCCOLROW* pRanges ) return nRangeCnt; } +void ScMarkData::GetMarkedRowSpans( SCTAB nTab, std::vector<sc::RowSpan>& rSpans ) +{ + std::vector<sc::RowSpan> aSpans; + + if (bMarked) + MarkToMulti(); + + if (!bMultiMarked) + { + rSpans.swap(aSpans); + return; + } + + sc::SingleColumnSpanSet aMarkedRows; + for (SCCOL nCol = aMultiRange.aStart.Col(); nCol <= aMultiRange.aEnd.Col(); ++nCol) + aMarkedRows.scan(*this, nTab, nCol); + + aMarkedRows.getSpans(rSpans); +} + bool ScMarkData::IsAllMarked( const ScRange& rRange ) const { if ( !bMultiMarked ) diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 2ee7075b5c6f..800523e9892c 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -81,6 +81,7 @@ #include "prnsave.hxx" #include "searchresults.hxx" #include "tokenarray.hxx" +#include <columnspanset.hxx> #include <boost/scoped_ptr.hpp> #include <vector> @@ -107,12 +108,12 @@ sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) pMarkData = &GetViewData()->GetMarkData(); ScDocument* pDoc = pDocSh->GetDocument(); - SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT]; - SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges ); - if (nRangeCnt == 0) + std::vector<sc::RowSpan> aMarkedRows; + pMarkData->GetMarkedRowSpans(GetViewData()->GetTabNo(), aMarkedRows); + if (aMarkedRows.empty()) { - pRanges[0] = pRanges[1] = GetViewData()->GetCurY(); - nRangeCnt = 1; + SCROW nCurRow = GetViewData()->GetCurY(); + aMarkedRows.push_back(sc::RowSpan(nCurRow, nCurRow)); } double nPPTX = GetViewData()->GetPPTX(); @@ -133,26 +134,25 @@ sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) for (; itr != itrEnd; ++itr) { SCTAB nTab = *itr; - SCCOLROW* pOneRange = pRanges; - sal_Bool bChanged = false; + bool bChanged = false; SCROW nPaintY = 0; - for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) + std::vector<sc::RowSpan>::const_iterator itRows = aMarkedRows.begin(), itRowsEnd = aMarkedRows.end(); + for (; itRows != itRowsEnd; ++itRows) { - SCROW nStartNo = *(pOneRange++); - SCROW nEndNo = *(pOneRange++); + SCROW nStartNo = itRows->mnRow1; + SCROW nEndNo = itRows->mnRow2; if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(), nPPTX, nPPTY, aZoomX, aZoomY, false )) { if (!bChanged) nPaintY = nStartNo; - bAnyChanged = bChanged = sal_True; + bAnyChanged = bChanged = true; } } if ( bPaint && bChanged ) pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID | PAINT_LEFT ); } - delete[] pRanges; if ( bPaint && bAnyChanged ) pDocSh->UpdateOle(GetViewData()); diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 089024a8d50d..b96752606c46 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -2905,7 +2905,7 @@ void ScViewFunc::UpdateSelectionArea( const ScMarkData& rSel, ScPatternAttr* pAt PAINT_GRID, nExtFlags | SC_PF_TESTMERGE ); ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); pTabViewShell->CellContentChanged(); - pTabViewShell->AdjustBlockHeight(true, const_cast<ScMarkData*>(&rSel)); + pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel)); } |