[Libreoffice-commits] core.git: Branch 'private/kohei/calc-shared-string' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Fri Oct 18 08:07:24 PDT 2013


 sc/inc/scmatrix.hxx              |   10 +-
 sc/source/core/tool/interpr1.cxx |  185 ++++++++++++++++++++++-----------------
 sc/source/core/tool/scmatrix.cxx |   27 ++++-
 3 files changed, 134 insertions(+), 88 deletions(-)

New commits:
commit 57b1dedcbde5418b1bae6295cbe730afce47a348
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Oct 18 11:07:38 2013 -0400

    Slightly optimize matrix value traversal.
    
    Change-Id: Idbcb2348ff7f4a5df32d66761849e3a92b4eb794

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 5e9800e..7d6d911 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -404,7 +404,15 @@ public:
     void CompareMatrix(
         ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions = NULL ) const;
 
-    void GetDoubleArray( std::vector<double>& rArray ) const;
+    /**
+     * Convert the content of matrix into a linear array of numeric values.
+     * String elements are mapped to NaN's and empty elements are mapped to
+     * either NaN or zero values.
+     *
+     * @param bEmptyAsZero if true empty elements are mapped to zero values,
+     *                     otherwise they become NaN values.
+     */
+    void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero = true ) const;
     void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
 
     ScMatrix& operator+= ( const ScMatrix& r );
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 7515c0c..0d63f54 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5353,7 +5353,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             }
 
             if (nGlobalError)
-                continue;   // and bail out, no need to evaluate other arguments
+                return 0;   // and bail out, no need to evaluate other arguments
 
             // take range
             nParam = 1;
@@ -5391,6 +5391,7 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                         if (!pQueryMatrix)
                         {
                             SetError( errIllegalParameter);
+                            return 0;
                         }
                         nCol1 = 0;
                         nRow1 = 0;
@@ -5404,9 +5405,13 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                     break;
                 default:
                     SetError( errIllegalParameter);
+                    return 0;
             }
             if ( nTab1 != nTab2 )
+            {
                 SetError( errIllegalArgument);
+                return 0;
+            }
 
             // All reference ranges must be of same dimension and size.
             if (!nDimensionCols)
@@ -5414,80 +5419,87 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             if (!nDimensionRows)
                 nDimensionRows = nRow2 - nRow1 + 1;
             if ((nDimensionCols != (nCol2 - nCol1 + 1)) || (nDimensionRows != (nRow2 - nRow1 + 1)))
+            {
                 SetError ( errIllegalArgument);
+                return 0;
+            }
 
             // recalculate matrix values
-            if (nGlobalError == 0)
+            if (nGlobalError)
+                return 0;
+
+            // initialize temporary result matrix
+            if (!pResMat)
             {
-                // initialize temporary result matrix
+                SCSIZE nResC, nResR;
+                nResC = nCol2 - nCol1 + 1;
+                nResR = nRow2 - nRow1 + 1;
+                pResMat = GetNewMat(nResC, nResR, false);
                 if (!pResMat)
                 {
-                    SCSIZE nResC, nResR;
-                    nResC = nCol2 - nCol1 + 1;
-                    nResR = nRow2 - nRow1 + 1;
-                    pResMat = GetNewMat(nResC, nResR, false);
-                    if (!pResMat)
-                        SetError( errIllegalParameter);
+                    SetError( errIllegalParameter);
+                    return 0;
                 }
+            }
 
-                ScQueryParam rParam;
-                rParam.nRow1       = nRow1;
-                rParam.nRow2       = nRow2;
+            ScQueryParam rParam;
+            rParam.nRow1       = nRow1;
+            rParam.nRow2       = nRow2;
 
