[Libreoffice-commits] core.git: sc/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 13 14:01:06 UTC 2021


 sc/source/core/data/segmenttree.cxx |   25 ++++++++++++++++++-------
 sc/source/core/data/table2.cxx      |    9 +++++----
 2 files changed, 23 insertions(+), 11 deletions(-)

New commits:
commit 64152322b99556b2e80a58cdf04a586e6941ba10
Author:     Noel Grandin <noel at peralex.com>
AuthorDate: Tue Apr 13 14:03:53 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Tue Apr 13 16:00:28 2021 +0200

    tdf#130326 speed up row height calculated
    
    for scaled rows. Teach the ForwardIterator to use the slightly
    faster normal search, and make getRangeData cache the resulting
    iterator even when doing a tree search. The combination of
    tree search for the first item, and then using a cached iterator
    to step through the row data is fairly fast.
    
    Take my load time from 23s to 22.3s
    
    Change-Id: Icd1aa3d3a8022a073b125dfc05a670b75da1837e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114045
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx
index 3233a074ac06..77d1e329a839 100644
--- a/sc/source/core/data/segmenttree.cxx
+++ b/sc/source/core/data/segmenttree.cxx
@@ -247,10 +247,10 @@ bool ScFlatSegmentsImpl<ValueType_, ExtValueType_>::getRangeData(SCCOLROW nPos,
         maSegments.build_tree();
     }
 
-    auto it = maSegments.search_tree(nPos, rData.mnValue, &rData.mnPos1, &rData.mnPos2);
-    if (!it.second)
+    auto [it,found] = maSegments.search_tree(nPos, rData.mnValue, &rData.mnPos1, &rData.mnPos2);
+    if (!found)
         return false;
-
+    maItr = it; // cache the iterator to speed up ForwardIterator.
     rData.mnPos2 = rData.mnPos2-1; // end point is not inclusive.
     return true;
 }
@@ -597,12 +597,23 @@ bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16&
     if (mnCurPos > mnLastPos)
     {
         // position not in the current segment.  Update the current value.
-        ScFlatUInt16RowSegments::RangeData aData;
-        if (!mrSegs.getRangeData(mnCurPos, aData))
-            return false;
+        ScFlatUInt16SegmentsImpl::RangeData aData;
+        if (mnLastPos == -1)
+        {
+            // first time in this method, use the tree search based method
+            if (!mrSegs.mpImpl->getRangeData(mnCurPos, aData))
+                return false;
+        }
+        else
+        {
+            // but on subsequent calls, use the leaf method, which is faster
+            // because we have a cached iterator.
+            if (!mrSegs.mpImpl->getRangeDataLeaf(mnCurPos, aData))
+                return false;
+        }
 
         mnCurValue = aData.mnValue;
-        mnLastPos = aData.mnRow2;
+        mnLastPos = aData.mnPos2;
     }
 
     rVal = mnCurValue;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a94d07bf5032..a86c95da082d 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -3307,16 +3307,17 @@ sal_uLong ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fS
                     nLastRow = nEndRow;
 
                 // #i117315# can't use getSumValue, because individual values must be rounded
+                ScFlatUInt16RowSegments::ForwardIterator aSegmentIter(*mpRowHeights);
                 while (nRow <= nLastRow)
                 {
-                    ScFlatUInt16RowSegments::RangeData aData;
-                    if (!mpRowHeights->getRangeData(nRow, aData))
+                    sal_uInt16 nRowVal;
+                    if (!aSegmentIter.getValue(nRow, nRowVal))
                         return nHeight;   // shouldn't happen
 
-                    SCROW nSegmentEnd = std::min( nLastRow, aData.mnRow2 );
+                    SCROW nSegmentEnd = std::min( nLastRow, aSegmentIter.getLastPos() );
 
                     // round-down a single height value, multiply resulting (pixel) values
-                    const sal_uLong nOneHeight = static_cast<sal_uLong>( aData.mnValue * fScale );
+                    const sal_uLong nOneHeight = static_cast<sal_uLong>( nRowVal * fScale );
                     // sometimes scaling results in zero height
                     if (nOneHeight)
                     {


More information about the Libreoffice-commits mailing list