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

Kohei Yoshida kohei.yoshida at collabora.com
Sun Oct 20 10:44:21 PDT 2013


 sc/inc/compare.hxx               |   38 +++--
 sc/source/core/tool/compare.cxx  |  268 ++++++++++++++++++++++++++++++++-------
 sc/source/core/tool/interpr1.cxx |   79 ++++++-----
 sc/source/core/tool/scmatrix.cxx |  193 ++++++++++++++++++++++------
 4 files changed, 445 insertions(+), 133 deletions(-)

New commits:
commit 2d41f3acc359643a88bd39ef8c8d7bac106765fa
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Oct 20 13:41:58 2013 -0400

    Reduce branching on empty matrix elements as well.
    
    This makes a big difference in performance.
    
    Change-Id: I88b48d10ff575d80c1c139278dc207d921f15848

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index 5f9e158..485f882 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -70,6 +70,11 @@ double CompareFunc( double fCell1, const Compare::Cell& rCell2, CompareOptions*
 double CompareFunc( const Compare::Cell& rCell1, double fCell2, CompareOptions* pOptions = NULL );
 double CompareFunc( double fCell1, double fCell2 );
 
+/**
+ * Left cell is empty while the right cell is numeric.
+ */
+double CompareEmptyToNumericFunc( double fCell2 );
+
 }
 
 #endif
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index a876fb1..36e18bc 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -357,6 +357,26 @@ double CompareFunc( double fCell1, double fCell2 )
     return fRes;
 }
 
+double CompareEmptyToNumericFunc( double fCell2 )
+{
+    // Keep DoubleError if encountered
+    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+    if (!rtl::math::isFinite(fCell2))
+        return fCell2;
+
+    double fRes = 0;
+    if (fCell2 != 0.0)
+    {
+        if (fCell2 < 0.0)
+            fRes = 1;       // empty cell > -x
+        else
+            fRes = -1;      // empty cell < x
+    }
+    // else: empty cell == 0.0
+
+    return fRes;
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index a195a4f..1a5ebbb 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1359,6 +1359,13 @@ class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_b
         maResValues.push_back(evaluate(fVal, mrComp.meOp));
     }
 
+    void compareLeftEmpty( size_t nSize )
+    {
+        double fVal = sc::CompareEmptyToNumericFunc(mfRightValue);
+        bool bRes = evaluate(fVal, mrComp.meOp);
+        maResValues.resize(maResValues.size() + nSize, bRes);
+    }
+
 public:
     CompareMatrixToNumericFunc( size_t nResSize, sc::Compare& rComp, double fRightValue, sc::CompareOptions* pOptions ) :
         mrComp(rComp), mfRightValue(fRightValue), mpOptions(pOptions)
@@ -1409,13 +1416,8 @@ public:
             }
             break;
             case mdds::mtm::element_empty:
-            {
-                rCell.mbValue = false;
-                rCell.mbEmpty = true;
-                rCell.maStr = svl::SharedString::getEmptyString();
-                for (size_t i = 0; i < node.size; ++i)
-                    compare();
-            }
+                compareLeftEmpty(node.size);
+            break;
             default:
                 ;
         }
@@ -1627,7 +1629,9 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
     {
         if (rComp.maCells[1].mbValue && !rComp.maCells[1].mbEmpty)
         {
-            // Matrix on the left, and a numeric value on the right.
+            // Matrix on the left, and a numeric value on the right.  Use a
+            // function object that has much less branching for much better
+            // performance.
             CompareMatrixToNumericFunc aFunc(nSize, rComp, rComp.maCells[1].mfValue, pOptions);
             maMat.walk(aFunc);
 
commit 426708e70807e052aca2ec16314c103b1d2a0439
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Oct 20 13:14:55 2013 -0400

    Reduce branching in CompareMatrix(). This makes a big difference.
    
    Change-Id: I391e889a50864ae002e85d636b767d7c6f187a23

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index f428d90..5f9e158 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -66,6 +66,9 @@ private:
         NULL means case sensitivity document option is to be used!
  */
 double CompareFunc( const Compare::Cell& rCell1, const Compare::Cell& rCell2, bool bIgnoreCase, CompareOptions* pOptions = NULL );
+double CompareFunc( double fCell1, const Compare::Cell& rCell2, CompareOptions* pOptions = NULL );
+double CompareFunc( const Compare::Cell& rCell1, double fCell2, CompareOptions* pOptions = NULL );
+double CompareFunc( double fCell1, double fCell2 );
 
 }
 
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index d935d51..a876fb1 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -208,6 +208,155 @@ double CompareFunc( const Compare::Cell& rCell1, const Compare::Cell& rCell2, bo
     return fRes;
 }
 
+double CompareFunc( double fCell1, const Compare::Cell& rCell2, CompareOptions* pOptions )
+{
+    // Keep DoubleError if encountered
+    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+    if (!rtl::math::isFinite(fCell1))
+        return fCell1;
+    if (!rCell2.mbEmpty && rCell2.mbValue && !rtl::math::isFinite(rCell2.mfValue))
+        return rCell2.mfValue;
+
+    bool bStringQuery = false;
+    double fRes = 0;
+    if (rCell2.mbEmpty)
+    {
+        if (fCell1 != 0.0)
+        {
+            if (fCell1 < 0.0)
+                fRes = -1;      // -x < empty cell
+            else
+                fRes = 1;       // x > empty cell
+        }
+        // else: empty cell == 0.0
+    }
+    else
+    {
+        if (rCell2.mbValue)
+        {
+            if (!rtl::math::approxEqual(fCell1, rCell2.mfValue))
+            {
+                if (fCell1 - rCell2.mfValue < 0)
+                    fRes = -1;
+                else
+                    fRes = 1;
+            }
+        }
+        else
+        {
+            fRes = -1;          // number is less than string
+            bStringQuery = true;
+        }
+    }
+
+    if (bStringQuery && pOptions)
+    {
+        const ScQueryEntry& rEntry = pOptions->aQueryEntry;
+        const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+        if (!rItems.empty())
+        {
+            const ScQueryEntry::Item& rItem = rItems[0];
+            if (rItem.meType != ScQueryEntry::ByString && !rItem.maString.isEmpty() &&
+                (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL))
+            {
+                // As in ScTable::ValidQuery() match a numeric string for a
+                // number query that originated from a string, e.g. in SUMIF
+                // and COUNTIF. Transliteration is not needed here.
+                bool bEqual = rCell2.maStr == rItem.maString;
+
+                // match => fRes=0, else fRes=1
+                fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
+            }
+        }
+    }
+
+    return fRes;
+}
+
+double CompareFunc( const Compare::Cell& rCell1, double fCell2, CompareOptions* pOptions )
+{
+    // Keep DoubleError if encountered
+    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+    if (!rCell1.mbEmpty && rCell1.mbValue && !rtl::math::isFinite(rCell1.mfValue))
+        return rCell1.mfValue;
+    if (!rtl::math::isFinite(fCell2))
+        return fCell2;
+
+    bool bStringQuery = false;
+    double fRes = 0;
+    if (rCell1.mbEmpty)
+    {
+        if (fCell2 != 0.0)
+        {
+            if (fCell2 < 0.0)
+                fRes = 1;       // empty cell > -x
+            else
+                fRes = -1;      // empty cell < x
+        }
+        // else: empty cell == 0.0
+    }
+    else if (rCell1.mbValue)
+    {
+        if (!rtl::math::approxEqual(rCell1.mfValue, fCell2))
+        {
+            if (rCell1.mfValue - fCell2 < 0)
+                fRes = -1;
+            else
+                fRes = 1;
+        }
+    }
+    else
+    {
+        fRes = 1;               // string is greater than number
+        bStringQuery = true;
+    }
+
+    if (bStringQuery && pOptions)
+    {
+        const ScQueryEntry& rEntry = pOptions->aQueryEntry;
+        const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
+        if (!rItems.empty())
+        {
+            const ScQueryEntry::Item& rItem = rItems[0];
+            if (rItem.meType != ScQueryEntry::ByString && !rItem.maString.isEmpty() &&
+                (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL))
+            {
+                // As in ScTable::ValidQuery() match a numeric string for a
+                // number query that originated from a string, e.g. in SUMIF
+                // and COUNTIF. Transliteration is not needed here.
+                bool bEqual = rCell1.maStr == rItem.maString;
+
+                // match => fRes=0, else fRes=1
+                fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
+            }
+        }
+    }
+
+    return fRes;
+}
+
+double CompareFunc( double fCell1, double fCell2 )
+{
+    // Keep DoubleError if encountered
+    // #i40539# if bEmpty is set, bVal/nVal are uninitialized
+    if (!rtl::math::isFinite(fCell1))
+        return fCell1;
+    if (!rtl::math::isFinite(fCell2))
+        return fCell2;
+
+    double fRes = 0.0;
+
+    if (!rtl::math::approxEqual(fCell1, fCell2))
+    {
+        if (fCell1 - fCell2 < 0.0)
+            fRes = -1;
+        else
+            fRes = 1;
+    }
+
+    return fRes;
+}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 89730bd..a195a4f 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1218,6 +1218,34 @@ public:
     }
 };
 
+inline bool evaluate( double fVal, ScQueryOp eOp )
+{
+    switch (eOp)
+    {
+        case SC_EQUAL:
+            return fVal == 0.0;
+        case SC_LESS:
+            return fVal < 0.0;
+        case SC_GREATER:
+            return fVal > 0.0;
+        break;
+        case SC_LESS_EQUAL:
+            return fVal <= 0.0;
+        break;
+        case SC_GREATER_EQUAL:
+            return fVal >= 0.0;
+        break;
+        case SC_NOT_EQUAL:
+            return fVal != 0.0;
+        break;
+        default:
+            ;
+    }
+
+    OSL_TRACE( "evaluate: unhandled comparison operator: %d", (int)eOp);
+    return false;
+}
+
 class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
 {
     sc::Compare& mrComp;
@@ -1228,31 +1256,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type
     void compare()
     {
         double fVal = sc::CompareFunc(mrComp.maCells[0], mrComp.maCells[1], mrComp.mbIgnoreCase, mpOptions);
-        bool bRes = false;
-        switch (mrComp.meOp)
-        {
-            case SC_EQUAL:
-                bRes = fVal == 0.0;
-            break;
-            case SC_LESS:
-                bRes = fVal < 0.0;
-            break;
-            case SC_GREATER:
-                bRes = fVal > 0.0;
-            break;
-            case SC_LESS_EQUAL:
-                bRes = fVal <= 0.0;
-            break;
-            case SC_GREATER_EQUAL:
-                bRes = fVal >= 0.0;
-            break;
-            case SC_NOT_EQUAL:
-                bRes = fVal != 0.0;
-            break;
-            default:
-                OSL_TRACE( "CompareMatrixFunc: unhandled comparison operator: %d", (int)mrComp.meOp);
-        }
-        maResValues.push_back(bRes);
+        maResValues.push_back(evaluate(fVal, mrComp.meOp));
     }
 
 public:
@@ -1333,6 +1337,96 @@ public:
     }
 };
 
+/**
+ * Left-hand side is a matrix while the right-hand side is a numeric value.
+ */
+class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_block_type, void>
+{
+    sc::Compare& mrComp;
+    double mfRightValue;
+    sc::CompareOptions* mpOptions;
+    std::vector<bool> maResValues;
+
+    void compare()
+    {
+        double fVal = sc::CompareFunc(mrComp.maCells[0], mfRightValue, mpOptions);
+        maResValues.push_back(evaluate(fVal, mrComp.meOp));
+    }
+
+    void compareLeftNumeric( double fLeftVal )
+    {
+        double fVal = sc::CompareFunc(fLeftVal, mfRightValue);
+        maResValues.push_back(evaluate(fVal, mrComp.meOp));
+    }
+
+public:
+    CompareMatrixToNumericFunc( size_t nResSize, sc::Compare& rComp, double fRightValue, sc::CompareOptions* pOptions ) :
+        mrComp(rComp), mfRightValue(fRightValue), mpOptions(pOptions)
+    {
+        maResValues.reserve(nResSize);
+    }
+
+    void operator() (const MatrixImplType::element_block_node_type& node)
+    {
+        sc::Compare::Cell& rCell = mrComp.maCells[0];
+
+        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);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                    compareLeftNumeric(*it);
+            }
+            break;
+            case mdds::mtm::element_boolean:
+            {
+                typedef MatrixImplType::boolean_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                    compareLeftNumeric(*it);
+            }
+            break;
+            case mdds::mtm::element_string:
+            {
+                typedef MatrixImplType::string_block_type block_type;
+
+                block_type::const_iterator it = block_type::begin(*node.data);
+                block_type::const_iterator itEnd = block_type::end(*node.data);
+                for (; it != itEnd; ++it)
+                {
+                    const svl::SharedString& rStr = *it;
+                    rCell.mbValue = false;
+                    rCell.mbEmpty = false;
+                    rCell.maStr = rStr;
+                    compare();
+                }
+            }
+            break;
+            case mdds::mtm::element_empty:
+            {
+                rCell.mbValue = false;
+                rCell.mbEmpty = true;
+                rCell.maStr = svl::SharedString::getEmptyString();
+                for (size_t i = 0; i < node.size; ++i)
+                    compare();
+            }
+            default:
+                ;
+        }
+    }
+
+    const std::vector<bool>& getValues() const
+    {
+        return maResValues;
+    }
+};
+
 class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, void>
 {
     std::vector<double> maArray;
@@ -1529,6 +1623,23 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
     size_t nSize = aSize.column * aSize.row;
+    if (nMatPos == 0)
+    {
+        if (rComp.maCells[1].mbValue && !rComp.maCells[1].mbEmpty)
+        {
+            // Matrix on the left, and a numeric value on the right.
+            CompareMatrixToNumericFunc aFunc(nSize, rComp, rComp.maCells[1].mfValue, pOptions);
+            maMat.walk(aFunc);
+
+            // We assume the result matrix has the same dimension as this matrix.
+            const std::vector<bool>& rResVal = aFunc.getValues();
+            if (nSize != rResVal.size())
+                ScMatrixRef();
+
+            return ScMatrixRef(new ScMatrix(aSize.column, aSize.row, rResVal));
+        }
+    }
+
     CompareMatrixFunc aFunc(nSize, rComp, nMatPos, pOptions);
     maMat.walk(aFunc);
 
commit 013abfd29b125f8a049691c064bdae1db4d5880f
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Oct 19 22:09:25 2013 -0400

    Pass cells to CompareFunc, rather than the whole Compare struct.
    
    Change-Id: I4d5554fc5783b123aa0f90b7c078e1fc0f0cd866

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index d188d54..f428d90 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -53,7 +53,6 @@ struct CompareOptions
     ScQueryEntry        aQueryEntry;
     bool                bRegEx;
     bool                bMatchWholeCell;
-    bool                bIgnoreCase;
 
     CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg );
 private:
@@ -66,7 +65,7 @@ private:
 /** @param pOptions
         NULL means case sensitivity document option is to be used!
  */
-double CompareFunc( const Compare& rComp, CompareOptions* pOptions = NULL );
+double CompareFunc( const Compare::Cell& rCell1, const Compare::Cell& rCell2, bool bIgnoreCase, CompareOptions* pOptions = NULL );
 
 }
 
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index 679b103..d935d51 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -35,8 +35,7 @@ Compare::Compare() :
 CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
     aQueryEntry(rEntry),
     bRegEx(bReg),
-    bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell()),
-    bIgnoreCase(true)
+    bMatchWholeCell(pDoc->GetDocOptions().IsMatchWholeCell())
 {
     bRegEx = (bRegEx && (aQueryEntry.eOp == SC_EQUAL || aQueryEntry.eOp == SC_NOT_EQUAL));
     // Interpreter functions usually are case insensitive, except the simple
@@ -44,11 +43,8 @@ CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bo
     // struct if needed.
 }
 
-double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
+double CompareFunc( const Compare::Cell& rCell1, const Compare::Cell& rCell2, bool bIgnoreCase, CompareOptions* pOptions )
 {
-    const Compare::Cell& rCell1 = rComp.maCells[0];
-    const Compare::Cell& rCell2 = rComp.maCells[1];
-
     // Keep DoubleError if encountered
     // #i40539# if bEmpty is set, bVal/nVal are uninitialized
     if (!rCell1.mbEmpty && rCell1.mbValue && !rtl::math::isFinite(rCell1.mfValue))
@@ -138,7 +134,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 sal_Int32 nStart = 0;
                 sal_Int32 nStop  = rCell1.maStr.getLength();
                 bool bMatch = rEntry.GetSearchTextPtr(
-                        !pOptions->bIgnoreCase)->SearchForward(
+                        !bIgnoreCase)->SearchForward(
                             rCell1.maStr.getString(), &nStart, &nStop);
                 if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rCell1.maStr.getLength()))
                     bMatch = false;     // RegEx must match entire string.
@@ -147,12 +143,12 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
             else if (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL)
             {
                 ::utl::TransliterationWrapper* pTransliteration =
-                    (pOptions->bIgnoreCase ? ScGlobal::GetpTransliteration() :
+                    (bIgnoreCase ? ScGlobal::GetpTransliteration() :
                      ScGlobal::GetCaseTransliteration());
                 bool bMatch = false;
                 if (pOptions->bMatchWholeCell)
                 {
-                    if (pOptions->bIgnoreCase)
+                    if (bIgnoreCase)
                         bMatch = rCell1.maStr.getDataIgnoreCase() == rCell2.maStr.getDataIgnoreCase();
                     else
                         bMatch = rCell1.maStr.getData() == rCell2.maStr.getData();
@@ -169,14 +165,14 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 }
                 fRes = (bMatch ? 0 : 1);
             }
-            else if (pOptions->bIgnoreCase)
+            else if (bIgnoreCase)
                 fRes = (double) ScGlobal::GetCollator()->compareString(
                         rCell1.maStr.getString(), rCell2.maStr.getString());
             else
                 fRes = (double) ScGlobal::GetCaseCollator()->compareString(
                         rCell1.maStr.getString(), rCell2.maStr.getString());
         }
-        else if (rComp.mbIgnoreCase)
+        else if (bIgnoreCase)
             fRes = (double) ScGlobal::GetCollator()->compareString(
                 rCell1.maStr.getString(), rCell2.maStr.getString());
         else
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index a598da2..6b600a0 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -876,7 +876,7 @@ double ScInterpreter::Compare()
     if( nGlobalError )
         return 0;
     nCurFmtType = nFuncFmtType = NUMBERFORMAT_LOGICAL;
-    return sc::CompareFunc(aComp);
+    return sc::CompareFunc(aComp.maCells[0], aComp.maCells[1], aComp.mbIgnoreCase);
 }
 
 
@@ -986,7 +986,8 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                             rCell.mbEmpty = false;
                         }
                     }
-                    aRes.mpMat->PutDouble(sc::CompareFunc(aComp, pOptions), j, k);
+                    aRes.mpMat->PutDouble(
+                        sc::CompareFunc(aComp.maCells[0], aComp.maCells[1], aComp.mbIgnoreCase, pOptions), j, k);
                 }
                 else
                     aRes.mpMat->PutString(mrStrPool.intern(ScGlobal::GetRscString(STR_NO_VALUE)), j, k);
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 18a1dfe..89730bd 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1227,7 +1227,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type
 
     void compare()
     {
-        double fVal = sc::CompareFunc(mrComp, mpOptions);
+        double fVal = sc::CompareFunc(mrComp.maCells[0], mrComp.maCells[1], mrComp.mbIgnoreCase, mpOptions);
         bool bRes = false;
         switch (mrComp.meOp)
         {
commit 1882a2b15187259a7e22d0a09f264ad149fa76be
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Oct 19 21:46:51 2013 -0400

    Try not to use array index access here...
    
    Change-Id: I48967956c63ba72b62604bcabe7166fc58061d13

diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index 6c60371..679b103 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -197,7 +197,12 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 // As in ScTable::ValidQuery() match a numeric string for a
                 // number query that originated from a string, e.g. in SUMIF
                 // and COUNTIF. Transliteration is not needed here.
-                bool bEqual = rComp.maCells[nStringQuery-1].maStr == rItem.maString;
+                bool bEqual = false;
+                if (nStringQuery == 1)
+                    bEqual = rCell1.maStr == rItem.maString;
+                else
+                    bEqual = rCell2.maStr == rItem.maString;
+
                 // match => fRes=0, else fRes=1
                 fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
             }
commit 81a555edbcea7493c6981dda452bf7d20e06fc02
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Oct 19 21:35:56 2013 -0400

    Store SharedString in Compare::Cell.
    
    This has a slight overhead for purely numeric comparisons.
    
    Change-Id: I243d5c81499177b3ae93b39a1af7c2f3b954bd39

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index 3189bc8..d188d54 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -22,7 +22,7 @@
 
 #include "queryentry.hxx"
 
-#include "rtl/ustring.hxx"
+#include "svl/sharedstring.hxx"
 
 class ScDocument;
 
@@ -33,12 +33,11 @@ struct Compare
     struct Cell
     {
         double mfValue;
-        OUString* mpStr;
+        svl::SharedString maStr;
         bool mbValue;
         bool mbEmpty;
 
         Cell();
-        Cell( OUString* p );
     };
 
     Cell maCells[2];
@@ -46,7 +45,7 @@ struct Compare
     ScQueryOp meOp;
     bool mbIgnoreCase;
 
-    Compare( OUString* p1, OUString* p2 );
+    Compare();
 };
 
 struct CompareOptions
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index 5782a6b..6c60371 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -27,17 +27,10 @@
 namespace sc {
 
 Compare::Cell::Cell() :
-    mfValue(0.0), mpStr(NULL), mbValue(false), mbEmpty(false) {}
+    mfValue(0.0), mbValue(false), mbEmpty(false) {}
 
-Compare::Cell::Cell( OUString* p ) :
-    mfValue(0.0), mpStr(p), mbValue(false), mbEmpty(false) {}
-
-Compare::Compare( OUString* p1, OUString* p2 ) :
-    meOp(SC_EQUAL), mbIgnoreCase(true)
-{
-    maCells[0] = Cell(p1);
-    maCells[1] = Cell(p2);
-}
+Compare::Compare() :
+    meOp(SC_EQUAL), mbIgnoreCase(true) {}
 
 CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
     aQueryEntry(rEntry),
@@ -82,7 +75,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
         }
         else
         {
-            if (!rCell2.mpStr->isEmpty())
+            if (!rCell2.maStr.isEmpty())
                 fRes = -1;      // empty cell < "..."
             // else: empty cell == ""
         }
@@ -102,7 +95,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
         }
         else
         {
-            if (!rCell1.mpStr->isEmpty())
+            if (!rCell1.maStr.isEmpty())
                 fRes = 1;       // "..." > empty cell
             // else: "" == empty cell
         }
@@ -139,15 +132,15 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
             // is/must be identical to *rEntry.pStr, which is essential for
             // regex to work through GetSearchTextPtr().
             ScQueryEntry& rEntry = pOptions->aQueryEntry;
-            OSL_ENSURE(rEntry.GetQueryItem().maString.getString().equals(*rCell2.mpStr), "ScInterpreter::CompareFunc: broken options");
+            OSL_ENSURE(rEntry.GetQueryItem().maString == rCell2.maStr, "ScInterpreter::CompareFunc: broken options");
             if (pOptions->bRegEx)
             {
                 sal_Int32 nStart = 0;
-                sal_Int32 nStop  = rCell1.mpStr->getLength();
+                sal_Int32 nStop  = rCell1.maStr.getLength();
                 bool bMatch = rEntry.GetSearchTextPtr(
                         !pOptions->bIgnoreCase)->SearchForward(
-                            *rCell1.mpStr, &nStart, &nStop);
-                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rCell1.mpStr->getLength()))
+                            rCell1.maStr.getString(), &nStart, &nStop);
+                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rCell1.maStr.getLength()))
                     bMatch = false;     // RegEx must match entire string.
                 fRes = (bMatch ? 0 : 1);
             }
@@ -156,34 +149,39 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 ::utl::TransliterationWrapper* pTransliteration =
                     (pOptions->bIgnoreCase ? ScGlobal::GetpTransliteration() :
                      ScGlobal::GetCaseTransliteration());
-                bool bMatch;
+                bool bMatch = false;
                 if (pOptions->bMatchWholeCell)
-                    bMatch = pTransliteration->isEqual(*rCell1.mpStr, *rCell2.mpStr);
+                {
+                    if (pOptions->bIgnoreCase)
+                        bMatch = rCell1.maStr.getDataIgnoreCase() == rCell2.maStr.getDataIgnoreCase();
+                    else
+                        bMatch = rCell1.maStr.getData() == rCell2.maStr.getData();
+                }
                 else
                 {
                     OUString aCell( pTransliteration->transliterate(
-                                *rCell1.mpStr, ScGlobal::eLnge, 0,
-                                rCell1.mpStr->getLength(), NULL));
+                                rCell1.maStr.getString(), ScGlobal::eLnge, 0,
+                                rCell1.maStr.getLength(), NULL));
                     OUString aQuer( pTransliteration->transliterate(
-                                *rCell2.mpStr, ScGlobal::eLnge, 0,
-                                rCell2.mpStr->getLength(), NULL));
+                                rCell2.maStr.getString(), ScGlobal::eLnge, 0,
+                                rCell2.maStr.getLength(), NULL));
                     bMatch = (aCell.indexOf( aQuer ) != -1);
                 }
                 fRes = (bMatch ? 0 : 1);
             }
             else if (pOptions->bIgnoreCase)
                 fRes = (double) ScGlobal::GetCollator()->compareString(
-                        *rCell1.mpStr, *rCell2.mpStr);
+                        rCell1.maStr.getString(), rCell2.maStr.getString());
             else
                 fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                        *rCell1.mpStr, *rCell2.mpStr);
+                        rCell1.maStr.getString(), rCell2.maStr.getString());
         }
         else if (rComp.mbIgnoreCase)
             fRes = (double) ScGlobal::GetCollator()->compareString(
-                *rCell1.mpStr, *rCell2.mpStr);
+                rCell1.maStr.getString(), rCell2.maStr.getString());
         else
             fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                *rCell1.mpStr, *rCell2.mpStr);
+                rCell1.maStr.getString(), rCell2.maStr.getString());
     }
 
     if (nStringQuery && pOptions)
@@ -199,7 +197,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 // As in ScTable::ValidQuery() match a numeric string for a
                 // number query that originated from a string, e.g. in SUMIF
                 // and COUNTIF. Transliteration is not needed here.
-                bool bEqual = (*rComp.maCells[nStringQuery-1].mpStr) == rItem.maString.getString();
+                bool bEqual = rComp.maCells[nStringQuery-1].maStr == rItem.maString;
                 // match => fRes=0, else fRes=1
                 fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
             }
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 0de212f..a598da2 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -791,8 +791,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
 
 double ScInterpreter::Compare()
 {
-    OUString aVal1, aVal2;
-    sc::Compare aComp( &aVal1, &aVal2 );
+    sc::Compare aComp;
     aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
     for( short i = 1; i >= 0; i-- )
     {
@@ -810,7 +809,7 @@ double ScInterpreter::Compare()
                 rCell.mbValue = true;
                 break;
             case svString:
-                *rCell.mpStr = GetString().getString();
+                rCell.maStr = GetString();
                 rCell.mbValue = false;
                 break;
             case svDoubleRef :
@@ -827,7 +826,7 @@ double ScInterpreter::Compare()
                 {
                     svl::SharedString aStr;
                     GetCellString(aStr, aCell);
-                    *rCell.mpStr = aStr.getString();
+                    rCell.maStr = aStr;
                     rCell.mbValue = false;
                 }
                 else
@@ -857,7 +856,7 @@ double ScInterpreter::Compare()
                     rCell.mbEmpty = true;
                 else if (pMat->IsString(0, 0))
                 {
-                    *rCell.mpStr = pMat->GetString(0, 0).getString();
+                    rCell.maStr = pMat->GetString(0, 0);
                     rCell.mbValue = false;
                 }
                 else
@@ -883,8 +882,7 @@ double ScInterpreter::Compare()
 
 sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pOptions )
 {
-    OUString aVal1, aVal2;
-    sc::Compare aComp( &aVal1, &aVal2 );
+    sc::Compare aComp;
     aComp.meOp = eOp;
     aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
     sc::RangeMatrix aMat[2];
@@ -905,7 +903,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                 rCell.mbValue = true;
                 break;
             case svString:
-                *rCell.mpStr = GetString().getString();
+                rCell.maStr = GetString();
                 rCell.mbValue = false;
                 break;
             case svSingleRef:
@@ -919,7 +917,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                 {
                     svl::SharedString aStr;
                     GetCellString(aStr, aCell);
-                    *rCell.mpStr = aStr.getString();
+                    rCell.maStr = aStr;
                     rCell.mbValue = false;
                 }
                 else
@@ -978,7 +976,7 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                         if (aMat[i].mpMat->IsString(j, k))
                         {
                             rCell.mbValue = false;
-                            *rCell.mpStr = aMat[i].mpMat->GetString(j, k).getString();
+                            rCell.maStr = aMat[i].mpMat->GetString(j, k);
                             rCell.mbEmpty = aMat[i].mpMat->IsEmpty(j, k);
                         }
                         else
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 3f17535..18a1dfe 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1309,7 +1309,7 @@ public:
                     const svl::SharedString& rStr = *it;
                     rCell.mbValue = false;
                     rCell.mbEmpty = false;
-                    *rCell.mpStr = rStr.getString();
+                    rCell.maStr = rStr;
                     compare();
                 }
             }
@@ -1318,7 +1318,7 @@ public:
             {
                 rCell.mbValue = false;
                 rCell.mbEmpty = true;
-                *rCell.mpStr = svl::SharedString::getEmptyString().getString();
+                rCell.maStr = svl::SharedString::getEmptyString();
                 for (size_t i = 0; i < node.size; ++i)
                     compare();
             }
commit 73353186d58ae187f3f1ce4f206795424fb3336c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Oct 19 21:07:26 2013 -0400

    Better way to organize 2 compared cell values.
    
    Turns out this is slightly faster too.
    
    Change-Id: I5a8c3474ab2a342200a5cfa9a93e6d89433595c4

diff --git a/sc/inc/compare.hxx b/sc/inc/compare.hxx
index 0bbf8dc..3189bc8 100644
--- a/sc/inc/compare.hxx
+++ b/sc/inc/compare.hxx
@@ -30,23 +30,23 @@ namespace sc {
 
 struct Compare
 {
-    double nVal[2];
-    OUString* pVal[2];
-    bool bVal[2];
-    bool bEmpty[2];
+    struct Cell
+    {
+        double mfValue;
+        OUString* mpStr;
+        bool mbValue;
+        bool mbEmpty;
+
+        Cell();
+        Cell( OUString* p );
+    };
+
+    Cell maCells[2];
 
     ScQueryOp meOp;
     bool mbIgnoreCase;
 
-    Compare( OUString* p1, OUString* p2 ) :
-        meOp(SC_EQUAL),
-        mbIgnoreCase(true)
-    {
-        pVal[0] = p1;
-        pVal[1] = p2;
-        bEmpty[0] = false;
-        bEmpty[1] = false;
-    }
+    Compare( OUString* p1, OUString* p2 );
 };
 
 struct CompareOptions
diff --git a/sc/source/core/tool/compare.cxx b/sc/source/core/tool/compare.cxx
index bf50093..5782a6b 100644
--- a/sc/source/core/tool/compare.cxx
+++ b/sc/source/core/tool/compare.cxx
@@ -26,6 +26,19 @@
 
 namespace sc {
 
+Compare::Cell::Cell() :
+    mfValue(0.0), mpStr(NULL), mbValue(false), mbEmpty(false) {}
+
+Compare::Cell::Cell( OUString* p ) :
+    mfValue(0.0), mpStr(p), mbValue(false), mbEmpty(false) {}
+
+Compare::Compare( OUString* p1, OUString* p2 ) :
+    meOp(SC_EQUAL), mbIgnoreCase(true)
+{
+    maCells[0] = Cell(p1);
+    maCells[1] = Cell(p2);
+}
+
 CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bool bReg ) :
     aQueryEntry(rEntry),
     bRegEx(bReg),
@@ -40,24 +53,27 @@ CompareOptions::CompareOptions( ScDocument* pDoc, const ScQueryEntry& rEntry, bo
 
 double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
 {
+    const Compare::Cell& rCell1 = rComp.maCells[0];
+    const Compare::Cell& rCell2 = rComp.maCells[1];
+
     // Keep DoubleError if encountered
     // #i40539# if bEmpty is set, bVal/nVal are uninitialized
-    if ( !rComp.bEmpty[0] && rComp.bVal[0] && !::rtl::math::isFinite( rComp.nVal[0]))
-        return rComp.nVal[0];
-    if ( !rComp.bEmpty[1] && rComp.bVal[1] && !::rtl::math::isFinite( rComp.nVal[1]))
-        return rComp.nVal[1];
+    if (!rCell1.mbEmpty && rCell1.mbValue && !rtl::math::isFinite(rCell1.mfValue))
+        return rCell1.mfValue;
+    if (!rCell2.mbEmpty && rCell2.mbValue && !rtl::math::isFinite(rCell2.mfValue))
+        return rCell2.mfValue;
 
     size_t nStringQuery = 0;    // 0:=no, 1:=0, 2:=1
     double fRes = 0;
-    if ( rComp.bEmpty[ 0 ] )
+    if (rCell1.mbEmpty)
     {
-        if ( rComp.bEmpty[ 1 ] )
+        if (rCell2.mbEmpty)
             ;       // empty cell == empty cell, fRes 0
-        else if( rComp.bVal[ 1 ] )
+        else if (rCell2.mbValue)
         {
-            if (rComp.nVal[1] != 0.0)
+            if (rCell2.mfValue != 0.0)
             {
-                if ( rComp.nVal[ 1 ] < 0.0 )
+                if (rCell2.mfValue < 0.0)
                     fRes = 1;       // empty cell > -x
                 else
                     fRes = -1;      // empty cell < x
@@ -66,18 +82,18 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
         }
         else
         {
-            if ( !rComp.pVal[ 1 ]->isEmpty() )
+            if (!rCell2.mpStr->isEmpty())
                 fRes = -1;      // empty cell < "..."
             // else: empty cell == ""
         }
     }
-    else if ( rComp.bEmpty[ 1 ] )
+    else if (rCell2.mbEmpty)
     {
-        if( rComp.bVal[ 0 ] )
+        if (rCell1.mbValue)
         {
-            if (rComp.nVal[0] != 0.0)
+            if (rCell1.mfValue != 0.0)
             {
-                if ( rComp.nVal[ 0 ] < 0.0 )
+                if (rCell1.mfValue < 0.0)
                     fRes = -1;      // -x < empty cell
                 else
                     fRes = 1;       // x > empty cell
@@ -86,18 +102,18 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
         }
         else
         {
-            if ( !rComp.pVal[ 0 ]->isEmpty() )
+            if (!rCell1.mpStr->isEmpty())
                 fRes = 1;       // "..." > empty cell
             // else: "" == empty cell
         }
     }
-    else if( rComp.bVal[ 0 ] )
+    else if (rCell1.mbValue)
     {
-        if( rComp.bVal[ 1 ] )
+        if (rCell2.mbValue)
         {
-            if ( !::rtl::math::approxEqual( rComp.nVal[ 0 ], rComp.nVal[ 1 ] ) )
+            if (!rtl::math::approxEqual(rCell1.mfValue, rCell2.mfValue))
             {
-                if( rComp.nVal[ 0 ] - rComp.nVal[ 1 ] < 0 )
+                if (rCell1.mfValue - rCell2.mfValue < 0)
                     fRes = -1;
                 else
                     fRes = 1;
@@ -109,7 +125,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
             nStringQuery = 2;   // 1+1
         }
     }
-    else if( rComp.bVal[ 1 ] )
+    else if (rCell2.mbValue)
     {
         fRes = 1;               // string is greater than number
         nStringQuery = 1;       // 0+1
@@ -123,15 +139,15 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
             // is/must be identical to *rEntry.pStr, which is essential for
             // regex to work through GetSearchTextPtr().
             ScQueryEntry& rEntry = pOptions->aQueryEntry;
-            OSL_ENSURE(rEntry.GetQueryItem().maString.getString().equals(*rComp.pVal[1]), "ScInterpreter::CompareFunc: broken options");
+            OSL_ENSURE(rEntry.GetQueryItem().maString.getString().equals(*rCell2.mpStr), "ScInterpreter::CompareFunc: broken options");
             if (pOptions->bRegEx)
             {
                 sal_Int32 nStart = 0;
-                sal_Int32 nStop  = rComp.pVal[0]->getLength();
+                sal_Int32 nStop  = rCell1.mpStr->getLength();
                 bool bMatch = rEntry.GetSearchTextPtr(
-                        !pOptions->bIgnoreCase)->SearchForward( *rComp.pVal[0],
-                            &nStart, &nStop);
-                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rComp.pVal[0]->getLength()))
+                        !pOptions->bIgnoreCase)->SearchForward(
+                            *rCell1.mpStr, &nStart, &nStop);
+                if (bMatch && pOptions->bMatchWholeCell && (nStart != 0 || nStop != rCell1.mpStr->getLength()))
                     bMatch = false;     // RegEx must match entire string.
                 fRes = (bMatch ? 0 : 1);
             }
@@ -142,32 +158,32 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                      ScGlobal::GetCaseTransliteration());
                 bool bMatch;
                 if (pOptions->bMatchWholeCell)
-                    bMatch = pTransliteration->isEqual( *rComp.pVal[0], *rComp.pVal[1]);
+                    bMatch = pTransliteration->isEqual(*rCell1.mpStr, *rCell2.mpStr);
                 else
                 {
                     OUString aCell( pTransliteration->transliterate(
-                                *rComp.pVal[0], ScGlobal::eLnge, 0,
-                                rComp.pVal[0]->getLength(), NULL));
+                                *rCell1.mpStr, ScGlobal::eLnge, 0,
+                                rCell1.mpStr->getLength(), NULL));
                     OUString aQuer( pTransliteration->transliterate(
-                                *rComp.pVal[1], ScGlobal::eLnge, 0,
-                                rComp.pVal[1]->getLength(), NULL));
+                                *rCell2.mpStr, ScGlobal::eLnge, 0,
+                                rCell2.mpStr->getLength(), NULL));
                     bMatch = (aCell.indexOf( aQuer ) != -1);
                 }
                 fRes = (bMatch ? 0 : 1);
             }
             else if (pOptions->bIgnoreCase)
                 fRes = (double) ScGlobal::GetCollator()->compareString(
-                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+                        *rCell1.mpStr, *rCell2.mpStr);
             else
                 fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                        *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+                        *rCell1.mpStr, *rCell2.mpStr);
         }
         else if (rComp.mbIgnoreCase)
             fRes = (double) ScGlobal::GetCollator()->compareString(
-                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+                *rCell1.mpStr, *rCell2.mpStr);
         else
             fRes = (double) ScGlobal::GetCaseCollator()->compareString(
-                *rComp.pVal[ 0 ], *rComp.pVal[ 1 ] );
+                *rCell1.mpStr, *rCell2.mpStr);
     }
 
     if (nStringQuery && pOptions)