-                ScQueryEntry& rEntry = rParam.GetEntry(0);
-                ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
-                rEntry.bDoQuery = true;
-                if (!bIsString)
-                {
-                    rItem.meType = ScQueryEntry::ByValue;
-                    rItem.mfVal = fVal;
-                    rEntry.eOp = SC_EQUAL;
-                }
-                else
+            ScQueryEntry& rEntry = rParam.GetEntry(0);
+            ScQueryEntry::Item& rItem = rEntry.GetQueryItem();
+            rEntry.bDoQuery = true;
+            if (!bIsString)
+            {
+                rItem.meType = ScQueryEntry::ByValue;
+                rItem.mfVal = fVal;
+                rEntry.eOp = SC_EQUAL;
+            }
+            else
+            {
+                rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0);
+                sal_uInt32 nIndex = 0;
+                bool bNumber = pFormatter->IsNumberFormat(
+                        rItem.maString.getString(), nIndex, rItem.mfVal);
+                rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
+                if (rItem.meType == ScQueryEntry::ByString)
+                    rParam.bRegExp = MayBeRegExp(rItem.maString.getString(), pDok);
+            }
+            ScAddress aAdr;
+            aAdr.SetTab( nTab1 );
+            rParam.nCol1  = nCol1;
+            rParam.nCol2  = nCol2;
+            rEntry.nField = nCol1;
+            SCsCOL nColDiff = -nCol1;
+            SCsROW nRowDiff = -nRow1;
+            if (pQueryMatrix)
+            {
+                // Never case-sensitive.
+                sc::CompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
+                ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
+                if (nGlobalError || !pResultMatrix)
                 {
-                    rParam.FillInExcelSyntax(pDok->GetSharedStringPool(), aString.getString(), 0);
-                    sal_uInt32 nIndex = 0;
-                    bool bNumber = pFormatter->IsNumberFormat(
-                            rItem.maString.getString(), nIndex, rItem.mfVal);
-                    rItem.meType = bNumber ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
-                    if (rItem.meType == ScQueryEntry::ByString)
-                        rParam.bRegExp = MayBeRegExp(rItem.maString.getString(), pDok);
+                    SetError( errIllegalParameter);
+                    return 0;
                 }
-                ScAddress aAdr;
-                aAdr.SetTab( nTab1 );
-                rParam.nCol1  = nCol1;
-                rParam.nCol2  = nCol2;
-                rEntry.nField = nCol1;
-                SCsCOL nColDiff = -nCol1;
-                SCsROW nRowDiff = -nRow1;
-                if (pQueryMatrix)
-                {
-                    // Never case-sensitive.
-                    sc::CompareOptions aOptions( pDok, rEntry, rParam.bRegExp);
-                    ScMatrixRef pResultMatrix = QueryMat( pQueryMatrix, aOptions);
-                    if (nGlobalError || !pResultMatrix)
-                    {
-                        SetError( errIllegalParameter);
-                    }
 
-                    // query and result matrices have same geometry, and the
-                    // result matrix is filled with boolean values.
-                    *pResMat += *pResultMatrix;
-                }
-                else
+                // query and result matrices have same geometry, and the
+                // result matrix is filled with boolean values.
+                *pResMat += *pResultMatrix;
+            }
+            else
+            {
+                ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
+                // Increment Entry.nField in iterator when switching to next column.
+                aCellIter.SetAdvanceQueryParamEntryField( true );
+                if ( aCellIter.GetFirst() )
                 {
-                    ScQueryCellIterator aCellIter(pDok, nTab1, rParam, false);
-                    // Increment Entry.nField in iterator when switching to next column.
-                    aCellIter.SetAdvanceQueryParamEntryField( true );
-                    if ( aCellIter.GetFirst() )
+                    do
                     {
-                        do
-                        {
-                            SCSIZE nC = aCellIter.GetCol() + nColDiff;
-                            SCSIZE nR = aCellIter.GetRow() + nRowDiff;
-                            pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
-                        } while ( aCellIter.GetNext() );
-                    }
+                        SCSIZE nC = aCellIter.GetCol() + nColDiff;
+                        SCSIZE nR = aCellIter.GetRow() + nRowDiff;
+                        pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
+                    } while ( aCellIter.GetNext() );
                 }
             }
             nParamCount -= 2;
@@ -5548,13 +5560,20 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
                     break;
                 default:
                     SetError( errIllegalParameter);
+                    return 0;
             }
             if ( nMainTab1 != nMainTab2 )
+            {
                 SetError( errIllegalArgument);
+                return 0;
+            }
 
             // All reference ranges must be of same dimension and size.
             if ((nDimensionCols != (nMainCol2 - nMainCol1 + 1)) || (nDimensionRows != (nMainRow2 - nMainRow1 + 1)))
+            {
                 SetError ( errIllegalArgument);
+                return 0;
+            }
 
             if (nGlobalError)
                 return 0;   // bail out
