diff options
author | Pierre-Eric Pelloux-Prayer <pierre-eric@lanedo.com> | 2013-08-16 16:29:27 +0200 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.de> | 2013-08-27 14:12:38 +0000 |
commit | 7334f8db6f6004d48e2dbf014f27878a7ae21eb1 (patch) | |
tree | 3d7a773e5d48ac07063c4572f215ebfdb580f99a /sc | |
parent | e5321437322fd812b93fee266af309e782479488 (diff) |
matrix: add functions to lookup a double or string in columns
Allows efficient lookup, instead of doing per cell fetch + match.
Change-Id: I3cd0d26a8fc91ed38fd339229fc0e948fb849f5e
Reviewed-on: https://gerrit.libreoffice.org/5454
Reviewed-by: Kohei Yoshida <kohei.yoshida@suse.de>
Tested-by: Kohei Yoshida <kohei.yoshida@suse.de>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/scmatrix.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 126 |
2 files changed, 128 insertions, 0 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 4057cc4a84dd..2ef596b1eda3 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -334,6 +334,8 @@ public: IterateResult SumSquare(bool bTextAsZero) const; IterateResult Product(bool bTextAsZero) const; size_t Count(bool bCountStrings) const; + size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; + size_t MatchStringInColumns(const OUString& rStr, size_t nCol1, size_t nCol2) const; double GetMaxValue( bool bTextAsZero ) const; double GetMinValue( bool bTextAsZero ) const; diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 73ed2e2c45a1..3bf042b733ca 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -222,6 +222,8 @@ public: ScMatrix::IterateResult SumSquare(bool bTextAsZero) const; ScMatrix::IterateResult Product(bool bTextAsZero) const; size_t Count(bool bCountStrings) const; + size_t MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const; + size_t MatchStringInColumns(const OUString& rStr, size_t nCol1, size_t nCol2) const; double GetMaxValue( bool bTextAsZero ) const; double GetMinValue( bool bTextAsZero ) const; @@ -940,6 +942,108 @@ public: } }; + +template<typename vType> +class WalkAndMatchElements : std::unary_function<MatrixImplType::element_block_node_type, void> +{ + vType maMatchValue; + MatrixImplType::size_pair_type maSize; + size_t mnCol1, mnCol2; + size_t mnResult, mnIndex; + +public: + WalkAndMatchElements(vType aMatchValue, const MatrixImplType::size_pair_type& aSize, size_t nCol1, size_t nCol2) + : maMatchValue(aMatchValue), maSize(aSize), mnCol1(nCol1), mnCol2(nCol2), mnResult(size_t_MAX), mnIndex(0) {} + + size_t getMatching() const { return mnResult; } + + size_t compare(const MatrixImplType::element_block_node_type& node) const; + + void operator() (const MatrixImplType::element_block_node_type& node) + { + // early exit if match aleady found + if (mnResult != SCSIZE_MAX) + return; + + // limit lookup to the requested columns + if (mnIndex >= ( mnCol1 * maSize.row ) && + mnIndex <= ( ( mnCol2 + 1 ) * maSize.row ) ) + { + mnResult = compare(node); + } + + mnIndex += node.size; + } +}; + +template<> +size_t WalkAndMatchElements<double>::compare(const MatrixImplType::element_block_node_type& node) const { + size_t nCount = 0; + switch (node.type) + { + case mdds::mtm::element_numeric: + { + mdds::mtv::numeric_element_block::const_iterator it = mdds::mtv::numeric_element_block::begin(*node.data); + mdds::mtv::numeric_element_block::const_iterator itEnd = mdds::mtv::numeric_element_block::end(*node.data); + for (; it != itEnd; ++it, nCount++) + { + if (*it == maMatchValue) + { + return mnIndex + nCount; + } + } + break; + } + case mdds::mtm::element_boolean: + { + mdds::mtv::boolean_element_block::const_iterator it = mdds::mtv::boolean_element_block::begin(*node.data); + mdds::mtv::boolean_element_block::const_iterator itEnd = mdds::mtv::boolean_element_block::end(*node.data); + for (; it != itEnd; ++it, nCount++) + { + if (*it == maMatchValue) + { + return mnIndex + nCount; + } + } + break; + } + break; + case mdds::mtm::element_string: + case mdds::mtm::element_empty: + default: + ; + } + return SCSIZE_MAX; +} + +template<> +size_t WalkAndMatchElements<OUString>::compare(const MatrixImplType::element_block_node_type& node) const { + size_t nCount = 0; + switch (node.type) + { + case mdds::mtm::element_string: + { + MatrixImplType::string_block_type::const_iterator it = MatrixImplType::string_block_type::begin(*node.data); + MatrixImplType::string_block_type::const_iterator itEnd = MatrixImplType::string_block_type::end(*node.data); + for (; it != itEnd; ++it, ++nCount) + { + if (ScGlobal::GetpTransliteration()->isEqual(*it, maMatchValue)) + { + return mnIndex + nCount; + } + } + break; + } + case mdds::mtm::element_boolean: + case mdds::mtm::element_numeric: + case mdds::mtm::element_empty: + default: + ; + } + return SCSIZE_MAX; +} + + struct MaxOp { static double init() { return -std::numeric_limits<double>::max(); } @@ -1174,6 +1278,20 @@ size_t ScMatrixImpl::Count(bool bCountStrings) const return aFunc.getCount(); } +size_t ScMatrixImpl::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const +{ + WalkAndMatchElements<double> aFunc(fValue, maMat.size(), nCol1, nCol2); + maMat.walk(aFunc); + return aFunc.getMatching(); +} + +size_t ScMatrixImpl::MatchStringInColumns(const OUString& rStr, size_t nCol1, size_t nCol2) const +{ + WalkAndMatchElements<OUString> aFunc(rStr, maMat.size(), nCol1, nCol2); + maMat.walk(aFunc); + return aFunc.getMatching(); +} + double ScMatrixImpl::GetMaxValue( bool bTextAsZero ) const { CalcMaxMinValue<MaxOp> aFunc(bTextAsZero); @@ -1570,6 +1688,14 @@ size_t ScMatrix::Count(bool bCountStrings) const return pImpl->Count(bCountStrings); } +size_t ScMatrix::MatchDoubleInColumns(double fValue, size_t nCol1, size_t nCol2) const { + return pImpl->MatchDoubleInColumns(fValue, nCol1, nCol2); +} + +size_t ScMatrix::MatchStringInColumns(const OUString& rStr, size_t nCol1, size_t nCol2) const { + return pImpl->MatchStringInColumns(rStr, nCol1, nCol2); +} + double ScMatrix::GetMaxValue( bool bTextAsZero ) const { return pImpl->GetMaxValue(bTextAsZero); |