@@ -183,7 +199,7 @@ double CompareFunc( const Compare& rComp, CompareOptions* pOptions )
                 // As in ScTable::ValidQuery() match a numeric string for a
                 // number query that originated from a string, e.g. in SUMIF
                 // and COUNTIF. Transliteration is not needed here.
-                bool bEqual = (*rComp.pVal[nStringQuery-1]) == rItem.maString.getString();
+                bool bEqual = (*rComp.maCells[nStringQuery-1].mpStr) == rItem.maString.getString();
                 // match => fRes=0, else fRes=1
                 fRes = (rEntry.eOp == SC_NOT_EQUAL) ? bEqual : !bEqual;
             }
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 2cea9a2..0de212f 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -796,20 +796,22 @@ double ScInterpreter::Compare()
     aComp.mbIgnoreCase = pDok->GetDocOptions().IsIgnoreCase();
     for( short i = 1; i >= 0; i-- )
     {
+        sc::Compare::Cell& rCell = aComp.maCells[i];
+
         switch ( GetRawStackType() )
         {
             case svEmptyCell:
                 Pop();
-                aComp.bEmpty[ i ] = true;
+                rCell.mbEmpty = true;
                 break;
             case svMissing:
             case svDouble:
-                aComp.nVal[ i ] = GetDouble();
-                aComp.bVal[ i ] = true;
+                rCell.mfValue = GetDouble();
+                rCell.mbValue = true;
                 break;
             case svString:
-                *aComp.pVal[ i ] = GetString().getString();
-                aComp.bVal[ i ] = false;
+                *rCell.mpStr = GetString().getString();
+                rCell.mbValue = false;
                 break;
             case svDoubleRef :
             case svSingleRef :
@@ -820,18 +822,18 @@ double ScInterpreter::Compare()
                 ScRefCellValue aCell;
                 aCell.assign(*pDok, aAdr);
                 if (aCell.hasEmptyValue())
-                    aComp.bEmpty[i] = true;
+                    rCell.mbEmpty = true;
                 else if (aCell.hasString())
                 {
                     svl::SharedString aStr;
                     GetCellString(aStr, aCell);
-                    *aComp.pVal[i] = aStr.getString();
-                    aComp.bVal[i] = false;
+                    *rCell.mpStr = aStr.getString();
+                    rCell.mbValue = false;
                 }
                 else
                 {
-                    aComp.nVal[i] = GetCellValue(aAdr, aCell);
-                    aComp.bVal[i] = true;
+                    rCell.mfValue = GetCellValue(aAdr, aCell);
+                    rCell.mbValue = true;
                 }
             }
             break;
@@ -852,16 +854,16 @@ double ScInterpreter::Compare()
                     break;
                 }
                 if (pMat->IsEmpty(0, 0))
