Kaydet (Commit) 4b3e4c1c authored tarafından Dennis Francis's avatar Dennis Francis

cache FormulaToken for doubles

Change-Id: Ic0b4dff6f03ef3f88bd150e798fa2d83dfb0f486
üst 9c88d6f2
......@@ -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();
......
......@@ -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 )
......
......@@ -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);
......
......@@ -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 )
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment