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

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Wed Jun 26 12:42:12 UTC 2019


 sc/inc/mtvcellfunc.hxx  |    4 +++-
 sc/inc/mtvfunctions.hxx |   36 ++++++++++++++++++++++++++++++++++--
 2 files changed, 37 insertions(+), 3 deletions(-)

New commits:
commit ea19b0c0230fcc730245ecd445c03164cb6a1d18
Author:     Noel Grandin <noel.grandin at collabora.co.uk>
AuthorDate: Wed Jun 26 13:49:20 2019 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Wed Jun 26 14:41:18 2019 +0200

    tdf#113112 insert a new sheet slow
    
    We were spending vast amounts of time in ScColumn::EndListening calling
    set_empty on the mdds_vector, which moved the block data around.
    
    So walk backwards through the data, which means we will delete from the
    end, and largely avoid any expensive moving around.
    
    Change-Id: I78cbecedf137972fb2a1b7042635f4e7b03d77ff
    Reviewed-on: https://gerrit.libreoffice.org/74738
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sc/inc/mtvcellfunc.hxx b/sc/inc/mtvcellfunc.hxx
index 145d1ee38779..562d003a5c50 100644
--- a/sc/inc/mtvcellfunc.hxx
+++ b/sc/inc/mtvcellfunc.hxx
@@ -119,8 +119,10 @@ ParseFormulaNumeric(
 template<typename Func>
 void ProcessFormulaEditText(CellStoreType& rStore, Func& rFunc)
 {
+    // Walk backwards through the data - this helps when the FuncElem will be deleting
+    // stuff, so we don't continually move block data around.
     FuncElseNoOp<size_t> aElse;
-    ProcessElements2<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
+    ProcessElements2Reverse<CellStoreType, edittext_block, formula_block, Func, FuncElseNoOp<size_t> >(rStore, rFunc, aElse);
 }
 
 template<typename Func>
diff --git a/sc/inc/mtvfunctions.hxx b/sc/inc/mtvfunctions.hxx
index f9052edfb27c..5e48bb2942d7 100644
--- a/sc/inc/mtvfunctions.hxx
+++ b/sc/inc/mtvfunctions.hxx
@@ -113,8 +113,18 @@ void EachElem(NodeT& rNode, size_t nOffset, size_t nDataSize, FuncElem& rFuncEle
 template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
 void EachElem(NodeT& rNode, FuncElem& rFuncElem)
 {
-    ItrT it = BlkT::begin(*rNode.data);
-    ItrT itEnd = BlkT::end(*rNode.data);
+    auto it = BlkT::begin(*rNode.data);
+    auto itEnd = BlkT::end(*rNode.data);
+    size_t nRow = rNode.position;
+    for (; it != itEnd; ++it, ++nRow)
+        rFuncElem(nRow, *it);
+}
+
+template<typename BlkT, typename ItrT, typename NodeT, typename FuncElem>
+void EachElemReverse(NodeT& rNode, FuncElem& rFuncElem)
+{
+    auto it = BlkT::rbegin(*rNode.data);
+    auto itEnd = BlkT::rend(*rNode.data);
     size_t nRow = rNode.position;
     for (; it != itEnd; ++it, ++nRow)
         rFuncElem(nRow, *it);
@@ -374,6 +384,28 @@ void ProcessElements2(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
     }
 }
 
+template<typename StoreT, typename Blk1, typename Blk2, typename FuncElem, typename FuncElse>
+void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse)
+{
+    typename StoreT::size_type nTopRow = 0, nDataSize = 0;
+    typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end();
+    for (; it != itEnd; ++it, nTopRow += nDataSize)
+    {
+        nDataSize = it->size;
+        switch (it->type)
+        {
+            case Blk1::block_type:
+                EachElemReverse<Blk1, typename Blk1::iterator>(*it, rFuncElem);
+            break;
+            case Blk2::block_type:
+                EachElemReverse<Blk2, typename Blk2::iterator>(*it, rFuncElem);
+            break;
+            default:
+                rFuncElse(it->type, nTopRow, nDataSize);
+        }
+    }
+}
+
 template<typename StoreT, typename Blk1, typename FuncElem, typename FuncElse>
 std::pair<typename StoreT::const_iterator, typename StoreT::size_type>
 FindElement1(


More information about the Libreoffice-commits mailing list