[Libreoffice-commits] core.git: sc/inc sc/source
Noel Grandin (via logerrit)
logerrit at kemper.freedesktop.org
Mon May 25 13:56:26 UTC 2020
sc/inc/compressedarray.hxx | 20 ++++++++++++++++++
sc/inc/rowheightcontext.hxx | 9 +++++---
sc/source/core/data/column2.cxx | 33 +++++++++++++++++++++----------
sc/source/core/data/compressedarray.cxx | 1
sc/source/core/data/rowheightcontext.cxx | 5 ----
sc/source/core/data/table1.cxx | 32 ++++++++++++++----------------
6 files changed, 65 insertions(+), 35 deletions(-)
New commits:
commit 68547fa26897a8076eeda13cdcf20fb6078af6a4
Author: Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Fri May 22 15:58:12 2020 +0200
Commit: Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon May 25 15:55:15 2020 +0200
tdf#88109 speed up calc autofill
switch from ScFlatUInt16RowSegments to ScCompressedArray
The problem with the underlying mdds::flat_segment_tree data structure
is that it is optimised for bulk-load and then frequent read.
But here we are interleaving reading and updating the data, which means
flat_segment_tree spends a lot of time in its build_tree code.
Change-Id: Ic0d46834a2449e4fa9f84343971417adb48ba2de
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94694
Tested-by: Noel Grandin <noel.grandin at collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>
diff --git a/sc/inc/compressedarray.hxx b/sc/inc/compressedarray.hxx
index 593aeb6e868d..91540d8391db 100644
--- a/sc/inc/compressedarray.hxx
+++ b/sc/inc/compressedarray.hxx
@@ -65,6 +65,11 @@ public:
D aValue;
DataEntry() {} //! uninitialized
};
+ struct RangeData
+ {
+ A mnRow1, mnRow2;
+ D maValue;
+ };
/** Construct with nMaxAccess=MAXROW, for example. */
ScCompressedArray( A nMaxAccess,
@@ -82,6 +87,10 @@ public:
[[nodiscard]]
const D& GetValue( A nPos, size_t& nIndex, A& nEnd ) const;
+ /** Get range data for a row, i.e. value and start and end rows with that value */
+ [[nodiscard]]
+ RangeData GetRangeData( A nPos ) const;
+
/** Get next value and it's region end row. If nIndex<nCount, nIndex is
incremented first. If the resulting nIndex>=nCount, the value of the
last entry is returned again. */
@@ -149,6 +158,17 @@ const D& ScCompressedArray<A,D>::GetValue( A nPos, size_t& nIndex, A& nEnd ) con
return pData[nIndex].aValue;
}
+template< typename A, typename D >
+typename ScCompressedArray<A,D>::RangeData ScCompressedArray<A,D>::GetRangeData( A nPos ) const
+{
+ size_t nIndex = Search( nPos);
+ RangeData aData;
+ aData.mnRow1 = nIndex == 0 ? 0 : pData[nIndex - 1].nEnd + 1;
+ aData.mnRow2 = pData[nIndex].nEnd;
+ aData.maValue = pData[nIndex].aValue;
+ return aData;
+}
+
template< typename A, typename D >
const D& ScCompressedArray<A,D>::GetNextValue( size_t& nIndex, A& nEnd ) const
{
diff --git a/sc/inc/rowheightcontext.hxx b/sc/inc/rowheightcontext.hxx
index 06da424c444c..054360396306 100644
--- a/sc/inc/rowheightcontext.hxx
+++ b/sc/inc/rowheightcontext.hxx
@@ -16,13 +16,16 @@
#include <vcl/vclptr.hxx>
#include <vcl/outdev.hxx>
-#include "segmenttree.hxx"
+#include "compressedarray.hxx"
+#include "types.hxx"
+
+using RowHeightsArray = ScCompressedArray<SCROW, sal_uInt16>;
namespace sc {
class SC_DLLPUBLIC RowHeightContext
{
- ScFlatUInt16RowSegments maHeights;
+ RowHeightsArray maHeights;
double mfPPTX;
double mfPPTY;
@@ -53,7 +56,7 @@ public:
void setForceAutoSize( bool b );
bool isForceAutoSize() const { return mbForceAutoSize;}
- ScFlatUInt16RowSegments& getHeightArray();
+ RowHeightsArray& getHeightArray() { return maHeights; }
};
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 6d19daf40fa5..61a756699081 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -783,7 +783,7 @@ void ScColumn::GetOptimalHeight(
sc::RowHeightContext& rCxt, SCROW nStartRow, SCROW nEndRow, sal_uInt16 nMinHeight, SCROW nMinStart )
{
ScDocument* pDocument = GetDoc();
- ScFlatUInt16RowSegments& rHeights = rCxt.getHeightArray();
+ RowHeightsArray& rHeights = rCxt.getHeightArray();
ScAttrIterator aIter( pAttrArray.get(), nStartRow, nEndRow, pDocument->GetDefPattern() );
SCROW nStart = -1;
@@ -883,7 +883,20 @@ void ScColumn::GetOptimalHeight(
nStdEnd = (nMinStart>0) ? nMinStart-1 : 0;
if (nStart <= nStdEnd)
- rHeights.setValueIf(nStart, nStdEnd, nDefHeight, [=](sal_uInt16 nRowHeight){ return nDefHeight > nRowHeight; });
+ {
+ SCROW nRow = nStart;
+ for (;;)
+ {
+ size_t nIndex;
+ SCROW nRangeEnd;
+ sal_uInt16 nRangeHeight = rHeights.GetValue(nRow, nIndex, nRangeEnd);
+ if (nRangeHeight < nDefHeight)
+ rHeights.SetValue(nRow, std::min(nRangeEnd, nStdEnd), nDefHeight);
+ nRow = nRangeEnd + 1;
+ if (nRow > nStdEnd)
+ break;
+ }
+ }
if ( bStdOnly )
{
@@ -903,22 +916,22 @@ void ScColumn::GetOptimalHeight(
{
if ( nCjkHeight == 0 )
nCjkHeight = lcl_GetAttribHeight( *pPattern, ATTR_CJK_FONT_HEIGHT );
- if (nCjkHeight > rHeights.getValue(nRow))
- rHeights.setValue(nRow, nRow, nCjkHeight);
+ if (nCjkHeight > rHeights.GetValue(nRow))
+ rHeights.SetValue(nRow, nRow, nCjkHeight);
}
else if ( nScript == SvtScriptType::COMPLEX )
{
if ( nCtlHeight == 0 )
nCtlHeight = lcl_GetAttribHeight( *pPattern, ATTR_CTL_FONT_HEIGHT );
- if (nCtlHeight > rHeights.getValue(nRow))
- rHeights.setValue(nRow, nRow, nCtlHeight);
+ if (nCtlHeight > rHeights.GetValue(nRow))
+ rHeights.SetValue(nRow, nRow, nCtlHeight);
}
else
{
if ( nLatHeight == 0 )
nLatHeight = lcl_GetAttribHeight( *pPattern, ATTR_FONT_HEIGHT );
- if (nLatHeight > rHeights.getValue(nRow))
- rHeights.setValue(nRow, nRow, nLatHeight);
+ if (nLatHeight > rHeights.GetValue(nRow))
+ rHeights.SetValue(nRow, nRow, nLatHeight);
}
}
}
@@ -945,8 +958,8 @@ void ScColumn::GetOptimalHeight(
rCxt.getZoomX(), rCxt.getZoomY(), false, aOptions,
&pPattern) / rCxt.getPPTY(),
double(std::numeric_limits<sal_uInt16>::max())));
- if (nHeight > rHeights.getValue(nRow))
- rHeights.setValue(nRow, nRow, nHeight);
+ if (nHeight > rHeights.GetValue(nRow))
+ rHeights.SetValue(nRow, nRow, nHeight);
// Pattern changed due to calculation? => sync.
if (pPattern != pOldPattern)
{
diff --git a/sc/source/core/data/compressedarray.cxx b/sc/source/core/data/compressedarray.cxx
index 2016478d9194..914a6c52eb1f 100644
--- a/sc/source/core/data/compressedarray.cxx
+++ b/sc/source/core/data/compressedarray.cxx
@@ -417,6 +417,7 @@ template class ScCompressedArray< SCROW, CRFlags>; // flags, base cl
template class ScBitMaskCompressedArray< SCROW, CRFlags>; // flags
template class ScCompressedArray< SCCOL, sal_uInt16>;
template class ScCompressedArray< SCCOL, CRFlags>;
+template class ScCompressedArray< SCROW, sal_uInt16>;
template class ScBitMaskCompressedArray< SCCOL, CRFlags>;
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/rowheightcontext.cxx b/sc/source/core/data/rowheightcontext.cxx
index 86d2ab1da082..c5f615c666c2 100644
--- a/sc/source/core/data/rowheightcontext.cxx
+++ b/sc/source/core/data/rowheightcontext.cxx
@@ -33,11 +33,6 @@ void RowHeightContext::setForceAutoSize( bool b )
mbForceAutoSize = b;
}
-ScFlatUInt16RowSegments& RowHeightContext::getHeightArray()
-{
- return maHeights;
-}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index c40ce2467724..022a57f2503f 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -94,16 +94,15 @@ void GetOptimalHeightsInColumn(
// from there search for the standard height that is in use in the lower part
- ScFlatUInt16RowSegments& rHeights = rCxt.getHeightArray();
- sal_uInt16 nMinHeight = rHeights.getValue(nEndRow);
- SCSIZE nPos = nEndRow-1;
- ScFlatUInt16RowSegments::RangeData aRangeData;
- while ( nPos && rHeights.getRangeData(nPos-1, aRangeData) )
- {
- if (aRangeData.mnValue >= nMinHeight)
- nPos = std::max<SCSIZE>(0, aRangeData.mnRow1);
- else
+ RowHeightsArray& rHeights = rCxt.getHeightArray();
+ sal_uInt16 nMinHeight = rHeights.GetValue(nEndRow);
+ SCSIZE nPos = nEndRow - 1;
+ while ( nPos )
+ {
+ auto aRangeData = rHeights.GetRangeData(nPos-1);
+ if (aRangeData.maValue < nMinHeight)
break;
+ nPos = std::max<SCSIZE>(0, aRangeData.mnRow1);
}
const SCROW nMinStart = nPos;
@@ -192,12 +191,13 @@ bool SetOptimalHeightsToRows(
{
if (nLast)
{
- ScFlatUInt16RowSegments::RangeData aRangeData;
- (void)rCxt.getHeightArray().getRangeData(nInner, aRangeData);
- if (aRangeData.mnValue + nExtraHeight == nLast)
+ SCROW nRangeRowEnd;
+ size_t nTmp;
+ sal_uInt16 nRangeValue = rCxt.getHeightArray().GetValue(nInner, nTmp, nRangeRowEnd);
+ if (nRangeValue + nExtraHeight == nLast)
{
- nRngEnd = std::min<SCSIZE>(i + nMoreRows, aRangeData.mnRow2);
- nInner = aRangeData.mnRow2;
+ nRngEnd = std::min<SCSIZE>(i + nMoreRows, nRangeRowEnd);
+ nInner = nRangeRowEnd;
}
else
{
@@ -207,7 +207,7 @@ bool SetOptimalHeightsToRows(
}
if (!nLast)
{
- nLast = rCxt.getHeightArray().getValue(nInner) + rCxt.getExtraHeight();
+ nLast = rCxt.getHeightArray().GetValue(nInner) + rCxt.getExtraHeight();
nRngStart = nInner;
nRngEnd = nInner;
}
@@ -466,7 +466,6 @@ bool ScTable::SetOptimalHeight(
GetOptimalHeightsInColumn(rCxt, aCol, nStartRow, nEndRow, pProgress, nProgressStart);
- rCxt.getHeightArray().enableTreeSearch(true);
SetRowHeightRangeFunc aFunc(this, rCxt.getPPTY());
bool bChanged = SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags.get(), nStartRow, nEndRow);
@@ -494,7 +493,6 @@ void ScTable::SetOptimalHeightOnly(
SetRowHeightOnlyFunc aFunc(this);
- rCxt.getHeightArray().enableTreeSearch(true);
SetOptimalHeightsToRows(rCxt, aFunc, pRowFlags.get(), nStartRow, nEndRow);
if ( pProgress != pOuterProgress )
More information about the Libreoffice-commits
mailing list