[Libreoffice-commits] core.git: Branch 'feature/calc-parallel' - formula/source include/formula sc/source

Dennis Francis dennis.francis at collabora.co.uk
Wed Nov 15 15:50:09 UTC 2017


 formula/source/core/api/token.cxx |   10 ++++++++
 include/formula/token.hxx         |    2 +
 sc/source/core/inc/interpre.hxx   |    4 +++
 sc/source/core/tool/interpr4.cxx  |   45 ++++++++++++++++++++++++++++++++------
 4 files changed, 55 insertions(+), 6 deletions(-)

New commits:
commit 177c53949d6ec0a285d11a1e30514644ae9dbdf4
Author: Dennis Francis <dennis.francis at collabora.co.uk>
Date:   Wed Nov 15 21:08:44 2017 +0530

    cache FormulaToken for doubles
    
    Change-Id: Ic0b4dff6f03ef3f88bd150e798fa2d83dfb0f486

diff --git a/formula/source/core/api/token.cxx b/formula/source/core/api/token.cxx
index 4a4126904691..bba921d98539 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -215,6 +215,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" );
@@ -1796,6 +1801,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 9c754c2e9386..2ee692f1bc10 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 e62610b1d50b..68ec8df0bcb8 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)
@@ -3842,6 +3870,11 @@ ScInterpreter::~ScInterpreter()
     else
         delete pStackObj;
     delete pTokenMatrixMap;
+
+    for ( auto p : maTokenCache )
+        if ( p && p->GetRef() == 1 )
+            p->DecRef();
+
 }
 
 ScCalcConfig& ScInterpreter::GetOrCreateGlobalConfig()
@@ -4583,7 +4616,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 )
                         {


More information about the Libreoffice-commits mailing list