[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