-                    aComp.bEmpty[i] = true;
+                    rCell.mbEmpty = true;
                 else if (pMat->IsString(0, 0))
                 {
-                    *aComp.pVal[i] = pMat->GetString(0, 0).getString();
-                    aComp.bVal[i] = false;
+                    *rCell.mpStr = pMat->GetString(0, 0).getString();
+                    rCell.mbValue = false;
                 }
                 else
                 {
-                    aComp.nVal[i] = pMat->GetDouble(0, 0);
-                    aComp.bVal[i] = true;
+                    rCell.mfValue = pMat->GetDouble(0, 0);
+                    rCell.mbValue = true;
                 }
             }
             break;
@@ -889,20 +891,22 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
     ScAddress aAdr;
     for( short i = 1; i >= 0; i-- )
     {
+        sc::Compare::Cell& rCell = aComp.maCells[i];
+
         switch (GetRawStackType())
         {
             case svEmptyCell:
                 Pop();
-                aComp.bEmpty[ i ] = true;
+                rCell.mbEmpty = true;
                 break;
             case svMissing:
             case svDouble:
-                aComp.nVal[ i ] = GetDouble();
-                aComp.bVal[ i ] = true;
+                rCell.mfValue = GetDouble();
+                rCell.mbValue = true;
                 break;
             case svString:
-                *aComp.pVal[ i ] = GetString().getString();
-                aComp.bVal[ i ] = false;
+                *rCell.mpStr = GetString().getString();
+                rCell.mbValue = false;
                 break;
             case svSingleRef:
             {
@@ -910,18 +914,18 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                 ScRefCellValue aCell;
                 aCell.assign(*pDok, aAdr);
                 if (aCell.hasEmptyValue())
-                    aComp.bEmpty[i] = true;
+                    rCell.mbEmpty = true;
                 else if (aCell.hasString())
                 {
                     svl::SharedString aStr;
                     GetCellString(aStr, aCell);
-                    *aComp.pVal[i] = aStr.getString();
-                    aComp.bVal[i] = false;
+                    *rCell.mpStr = aStr.getString();
+                    rCell.mbValue = false;
                 }
                 else
                 {
-                    aComp.nVal[i] = GetCellValue(aAdr, aCell);
-                    aComp.bVal[i] = true;
+                    rCell.mfValue = GetCellValue(aAdr, aCell);
+                    rCell.mbValue = true;
                 }
             }
             break;
@@ -969,17 +973,19 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScQueryOp eOp, sc::CompareOptions* pO
                 {
                     for ( short i=1; i>=0; i-- )
                     {
+                        sc::Compare::Cell& rCell = aComp.maCells[i];
+
                         if (aMat[i].mpMat->IsString(j, k))
                         {
-                            aComp.bVal[i] = false;
-                            *aComp.pVal[i] = aMat[i].mpMat->GetString(j, k).getString();
-                            aComp.bEmpty[i] = aMat[i].mpMat->IsEmpty(j, k);
+                            rCell.mbValue = false;
+                            *rCell.mpStr = aMat[i].mpMat->GetString(j, k).getString();
+                            rCell.mbEmpty = aMat[i].mpMat->IsEmpty(j, k);
                         }
                         else
                         {
-                            aComp.bVal[i] = true;
-                            aComp.nVal[i] = aMat[i].mpMat->GetDouble(j, k);
-                            aComp.bEmpty[i] = false;
+                            rCell.mbValue = true;
+                            rCell.mfValue = aMat[i].mpMat->GetDouble(j, k);
+                            rCell.mbEmpty = false;
                         }
                     }
                     aRes.mpMat->PutDouble(sc::CompareFunc(aComp, pOptions), j, k);
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 3fbdc7f..3f17535 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1264,6 +1264,8 @@ public:
 
     void operator() (const MatrixImplType::element_block_node_type& node)
     {
+        sc::Compare::Cell& rCell = mrComp.maCells[mnMatPos];
+
         switch (node.type)
         {
             case mdds::mtm::element_numeric:
@@ -1274,9 +1276,9 @@ public:
                 block_type::const_iterator itEnd = block_type::end(*node.data);
                 for (; it != itEnd; ++it)
                 {
-                    mrComp.bVal[mnMatPos] = true;
-                    mrComp.nVal[mnMatPos] = *it;
-                    mrComp.bEmpty[mnMatPos] = false;
+                    rCell.mbValue = true;
+                    rCell.mbEmpty = false;
+                    rCell.mfValue = *it;
                     compare();
                 }
             }
@@ -1289,9 +1291,9 @@ public:
                 block_type::const_iterator itEnd = block_type::end(*node.data);
                 for (; it != itEnd; ++it)
                 {
-                    mrComp.bVal[mnMatPos] = true;
-                    mrComp.nVal[mnMatPos] = *it;
-                    mrComp.bEmpty[mnMatPos] = false;
+                    rCell.mbValue = true;
+                    rCell.mbEmpty = false;
+                    rCell.mfValue = *it;
                     compare();
                 }
             }
@@ -1305,18 +1307,18 @@ public:
                 for (; it != itEnd; ++it)
                 {
                     const svl::SharedString& rStr = *it;
-                    mrComp.bVal[mnMatPos] = false;
-                    *mrComp.pVal[mnMatPos] = rStr.getString();
-                    mrComp.bEmpty[mnMatPos] = false;
+                    rCell.mbValue = false;
+                    rCell.mbEmpty = false;
+                    *rCell.mpStr = rStr.getString();
                     compare();
                 }
             }
             break;
             case mdds::mtm::element_empty:
             {
-                mrComp.bVal[mnMatPos] = false;
-                *mrComp.pVal[mnMatPos] = svl::SharedString::getEmptyString().getString();
-                mrComp.bEmpty[mnMatPos] = true;
+                rCell.mbValue = false;
+                rCell.mbEmpty = true;
+                *rCell.mpStr = svl::SharedString::getEmptyString().getString();
                 for (size_t i = 0; i < node.size; ++i)
                     compare();
             }


More information about the Libreoffice-commits mailing list