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

Markus Mohrhard markus.mohrhard at collabora.co.uk
Tue Feb 16 09:09:26 UTC 2016


 sc/inc/scmatrix.hxx                      |   12 ++
 sc/source/core/tool/scmatrix.cxx         |  130 +++++++++++++++++++++++++++++++
 sc/source/ui/docshell/externalrefmgr.cxx |   42 +++-------
 3 files changed, 156 insertions(+), 28 deletions(-)

New commits:
commit f18cb2c196cc5b643b9832dfca1d940b82c832b0
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Tue Feb 16 07:07:53 2016 +0100

    single element access is really slow in mdds, tdf#67071
    
    Change-Id: I5491ba0bc44a9ce8844b31126835671c5d5abcaa
    Reviewed-on: https://gerrit.libreoffice.org/22386
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 9287f55..84eda9e 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -123,6 +123,10 @@ protected:
 public:
     enum Op { Add, Sub, Mul, Div };
 
+    typedef std::function<void(size_t, size_t, double)> DoubleOpFunction;
+    typedef std::function<void(size_t, size_t, bool)> BoolOpFunction;
+    typedef std::function<void(size_t, size_t, svl::SharedString)> StringOpFunction;
+
     /**
      * When adding all numerical matrix elements for a scalar result such as
      * summation, the interpreter wants to separate the first non-zero value
@@ -393,6 +397,9 @@ public:
 
     virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) = 0;
 
+    virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
+            DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const = 0;
+
 #if DEBUG_MATRIX
     void Dump() const;
 #endif
@@ -598,6 +605,8 @@ public:
 
     virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override;
 
+    virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
+            DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const;
     ScFullMatrix& operator+= ( const ScFullMatrix& r );
 
 #if DEBUG_MATRIX
@@ -806,6 +815,9 @@ public:
 
     virtual std::vector<ScMatrix::IterateResult> Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp) override;
 
+    virtual void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos, const std::pair<size_t, size_t>& rEndPos,
+            DoubleOpFunction aDoubleFunc, BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const;
+
     ScVectorRefMatrix& operator+=(const ScVectorRefMatrix& r);
 };
 
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 33879bc..6019cc2 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -300,6 +300,10 @@ public:
     template<typename T>
     void ApplyOperation(T aOp, ScMatrixImpl& rMat);
 
+    void ExecuteOperation(const std::pair<size_t, size_t>& rStartPos,
+            const std::pair<size_t, size_t>& rEndPos, ScFullMatrix::DoubleOpFunction aDoubleFunc,
+            ScFullMatrix::BoolOpFunction aBoolFunc, ScFullMatrix::StringOpFunction aStringFunc) const;
+
     template<typename T>
     std::vector<ScMatrix::IterateResult> ApplyCollectOperation(bool bTextAsZero, const std::vector<std::unique_ptr<T>>& aOp);
 
@@ -2169,6 +2173,117 @@ std::vector<ScMatrix::IterateResult> ScMatrixImpl::ApplyCollectOperation(bool bT
     return aFunc.getResult();
 }
 
+namespace {
+
+class WalkElementBlockOperation
+{
+public:
+
+    WalkElementBlockOperation(size_t nRowSize, size_t /*nColSize*/,
+            ScFullMatrix::DoubleOpFunction aDoubleFunc,
+            ScFullMatrix::BoolOpFunction aBoolFunc,
+            ScFullMatrix::StringOpFunction aStringFunc):
+        mnRowSize(nRowSize),
+        mnRowPos(0),
+        mnColPos(0),
+        maDoubleFunc(aDoubleFunc),
+        maBoolFunc(aBoolFunc),
+        maStringFunc(aStringFunc)
+    {
+    }
+
+    void operator()(const MatrixImplType::element_block_node_type& node)
+    {
+        switch (node.type)
+        {
+            case mdds::mtm::element_numeric:
+            {
+                typedef MatrixImplType::numeric_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                std::advance(it, node.offset);
+                block_type::const_iterator itEnd = it;
+                std::advance(itEnd, node.size);
+                for (auto itr = it; itr != itEnd; ++itr)
+                {
+                    maDoubleFunc(mnRowPos, mnColPos, *itr);
+                    ++mnRowPos;
+                    if (mnRowPos >= mnRowSize)
+                    {
+                        mnRowPos = 0;
+                        ++mnColPos;
+                    }
+                }
+            }
+            break;
+            case mdds::mtm::element_string:
+            {
+                typedef MatrixImplType::string_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                std::advance(it, node.offset);
+                block_type::const_iterator itEnd = it;
+                std::advance(itEnd, node.size);
+                for (auto itr = it; itr != itEnd; ++itr)
+                {
+                    maStringFunc(mnRowPos, mnColPos, *itr);
+                    ++mnRowPos;
+                    if (mnRowPos >= mnRowSize)
+                    {
+                        mnRowPos = 0;
+                        ++mnColPos;
+                    }
+                }
+            }
+            break;
+            case mdds::mtm::element_boolean:
+            {
+                typedef MatrixImplType::boolean_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                std::advance(it, node.offset);
+                block_type::const_iterator itEnd = it;
+                std::advance(itEnd, node.size);
+                for (auto itr = it; itr != itEnd; ++itr)
+                {
+                    maBoolFunc(mnRowPos, mnColPos, *itr);
+                    ++mnRowPos;
+                    if (mnRowPos >= mnRowSize)
+                    {
+                        mnRowPos = 0;
+                        ++mnColPos;
+                    }
+                }
+            }
+            break;
+            case mdds::mtm::element_empty:
+            break;
+        }
+    }
+
+private:
+
+    size_t mnRowSize;
+    size_t mnRowPos;
+    size_t mnColPos;
+
+    ScFullMatrix::DoubleOpFunction maDoubleFunc;
+    ScFullMatrix::BoolOpFunction maBoolFunc;
+    ScFullMatrix::StringOpFunction maStringFunc;
+};
+
+}
+
+void ScMatrixImpl::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos,
+        const std::pair<size_t, size_t>& rEndPos, ScMatrix::DoubleOpFunction aDoubleFunc,
+        ScMatrix::BoolOpFunction aBoolFunc, ScMatrix::StringOpFunction aStringFunc) const
+{
+    WalkElementBlockOperation aFunc(maMat.size().row, maMat.size().column,
+            aDoubleFunc, aBoolFunc, aStringFunc);
+    maMat.walk(aFunc, MatrixImplType::size_pair_type(rStartPos.first, rStartPos.second),
+            MatrixImplType::size_pair_type(rEndPos.first, rEndPos.second));
+}
+
 #if DEBUG_MATRIX
 
 void ScMatrixImpl::Dump() const
