[Libreoffice-commits] .: Branch 'feature/matrix-new-backend' - 2 commits - sc/inc sc/source
Kohei Yoshida
kohei at kemper.freedesktop.org
Wed Jul 18 12:07:15 PDT 2012
sc/inc/scmatrix.hxx | 5
sc/source/core/tool/interpr5.cxx | 202 +++++++++++++++++++++++++++------------
sc/source/core/tool/scmatrix.cxx | 36 ++++++
3 files changed, 183 insertions(+), 60 deletions(-)
New commits:
commit 9d96705b9a035944d0a3f53d8d56633458e7883c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jul 18 15:06:45 2012 -0400
Pass contiguous cell data as an array to matrix. This is faster.
It's generally faster to pass an array of elements to matrix than
passing them individually.
Change-Id: I4502025d08040327c1d1c09ce1756928be054c25
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 034bc4d..b40ba08 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -261,9 +261,14 @@ public:
void PutDouble( double fVal, SCSIZE nC, SCSIZE nR);
void PutDouble( double fVal, SCSIZE nIndex);
+ void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
+
void PutString( const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR);
void PutString( const ::rtl::OUString& rStr, SCSIZE nIndex);
+ void PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
+
void PutEmpty( SCSIZE nC, SCSIZE nR);
+
/// Jump FALSE without path
void PutEmptyPath( SCSIZE nC, SCSIZE nR);
void PutError( sal_uInt16 nErrorCode, SCSIZE nC, SCSIZE nR );
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index fb1a496..20c83f3 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -351,6 +351,43 @@ ScInterpreter::VolatileType ScInterpreter::GetVolatileType() const
return meVolatileType;
}
+namespace {
+
+struct CellBucket
+{
+ SCSIZE mnNumValStart;
+ SCSIZE mnStrValStart;
+ std::vector<double> maNumVals;
+ std::vector<rtl::OUString> maStrVals;
+
+ CellBucket() : mnNumValStart(0), mnStrValStart(0) {}
+
+ void flush(ScMatrix& rMat, SCSIZE nCol)
+ {
+ if (!maNumVals.empty())
+ {
+ const double* p = &maNumVals[0];
+ rMat.PutDouble(p, maNumVals.size(), nCol, mnNumValStart);
+ reset();
+ }
+ else if (!maStrVals.empty())
+ {
+ const rtl::OUString* p = &maStrVals[0];
+ rMat.PutString(p, maStrVals.size(), nCol, mnStrValStart);
+ reset();
+ }
+ }
+
+ void reset()
+ {
+ mnNumValStart = mnStrValStart = 0;
+ maNumVals.clear();
+ maStrVals.clear();
+ }
+};
+
+}
+
ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken,
SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
@@ -382,46 +419,89 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
if (!pMat || nGlobalError)
return NULL;
- ScCellIterator aCellIter(
- pDok, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ CellBucket aBucket;
- for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell =
- aCellIter.GetNext())
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
{
- SCCOL nThisCol = aCellIter.GetCol();
- SCROW nThisRow = aCellIter.GetRow();
- if (HasCellEmptyData(pCell))
- continue;
+ // Scan one column at a time, to pass a sequence of values to matrix in one call.
+ ScCellIterator aCellIter(
+ pDok, nCol, nRow1, nTab1, nCol, nRow2, nTab2);
+
+ SCROW nPrevRow = -2, nThisRow = -2;
- if (HasCellValueData(pCell))
+ for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext(), nPrevRow = nThisRow)
{
- ScAddress aAdr( nThisCol, nThisRow, nTab1);
- double fVal = GetCellValue( aAdr, pCell);
+ nThisRow = aCellIter.GetRow();
+
+ if (HasCellEmptyData(pCell))
+ {
+ aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
+ continue;
+ }
+
+ if (HasCellValueData(pCell))
+ {
+ ScAddress aAdr(nCol, nThisRow, nTab1);
+ double fVal = GetCellValue( aAdr, pCell);
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ }
+
+ if (nThisRow == nPrevRow + 1)
+ {
+ // Secondary numbers.
+ aBucket.maNumVals.push_back(fVal);
+ }
+ else
+ {
+ // First number.
+ aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
+ aBucket.mnNumValStart = nThisRow - nRow1;
+ aBucket.maNumVals.push_back(fVal);
+ }
+ continue;
+ }
+
+ String aStr;
+ GetCellString( aStr, pCell);
if ( nGlobalError )
{
- fVal = CreateDoubleError( nGlobalError);
+ double fVal = CreateDoubleError( nGlobalError);
nGlobalError = 0;
+
+ if (nThisRow == nPrevRow + 1)
+ {
+ // Secondary numbers.
+ aBucket.maNumVals.push_back(fVal);
+ }
+ else
+ {
+ // First number.
+ aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
+ aBucket.mnNumValStart = nThisRow - nRow1;
+ aBucket.maNumVals.push_back(fVal);
+ }
+ }
+ else
+ {
+ if (nThisRow == nPrevRow + 1)
+ {
+ // Secondary numbers.
+ aBucket.maStrVals.push_back(aStr);
+ }
+ else
+ {
+ // First number.
+ aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
+ aBucket.mnStrValStart = nThisRow - nRow1;
+ aBucket.maStrVals.push_back(aStr);
+ }
}
- pMat->PutDouble( fVal,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
- continue;
}
- String aStr;
- GetCellString( aStr, pCell);
- if ( nGlobalError )
- {
- double fVal = CreateDoubleError( nGlobalError);
- nGlobalError = 0;
- pMat->PutDouble( fVal,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
- }
- else
- pMat->PutString( aStr,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
+ aBucket.flush(*pMat, static_cast<SCSIZE>(nCol-nCol1));
}
if (pTokenMatrixMap)
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 8ff39c6..0a5f680 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -343,10 +343,14 @@ public:
bool ValidColRowReplicated( SCSIZE & rC, SCSIZE & rR ) const;
bool ValidColRowOrReplicated( SCSIZE & rC, SCSIZE & rR ) const;
void SetErrorAtInterpreter( sal_uInt16 nError ) const;
+
void PutDouble(double fVal, SCSIZE nC, SCSIZE nR);
void PutDouble( double fVal, SCSIZE nIndex);
+ void PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
+
void PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR);
void PutString(const ::rtl::OUString& rStr, SCSIZE nIndex);
+ void PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR);
void PutEmpty(SCSIZE nC, SCSIZE nR);
void PutEmptyPath(SCSIZE nC, SCSIZE nR);
@@ -495,6 +499,16 @@ void ScMatrixImpl::PutDouble(double fVal, SCSIZE nC, SCSIZE nR)
}
}
+void ScMatrixImpl::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ maMat.set(nR, nC, pArray, pArray + nLen);
+ else
+ {
+ OSL_FAIL("ScMatrixImpl::PutDouble: dimension error");
+ }
+}
+
void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
{
SCSIZE nC, nR;
@@ -505,7 +519,17 @@ void ScMatrixImpl::PutDouble( double fVal, SCSIZE nIndex)
void ScMatrixImpl::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
{
if (ValidColRow( nC, nR))
- maMat.set(nR, nC, rtl::OUString(rStr));
+ maMat.set(nR, nC, rStr);
+ else
+ {
+ OSL_FAIL("ScMatrixImpl::PutString: dimension error");
+ }
+}
+
+void ScMatrixImpl::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
+{
+ if (ValidColRow( nC, nR))
+ maMat.set(nR, nC, pArray, pArray + nLen);
else
{
OSL_FAIL("ScMatrixImpl::PutString: dimension error");
@@ -1181,6 +1205,11 @@ void ScMatrix::PutDouble( double fVal, SCSIZE nIndex)
pImpl->PutDouble(fVal, nIndex);
}
+void ScMatrix::PutDouble(const double* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
+{
+ pImpl->PutDouble(pArray, nLen, nC, nR);
+}
+
void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nC, SCSIZE nR)
{
pImpl->PutString(rStr, nC, nR);
@@ -1191,6 +1220,11 @@ void ScMatrix::PutString(const ::rtl::OUString& rStr, SCSIZE nIndex)
pImpl->PutString(rStr, nIndex);
}
+void ScMatrix::PutString(const rtl::OUString* pArray, size_t nLen, SCSIZE nC, SCSIZE nR)
+{
+ pImpl->PutString(pArray, nLen, nC, nR);
+}
+
void ScMatrix::PutEmpty(SCSIZE nC, SCSIZE nR)
{
pImpl->PutEmpty(nC, nR);
commit 8c4f226bd888e7af6784324e974764c562ed88a4
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Wed Jul 18 11:29:12 2012 -0400
Less indentations via early bailout.
Change-Id: Iae2b91fc732debe9b5c9cdd7c4717e1ef2fac08e
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index c689729..fb1a496 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -355,75 +355,79 @@ ScMatrixRef ScInterpreter::CreateMatrixFromDoubleRef( const FormulaToken* pToken
SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
SCCOL nCol2, SCROW nRow2, SCTAB nTab2 )
{
- RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateMatrixFromDoubleRef" );
- ScMatrixRef pMat = NULL;
- if (nTab1 == nTab2 && !nGlobalError)
- {
- ScTokenMatrixMap::const_iterator aIter;
- if ( static_cast<SCSIZE>(nRow2 - nRow1 + 1) *
- static_cast<SCSIZE>(nCol2 - nCol1 + 1) >
- ScMatrix::GetElementsMax() )
- SetError(errStackOverflow);
- else if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken))
- != pTokenMatrixMap->end()))
- pMat = static_cast<ScToken*>((*aIter).second.get())->GetMatrix();
- else
- {
- SCSIZE nMatCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
- SCSIZE nMatRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
- pMat = GetNewMat( nMatCols, nMatRows, true);
- if (pMat && !nGlobalError)
- {
- ScCellIterator aCellIter(
- pDok, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ if (nTab1 != nTab2 || nGlobalError)
+ {
+ // Not a 2D matrix.
+ SetError(errIllegalParameter);
+ return NULL;
+ }
- for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell =
- aCellIter.GetNext())
- {
- SCCOL nThisCol = aCellIter.GetCol();
- SCROW nThisRow = aCellIter.GetRow();
- if (HasCellEmptyData(pCell))
- continue;
+ SCSIZE nMatCols = static_cast<SCSIZE>(nCol2 - nCol1 + 1);
+ SCSIZE nMatRows = static_cast<SCSIZE>(nRow2 - nRow1 + 1);
- if (HasCellValueData(pCell))
- {
- ScAddress aAdr( nThisCol, nThisRow, nTab1);
- double fVal = GetCellValue( aAdr, pCell);
- if ( nGlobalError )
- {
- fVal = CreateDoubleError( nGlobalError);
- nGlobalError = 0;
- }
- pMat->PutDouble( fVal,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
- continue;
- }
+ if (nMatRows * nMatCols > ScMatrix::GetElementsMax())
+ {
+ SetError(errStackOverflow);
+ return NULL;
+ }
- String aStr;
- GetCellString( aStr, pCell);
- if ( nGlobalError )
- {
- double fVal = CreateDoubleError( nGlobalError);
- nGlobalError = 0;
- pMat->PutDouble( fVal,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
- }
- else
- pMat->PutString( aStr,
- static_cast<SCSIZE>(nThisCol-nCol1),
- static_cast<SCSIZE>(nThisRow-nRow1));
- }
+ ScTokenMatrixMap::const_iterator aIter;
+ if (pTokenMatrixMap && ((aIter = pTokenMatrixMap->find( pToken))
+ != pTokenMatrixMap->end()))
+ {
+ return static_cast<ScToken*>((*aIter).second.get())->GetMatrix();
+ }
+
+ ScMatrixRef pMat = GetNewMat( nMatCols, nMatRows, true);
+ if (!pMat || nGlobalError)
+ return NULL;
- if (pTokenMatrixMap)
- pTokenMatrixMap->insert( ScTokenMatrixMap::value_type(
- pToken, new ScMatrixToken( pMat)));
+ ScCellIterator aCellIter(
+ pDok, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+
+ for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell =
+ aCellIter.GetNext())
+ {
+ SCCOL nThisCol = aCellIter.GetCol();
+ SCROW nThisRow = aCellIter.GetRow();
+ if (HasCellEmptyData(pCell))
+ continue;
+
+ if (HasCellValueData(pCell))
+ {
+ ScAddress aAdr( nThisCol, nThisRow, nTab1);
+ double fVal = GetCellValue( aAdr, pCell);
+ if ( nGlobalError )
+ {
+ fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
}
+ pMat->PutDouble( fVal,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
+ continue;
+ }
+
+ String aStr;
+ GetCellString( aStr, pCell);
+ if ( nGlobalError )
+ {
+ double fVal = CreateDoubleError( nGlobalError);
+ nGlobalError = 0;
+ pMat->PutDouble( fVal,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
}
+ else
+ pMat->PutString( aStr,
+ static_cast<SCSIZE>(nThisCol-nCol1),
+ static_cast<SCSIZE>(nThisRow-nRow1));
}
- else // not a 2D matrix
- SetError(errIllegalParameter);
+
+ if (pTokenMatrixMap)
+ pTokenMatrixMap->insert( ScTokenMatrixMap::value_type(
+ pToken, new ScMatrixToken( pMat)));
+
return pMat;
}
More information about the Libreoffice-commits
mailing list