diff options
author | Dennis Francis <dennis.francis@collabora.co.uk> | 2017-11-15 21:08:44 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.co.uk> | 2017-11-21 16:09:44 +0530 |
commit | 4b3e4c1c98d0bd4ef5a5e0013dfb7faae0838a67 (patch) | |
tree | 46fb40eb09671bef54630fbcd3c6875f9cbd523a | |
parent | 9c88d6f2c9a1b03bc1f14684ceeceaf7e3e11bc5 (diff) |
cache FormulaToken for doubles
Change-Id: Ic0b4dff6f03ef3f88bd150e798fa2d83dfb0f486
-rw-r--r-- | formula/source/core/api/token.cxx | 10 | ||||
-rw-r--r-- | include/formula/token.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/inc/interpre.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 45 |
4 files changed, 55 insertions, 6 deletions
diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx index 04c4a203284d..2ed68521e720 100644 --- a/formula/source/core/api/token.cxx +++ b/formula/source/core/api/token.cxx @@ -216,6 +216,11 @@ short FormulaToken::GetDoubleType() const return 0; } +void FormulaToken::SetDoubleType( short ) +{ + SAL_WARN( "formula.core", "FormulaToken::SetDoubleType: virtual dummy called" ); +} + svl::SharedString FormulaToken::GetString() const { SAL_WARN( "formula.core", "FormulaToken::GetString: virtual dummy called" ); @@ -1797,6 +1802,11 @@ short FormulaTypedDoubleToken::GetDoubleType() const return mnType; } +void FormulaTypedDoubleToken::SetDoubleType( short nType ) +{ + mnType = nType; +} + bool FormulaTypedDoubleToken::operator==( const FormulaToken& r ) const { return FormulaDoubleToken::operator==( r ) && mnType == r.GetDoubleType(); diff --git a/include/formula/token.hxx b/include/formula/token.hxx index 9b06ae48182c..3de7c761d658 100644 --- a/include/formula/token.hxx +++ b/include/formula/token.hxx @@ -181,6 +181,7 @@ public: virtual double GetDouble() const; virtual double& GetDoubleAsReference(); virtual short GetDoubleType() const; + virtual void SetDoubleType( short nType ); virtual svl::SharedString GetString() const; virtual void SetString( const svl::SharedString& rStr ); virtual sal_uInt16 GetIndex() const; @@ -321,6 +322,7 @@ public: virtual FormulaToken* Clone() const override { return new FormulaTypedDoubleToken(*this); } virtual short GetDoubleType() const override; + virtual void SetDoubleType( short nType ) override; virtual bool operator==( const FormulaToken& rToken ) const override; DECL_FIXEDMEMPOOL_NEWDEL_DLL( FormulaTypedDoubleToken ) diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 8a240e617261..a6eaf5cd78ae 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -97,6 +97,7 @@ class SharedStringPool; } #define MAXSTACK (4096 / sizeof(formula::FormulaToken*)) +#define TOKEN_CACHE_SIZE 8 class ScTokenStack { @@ -229,6 +230,8 @@ private: bool bMatrixFormula; // formula cell is a matrix formula VolatileType meVolatileType; + size_t mnTokenCachePos; + std::vector<formula::FormulaToken*> maTokenCache; /// Merge global and document specific settings. void MergeCalcConfig(); @@ -395,6 +398,7 @@ private: sc::RangeMatrix PopRangeMatrix(); void QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr, sal_uLong& rRetIndexExpr); + formula::FormulaToken* CreateFormulaDoubleToken( double fVal, short nFmt = css::util::NumberFormat::NUMBER ); formula::FormulaToken* CreateDoubleOrTypedToken( double fVal ); void PushDouble(double nVal); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 73e91cfb6271..9ce2d00dde17 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -731,7 +731,7 @@ void ScInterpreter::PushCellResultToken( bool bDisplayEmptyAsString, { TreatDoubleError( fVal); if (!IfErrorPushError()) - PushTempTokenWithoutError( new FormulaDoubleToken( fVal)); + PushTempTokenWithoutError( CreateFormulaDoubleToken( fVal)); } else { @@ -1687,7 +1687,7 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr { if ( xMat->IsEmptyPath( 0, 0)) { // result of empty FALSE jump path - FormulaTokenRef xRes = new FormulaDoubleToken( 0.0); + FormulaTokenRef xRes = CreateFormulaDoubleToken( 0.0); PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get())); rRetTypeExpr = css::util::NumberFormat::LOGICAL; } @@ -1716,7 +1716,7 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr if (nErr != FormulaError::NONE) xRes = new FormulaErrorToken( nErr); else - xRes = new FormulaDoubleToken( nMatVal.fVal); + xRes = CreateFormulaDoubleToken( nMatVal.fVal); PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get())); if ( rRetTypeExpr != css::util::NumberFormat::LOGICAL ) rRetTypeExpr = css::util::NumberFormat::NUMBER; @@ -1728,14 +1728,42 @@ void ScInterpreter::QueryMatrixType(const ScMatrixRef& xMat, short& rRetTypeExpr SetError( FormulaError::UnknownStackVariable); } +formula::FormulaToken* ScInterpreter::CreateFormulaDoubleToken( double fVal, short nFmt ) +{ + if ( maTokenCache.size() != TOKEN_CACHE_SIZE ) + maTokenCache.resize( TOKEN_CACHE_SIZE ); + + // Find a spare token + for ( auto p : maTokenCache ) + { + if (p && p->GetRef() == 1) + { + p->IncRef(); + p->GetDoubleAsReference() = fVal; + p->SetDoubleType( nFmt ); + return p; + } + } + + // Allocate a new token + auto p = new FormulaTypedDoubleToken( fVal, nFmt ); + size_t pos = (mnTokenCachePos++) % TOKEN_CACHE_SIZE; + if ( maTokenCache[pos] ) + maTokenCache[pos]->DecRef(); + maTokenCache[pos] = p; + p->IncRef(); + + return p; +} + formula::FormulaToken* ScInterpreter::CreateDoubleOrTypedToken( double fVal ) { // NumberFormat::NUMBER is the default untyped double. if (nFuncFmtType && nFuncFmtType != css::util::NumberFormat::NUMBER && nFuncFmtType != css::util::NumberFormat::UNDEFINED) - return new FormulaTypedDoubleToken( fVal, nFuncFmtType); + return CreateFormulaDoubleToken( fVal, nFuncFmtType); else - return new FormulaDoubleToken( fVal); + return CreateFormulaDoubleToken( fVal); } void ScInterpreter::PushDouble(double nVal) @@ -3843,6 +3871,11 @@ ScInterpreter::~ScInterpreter() else delete pStackObj; delete pTokenMatrixMap; + + for ( auto p : maTokenCache ) + if ( p && p->GetRef() == 1 ) + p->DecRef(); + } ScCalcConfig& ScInterpreter::GetOrCreateGlobalConfig() @@ -4584,7 +4617,7 @@ StackVar ScInterpreter::Interpret() nRetIndexExpr = 0; // carry format index only for matching type nRetTypeExpr = nFuncFmtType = nCurFmtType; } - PushTempToken( new FormulaDoubleToken( fVal)); + PushTempToken( CreateFormulaDoubleToken( fVal)); } if ( nFuncFmtType == css::util::NumberFormat::UNDEFINED ) { |