@@ -2817,6 +2932,13 @@ void ScFullMatrix::PowOp( bool bFlag, double fVal, ScMatrix& rMat)
     }
 }
 
+void ScFullMatrix::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos,
+        const std::pair<size_t, size_t>& rEndPos, DoubleOpFunction aDoubleFunc,
+        BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const
+{
+    pImpl->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc);
+}
+
 std::vector<ScMatrix::IterateResult> ScFullMatrix::Collect(bool bTextAsZero, const std::vector<std::unique_ptr<sc::op::Op>>& aOp)
 {
     return pImpl->ApplyCollectOperation(bTextAsZero, aOp);
@@ -3555,4 +3677,12 @@ std::vector<ScMatrix::IterateResult> ScVectorRefMatrix::Collect(bool bTextAsZero
     return mpFullMatrix->Collect(bTextAsZero, aOp);
 }
 
+void ScVectorRefMatrix::ExecuteOperation(const std::pair<size_t, size_t>& rStartPos,
+        const std::pair<size_t, size_t>& rEndPos, DoubleOpFunction aDoubleFunc,
+        BoolOpFunction aBoolFunc, StringOpFunction aStringFunc) const
+{
+    const_cast<ScVectorRefMatrix*>(this)->ensureFullMatrix();
+    mpFullMatrix->ExecuteOperation(rStartPos, rEndPos, aDoubleFunc, aBoolFunc, aStringFunc);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 699ac27..7bbf7b7 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -791,35 +791,21 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa
             pTabData.reset(new Table);
 
         const ScMatrixRef& pMat = itrData->mpRangeData;
-        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        ScFullMatrix::DoubleOpFunction aDoubleFunc = [=](size_t row, size_t col, double val) -> void
         {
-            const SCSIZE nR = nRow - nRow1;
-            for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
-            {
-                const SCSIZE nC = nCol - nCol1;
-
-                ScMatrixValue value = pMat->Get(nC, nR);
-
-                TokenRef pToken;
-
-                switch (value.nType) {
-                    case SC_MATVAL_VALUE:
-                    case SC_MATVAL_BOOLEAN:
-                        pToken.reset(new formula::FormulaDoubleToken(value.fVal));
-                        break;
-                    case SC_MATVAL_STRING:
-                        pToken.reset(new formula::FormulaStringToken(value.aStr));
-                        break;
-                    default:
-                        // Don't cache empty cells.
-                        break;
-                }
-
-                if (pToken)
-                    // Don't mark this cell 'cached' here, for better performance.
-                    pTabData->setCell(nCol, nRow, pToken, 0, false);
-            }
-        }
+            pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaDoubleToken(val), 0, false);
+        };
+        ScFullMatrix::BoolOpFunction aBoolFunc = [=](size_t row, size_t col, bool val) -> void
+        {
+            pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaDoubleToken(val), 0, false);
+        };
+        ScFullMatrix::StringOpFunction aStringFunc = [=](size_t row, size_t col, svl::SharedString val) -> void
+        {
+            pTabData->setCell(col + nCol1, row + nRow1, new formula::FormulaStringToken(val), 0, false);
+        };
+        pMat->ExecuteOperation(std::pair<size_t, size_t>(0, 0),
+                std::pair<size_t, size_t>(nRow2-nRow1, nCol2-nCol1),
+                aDoubleFunc, aBoolFunc, aStringFunc);
         // Mark the whole range 'cached'.
         pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2);
     }


More information about the Libreoffice-commits mailing list