[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