@@ -5564,28 +5583,34 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
             aAdr.SetTab( nMainTab1 );
             if (pMainMatrix)
             {
-                SCSIZE nC, nR;
-                pResMat->GetDimensions(nC, nR);
-                for (SCSIZE nCol = 0; nCol < nC; ++nCol)
+                std::vector<double> aResValues, aMainValues;
+                pResMat->GetDoubleArray(aResValues, true);
+                pMainMatrix->GetDoubleArray(aMainValues, false); // Map empty values to NaN's.
+                if (aResValues.size() != aMainValues.size())
                 {
-                    for (SCSIZE nRow = 0; nRow < nR; ++nRow)
+                    SetError( errIllegalArgument);
+                    return 0;
+                }
+
+                std::vector<double>::const_iterator itRes = aResValues.begin(), itResEnd = aResValues.end();
+                std::vector<double>::const_iterator itMain = aMainValues.begin();
+                for (; itRes != itResEnd; ++itRes, ++itMain)
+                {
+                    if (*itRes != nQueryCount)
+                        continue;
+
+                    fVal = *itMain;
+                    if (rtl::math::isNan(fVal))
+                        continue;
+
+                    ++fCount;
+                    if (bNull && fVal != 0.0)
                     {
-                        if (pResMat->GetDouble( nCol, nRow) == nQueryCount)
-                        {
-                            if (pMainMatrix->IsValue( nCol, nRow))
-                            {
-                                fVal = pMainMatrix->GetDouble( nCol, nRow);
-                                ++fCount;
-                                if ( bNull && fVal != 0.0 )
-                                {
-                                    bNull = false;
-                                    fMem = fVal;
-                                }
-                                else
-                                    fSum += fVal;
-                            }
-                        }
+                        bNull = false;
+                        fMem = fVal;
                     }
+                    else
+                        fSum += fVal;
                 }
             }
             else
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 29dcda7..a5487a7 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -302,7 +302,7 @@ public:
 
     void CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMatPos, sc::CompareOptions* pOptions ) const;
 
-    void GetDoubleArray( std::vector<double>& rArray ) const;
+    void GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const;
     void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
     void AddValues( const ScMatrixImpl& rMat );
 
@@ -1482,8 +1482,11 @@ class ToDoubleArray : std::unary_function<MatrixImplType::element_block_type, vo
     std::vector<double> maArray;
     std::vector<double>::iterator miPos;
     double mfNaN;
+    bool mbEmptyAsZero;
+
 public:
-    ToDoubleArray(size_t nSize) : maArray(nSize, 0.0), miPos(maArray.begin())
+    ToDoubleArray( size_t nSize, bool bEmptyAsZero ) :
+        maArray(nSize, 0.0), miPos(maArray.begin()), mbEmptyAsZero(bEmptyAsZero)
     {
         rtl::math::setNan(&mfNaN);
     }
@@ -1517,7 +1520,17 @@ public:
             }
             break;
             case mdds::mtm::element_empty:
-                std::advance(miPos, node.size);
+            {
+                if (mbEmptyAsZero)
+                {
+                    std::advance(miPos, node.size);
+                    return;
+                }
+
+                for (size_t i = 0; i < node.size; ++i, ++miPos)
+                    *miPos = mfNaN;
+            }
+            break;
             default:
                 ;
         }
@@ -1669,10 +1682,10 @@ void ScMatrixImpl::CompareMatrix(
         rResMat.PutDouble(&rResVal[0], rResVal.size(), 0, 0);
 }
 
-void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray ) const
+void ScMatrixImpl::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
-    ToDoubleArray aFunc(aSize.row*aSize.column);
+    ToDoubleArray aFunc(aSize.row*aSize.column, bEmptyAsZero);
     maMat.walk(aFunc);
     aFunc.swap(rArray);
 }
@@ -2239,9 +2252,9 @@ void ScMatrix::CompareMatrix( ScMatrix& rResMat, sc::Compare& rComp, size_t nMat
     pImpl->CompareMatrix(rResMat, rComp, nMatPos, pOptions);
 }
 
-void ScMatrix::GetDoubleArray( std::vector<double>& rArray ) const
+void ScMatrix::GetDoubleArray( std::vector<double>& rArray, bool bEmptyAsZero ) const
 {
-    pImpl->GetDoubleArray(rArray);
+    pImpl->GetDoubleArray(rArray, bEmptyAsZero);
 }
 
 void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const


More information about the Libreoffice-commits mailing list