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

Pierre-Eric Pelloux-Prayer pierre-eric at lanedo.com
Tue Aug 27 07:13:03 PDT 2013


 sc/inc/scmatrix.hxx              |    2 
 sc/source/core/tool/scmatrix.cxx |  126 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 128 insertions(+)

New commits:
commit 7334f8db6f6004d48e2dbf014f27878a7ae21eb1
Author: Pierre-Eric Pelloux-Prayer <pierre-eric at lanedo.com>
Date:   Fri Aug 16 16:29:27 2013 +0200

    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 at suse.de>
    Tested-by: Kohei Yoshida <kohei.yoshida at suse.de>

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 4057cc4..2ef596b 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 73ed2e2..3bf042b 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);


More information about the Libreoffice-commits mailing list