sc/Library_sc.mk | 1 sc/inc/column.hxx | 2 sc/inc/formulacell.hxx | 4 - sc/inc/formulagroup.hxx | 22 ++++++++ sc/inc/types.hxx | 3 + sc/source/core/data/column2.cxx | 1 sc/source/core/data/formulacell.cxx | 77 ++-------------------------- sc/source/core/tool/formulagroup.cxx | 96 +++++++++++++++++++++++++++++++++++ 8 files changed, 130 insertions(+), 76 deletions(-)
New commits: commit 598fe47e7023abbe2c1f6859cefa395a09eddefe Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Apr 30 11:16:21 2013 -0400 Move the group calculation code into its own class. To isolate the code that will be re-written for true vectorized calculation... Change-Id: I3ccd15841ed6fcdc6a22a590ba82d46d0b4863c5 diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index fe5b4b1..f7be65cc 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -190,6 +190,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/tool/doubleref \ sc/source/core/tool/editutil \ sc/source/core/tool/filtopt \ + sc/source/core/tool/formulagroup \ sc/source/core/tool/formulaopt \ sc/source/core/tool/formulaparserpool \ sc/source/core/tool/formularesult \ diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index e70f108..e0773aa 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -82,8 +82,6 @@ struct ScFormulaCellGroup; struct ScRefCellValue; class ScDocumentImport; -typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef; - struct ScNeededSizeOptions { const ScPatternAttr* pPattern; diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx index e4f1cfa..2a8546f 100644 --- a/sc/inc/formulacell.hxx +++ b/sc/inc/formulacell.hxx @@ -51,8 +51,6 @@ inline void intrusive_ptr_release(ScFormulaCellGroup *p) delete p; } -typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef; - enum ScMatrixMode { MM_NONE = 0, // No matrix formula MM_FORMULA = 1, // Upper left matrix formula cell @@ -282,6 +280,8 @@ public: */ void SetResultDouble( double n ) { aResult.SetDouble( n); } + void SetResultToken( const formula::FormulaToken* pToken ); + double GetResultDouble() const { return aResult.GetDouble(); } void SetErrCode( sal_uInt16 n ); diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx index 0a8e3f7..55f6e09 100644 --- a/sc/inc/formulagroup.hxx +++ b/sc/inc/formulagroup.hxx @@ -10,9 +10,15 @@ #ifndef SC_FORMULAGROUP_HXX #define SC_FORMULAGROUP_HXX +#include "address.hxx" +#include "types.hxx" + #include <boost/noncopyable.hpp> #include <boost/ptr_container/ptr_vector.hpp> +class ScDocument; +class ScTokenArray; + namespace sc { struct FormulaGroupContext : boost::noncopyable @@ -23,6 +29,22 @@ struct FormulaGroupContext : boost::noncopyable ArrayStoreType maArrays; }; +/** + * All the vectorized formula calculation code should be collectd here. + */ +class FormulaGroupInterpreter +{ + ScDocument& mrDoc; + ScAddress maTopPos; + ScFormulaCellGroupRef mxGroup; + ScTokenArray& mrCode; +public: + FormulaGroupInterpreter( + ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode); + + bool interpret(); +}; + } #endif diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index aa20043..0a97b25 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -39,6 +39,9 @@ typedef ::boost::intrusive_ptr<const ScMatrix> ScConstMatrixRef; class ScToken; typedef ::boost::intrusive_ptr<ScToken> ScTokenRef; +struct ScFormulaCellGroup; +typedef ::boost::intrusive_ptr<ScFormulaCellGroup> ScFormulaCellGroupRef; + /** * When vectorization is enabled, we could potentially mass-calculate a * series of formula token arrays in adjacent formula cells in one step, diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 2e20d0f..c93e043 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1665,7 +1665,6 @@ bool ScColumn::ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow const double* ScColumn::FetchDoubleArray( sc::FormulaGroupContext& /*rCxt*/, SCROW nRow1, SCROW nRow2 ) const { // TODO: I'll use the context object later. - if (nRow1 > nRow2) return NULL; diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 3e85a9e..d271edc 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1611,6 +1611,10 @@ bool ScFormulaCell::IsDirtyOrInTableOpDirty() const return bDirty || (bTableOpDirty && pDocument->IsInInterpreterTableOp()); } +void ScFormulaCell::SetResultToken( const formula::FormulaToken* pToken ) +{ + aResult.SetToken(pToken); +} void ScFormulaCell::SetErrCode( sal_uInt16 n ) { @@ -3071,77 +3075,8 @@ bool ScFormulaCell::InterpretFormulaGroup() } } -#if 0 - // TODO: Calculate the formula group via vectorization. -#else - // Until we implement group calculation for real, decompose the group into - // individual formula token arrays for individual calculation. - ScAddress aTmpPos = aPos; - for (sal_Int32 i = 0; i < xGroup->mnLength; ++i) - { - aTmpPos.SetRow(xGroup->mnStart + i); - ScTokenArray aCode2; - for (const formula::FormulaToken* p = aCode.First(); p; p = aCode.Next()) - { - switch (p->GetType()) - { - case svSingleVectorRef: - { - const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p); - const double* pArray = p2->GetArray(); - aCode2.AddDouble(i < p2->GetArrayLength() ? pArray[i] : 0.0); - } - break; - case svDoubleVectorRef: - { - const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p); - const std::vector<const double*>& rArrays = p2->GetArrays(); - size_t nColSize = rArrays.size(); - size_t nRowStart = p2->IsStartFixed() ? 0 : i; - size_t nRowEnd = p2->GetRefRowSize() - 1; - if (!p2->IsEndFixed()) - nRowEnd += i; - - size_t nRowSize = nRowEnd - nRowStart + 1; - ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0)); - for (size_t nCol = 0; nCol < nColSize; ++nCol) - { - const double* pArray = rArrays[nCol]; - for (size_t nRow = 0; nRow < nRowSize; ++nRow) - { - if (nRowStart + nRow < p2->GetArrayLength()) - { - double fVal = pArray[nRowStart+nRow]; - pMat->PutDouble(fVal, nCol, nRow); - } - } - } - - ScMatrixToken aTok(pMat); - aCode2.AddToken(aTok); - } - break; - default: - aCode2.AddToken(*p); - } - } - - ScFormulaCell* pDest = pDocument->GetFormulaCell(aTmpPos); - if (!pDest) - return false; - - ScCompiler aComp(pDocument, aPos, aCode2); - aComp.SetGrammar(pDocument->GetGrammar()); - aComp.CompileTokenArray(); // Create RPN token array. - ScInterpreter aInterpreter(pDest, pDocument, aTmpPos, aCode2); - aInterpreter.Interpret(); - - pDest->aResult.SetToken(aInterpreter.GetResultToken().get()); - pDest->ResetDirty(); - } - - return true; -#endif + sc::FormulaGroupInterpreter aInterpreter(*pDocument, aPos, xGroup, aCode); + return aInterpreter.interpret(); } bool ScFormulaCell::InterpretInvariantFormulaGroup() diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx new file mode 100644 index 0000000..9f76fe2 --- /dev/null +++ b/sc/source/core/tool/formulagroup.cxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "formulagroup.hxx" +#include "document.hxx" +#include "formulacell.hxx" +#include "tokenarray.hxx" +#include "compiler.hxx" +#include "interpre.hxx" + +#include "formula/vectortoken.hxx" + +namespace sc { + +FormulaGroupInterpreter::FormulaGroupInterpreter( + ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) : + mrDoc(rDoc), maTopPos(rTopPos), mxGroup(xGroup), mrCode(rCode) {} + +bool FormulaGroupInterpreter::interpret() +{ + // Until we implement group calculation for real, decompose the group into + // individual formula token arrays for individual calculation. + ScAddress aTmpPos = maTopPos; + for (sal_Int32 i = 0; i < mxGroup->mnLength; ++i) + { + aTmpPos.SetRow(mxGroup->mnStart + i); + ScTokenArray aCode2; + for (const formula::FormulaToken* p = mrCode.First(); p; p = mrCode.Next()) + { + switch (p->GetType()) + { + case formula::svSingleVectorRef: + { + const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p); + const double* pArray = p2->GetArray(); + aCode2.AddDouble(i < p2->GetArrayLength() ? pArray[i] : 0.0); + } + break; + case formula::svDoubleVectorRef: + { + const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p); + const std::vector<const double*>& rArrays = p2->GetArrays(); + size_t nColSize = rArrays.size(); + size_t nRowStart = p2->IsStartFixed() ? 0 : i; + size_t nRowEnd = p2->GetRefRowSize() - 1; + if (!p2->IsEndFixed()) + nRowEnd += i; + + size_t nRowSize = nRowEnd - nRowStart + 1; + ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0)); + for (size_t nCol = 0; nCol < nColSize; ++nCol) + { + const double* pArray = rArrays[nCol]; + for (size_t nRow = 0; nRow < nRowSize; ++nRow) + { + if (nRowStart + nRow < p2->GetArrayLength()) + { + double fVal = pArray[nRowStart+nRow]; + pMat->PutDouble(fVal, nCol, nRow); + } + } + } + + ScMatrixToken aTok(pMat); + aCode2.AddToken(aTok); + } + break; + default: + aCode2.AddToken(*p); + } + } + + ScFormulaCell* pDest = mrDoc.GetFormulaCell(aTmpPos); + if (!pDest) + return false; + + ScCompiler aComp(&mrDoc, aTmpPos, aCode2); + aComp.SetGrammar(mrDoc.GetGrammar()); + aComp.CompileTokenArray(); // Create RPN token array. + ScInterpreter aInterpreter(pDest, &mrDoc, aTmpPos, aCode2); + aInterpreter.Interpret(); + + pDest->SetResultToken(aInterpreter.GetResultToken().get()); + pDest->ResetDirty(); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits