formula/source/core/api/token.cxx   |   29 +++++++++++++++
 include/formula/tokenarray.hxx      |    3 +
 sc/inc/tokenarray.hxx               |    3 +
 sc/source/core/tool/token.cxx       |   69 ++++++++++++++++++++++++++++++++++++
 sc/source/filter/excel/namebuff.cxx |    8 ++--
 sc/source/filter/inc/namebuff.hxx   |    5 +-
 6 files changed, 110 insertions(+), 7 deletions(-)

New commits:
commit 45b17d9d5bf98aefba392da6271c7077c1363238
Author:     Noel Grandin <noelgran...@gmail.com>
AuthorDate: Sat Sep 4 09:02:15 2021 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Sep 4 14:03:19 2021 +0200

    store ScTokenArray by value in SharedFormulaBuffer
    
    Change-Id: Ibff3c2fea3cadc234266953ab15ae5f25c4ac1e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121626
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/formula/source/core/api/token.cxx 
b/formula/source/core/api/token.cxx
index c5b69acf2c90..89ae03162778 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -598,6 +598,11 @@ FormulaTokenArray::FormulaTokenArray( const 
FormulaTokenArray& rArr )
     Assign( rArr );
 }
 
+FormulaTokenArray::FormulaTokenArray( FormulaTokenArray&& rArr )
+{
+    Move( std::move(rArr) );
+}
+
 FormulaTokenArray::~FormulaTokenArray()
 {
     FormulaTokenArray::Clear();
@@ -646,6 +651,23 @@ void FormulaTokenArray::Assign( const FormulaTokenArray& r 
)
     }
 }
 
+void FormulaTokenArray::Move( FormulaTokenArray&& r )
+{
+    pCode  = std::move(r.pCode);
+    pRPN   = r.pRPN;
+    r.pRPN = nullptr;
+    nLen   = r.nLen;
+    r.nLen = 0;
+    nRPN   = r.nRPN;
+    r.nRPN = 0;
+    nError = r.nError;
+    nMode  = r.nMode;
+    bHyperLink = r.bHyperLink;
+    mbFromRangeName = r.mbFromRangeName;
+    mbShareable = r.mbShareable;
+    mbFinalized = r.mbFinalized;
+}
+
 /// Optimisation for efficiently creating StringXML placeholders
 void FormulaTokenArray::Assign( sal_uInt16 nCode, FormulaToken **pTokens )
 {
@@ -675,6 +697,13 @@ FormulaTokenArray& FormulaTokenArray::operator=( const 
FormulaTokenArray& rArr )
     return *this;
 }
 
+FormulaTokenArray& FormulaTokenArray::operator=( FormulaTokenArray&& rArr )
+{
+    Clear();
+    Move( std::move(rArr) );
+    return *this;
+}
+
 void FormulaTokenArray::Clear()
 {
     if( nRPN ) DelRPN();
diff --git a/include/formula/tokenarray.hxx b/include/formula/tokenarray.hxx
index 87377cb228e0..6b373ff44e15 100644
--- a/include/formula/tokenarray.hxx
+++ b/include/formula/tokenarray.hxx
@@ -248,6 +248,7 @@ protected:
 protected:
     void                    Assign( const FormulaTokenArray& );
     void                    Assign( sal_uInt16 nCode, FormulaToken **pTokens );
+    void                    Move( FormulaTokenArray&& );
 
     /// Also used by the compiler. The token MUST had been allocated with new!
     FormulaToken*           Add( FormulaToken* );
@@ -289,6 +290,7 @@ public:
     /** Assignment with incrementing references of FormulaToken entries
         (not copied!) */
     FormulaTokenArray( const FormulaTokenArray& );
+    FormulaTokenArray( FormulaTokenArray&& );
     virtual ~FormulaTokenArray();
 
     virtual void Clear();
@@ -485,6 +487,7 @@ public:
     /** Assignment with incrementing references of FormulaToken entries
         (not copied!) */
     FormulaTokenArray& operator=( const FormulaTokenArray& );
+    FormulaTokenArray& operator=( FormulaTokenArray&& );
 
     /** Determines if this formula needs any changes to convert it to something
         previous versions of OOo could consume (Plain Old Formula, pre-ODFF, or
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 401ecb392239..0592521901b3 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -66,12 +66,14 @@ public:
     /** Assignment with incrementing references of FormulaToken entries
         (not copied!) */
     ScTokenArray( const ScTokenArray& ) = default;
+    ScTokenArray( ScTokenArray&& ) = default;
     virtual ~ScTokenArray() override;
 
     bool EqualTokens( const ScTokenArray* pArr2 ) const;
 
     virtual void Clear() override;
     std::unique_ptr<ScTokenArray> Clone() const;    /// True copy!
+    ScTokenArray CloneValue() const;    /// True copy!
 
     void GenHash();
     size_t GetHash() const { return mnHashValue;}
@@ -130,6 +132,7 @@ public:
     /** Assignment with incrementing references of FormulaToken entries
         (not copied!) */
     ScTokenArray& operator=( const ScTokenArray& );
+    ScTokenArray& operator=( ScTokenArray&& );
 
     /**
      * Make all absolute references external references pointing to the old 
document
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 6c4c80a8fb03..9fc32499731d 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1892,6 +1892,17 @@ ScTokenArray& ScTokenArray::operator=( const 
ScTokenArray& rArr )
     return *this;
 }
 
+ScTokenArray& ScTokenArray::operator=( ScTokenArray&& rArr )
+{
+    mxSheetLimits = std::move(rArr.mxSheetLimits);
+    mnHashValue = rArr.mnHashValue;
+    meVectorState = rArr.meVectorState;
+    mbOpenCLEnabled = rArr.mbOpenCLEnabled;
+    mbThreadingEnabled = rArr.mbThreadingEnabled;
+    Move(std::move(rArr));
+    return *this;
+}
+
 bool ScTokenArray::EqualTokens( const ScTokenArray* pArr2) const
 {
     // We only compare the non-RPN array
@@ -1974,6 +1985,64 @@ std::unique_ptr<ScTokenArray> ScTokenArray::Clone() const
     return p;
 }
 
+ScTokenArray ScTokenArray::CloneValue() const
+{
+    ScTokenArray aNew(*mxSheetLimits);
+    aNew.nLen = nLen;
+    aNew.nRPN = nRPN;
+    aNew.nMode = nMode;
+    aNew.nError = nError;
+    aNew.bHyperLink = bHyperLink;
+    aNew.mnHashValue = mnHashValue;
+    aNew.meVectorState = meVectorState;
+    aNew.mbOpenCLEnabled = mbOpenCLEnabled;
+    aNew.mbThreadingEnabled = mbThreadingEnabled;
+    aNew.mbFromRangeName = mbFromRangeName;
+    aNew.mbShareable = mbShareable;
+
+    FormulaToken** pp;
+    if( nLen )
+    {
+        aNew.pCode.reset(new FormulaToken*[ nLen ]);
+        pp = aNew.pCode.get();
+        memcpy( pp, pCode.get(), nLen * sizeof( formula::FormulaToken* ) );
+        for( sal_uInt16 i = 0; i < nLen; i++, pp++ )
+        {
+            *pp = (*pp)->Clone();
+            (*pp)->IncRef();
+        }
+    }
+    if( nRPN )
+    {
+        pp = aNew.pRPN = new FormulaToken*[ nRPN ];
+        memcpy( pp, pRPN, nRPN * sizeof( formula::FormulaToken* ) );
+        for( sal_uInt16 i = 0; i < nRPN; i++, pp++ )
+        {
+            FormulaToken* t = *pp;
+            if( t->GetRef() > 1 )
+            {
+                FormulaToken** p2 = pCode.get();
+                sal_uInt16 nIdx = 0xFFFF;
+                for( sal_uInt16 j = 0; j < nLen; j++, p2++ )
+                {
+                    if( *p2 == t )
+                    {
+                        nIdx = j; break;
+                    }
+                }
+                if( nIdx == 0xFFFF )
+                    *pp = t->Clone();
+                else
+                    *pp = aNew.pCode[ nIdx ];
+            }
+            else
+                *pp = t->Clone();
+            (*pp)->IncRef();
+        }
+    }
+    return aNew;
+}
+
 FormulaToken* ScTokenArray::AddRawToken( const ScRawToken& r )
 {
     return Add( r.CreateToken(*mxSheetLimits) );
diff --git a/sc/source/filter/excel/namebuff.cxx 
b/sc/source/filter/excel/namebuff.cxx
index 5b3157a6dffe..52314520976b 100644
--- a/sc/source/filter/excel/namebuff.cxx
+++ b/sc/source/filter/excel/namebuff.cxx
@@ -62,9 +62,9 @@ void SharedFormulaBuffer::Clear()
 
 void SharedFormulaBuffer::Store( const ScAddress& rPos, const ScTokenArray& 
rArray )
 {
-    std::unique_ptr<ScTokenArray> xCode(rArray.Clone());
-    xCode->GenHash();
-    maTokenArrays.emplace(rPos, std::move(xCode));
+    ScTokenArray aCode(rArray.CloneValue());
+    aCode.GenHash();
+    maTokenArrays.emplace(rPos, std::move(aCode));
 }
 
 const ScTokenArray* SharedFormulaBuffer::Find( const ScAddress& rRefPos ) const
@@ -73,7 +73,7 @@ const ScTokenArray* SharedFormulaBuffer::Find( const 
ScAddress& rRefPos ) const
     if (it == maTokenArrays.end())
         return nullptr;
 
-    return it->second.get();
+    return &it->second;
 }
 
 sal_Int16 ExtSheetBuffer::Add( const OUString& rFPAN, const OUString& rTN, 
const bool bSWB )
diff --git a/sc/source/filter/inc/namebuff.hxx 
b/sc/source/filter/inc/namebuff.hxx
index 26cc5585f38d..24ff4dc395bd 100644
--- a/sc/source/filter/inc/namebuff.hxx
+++ b/sc/source/filter/inc/namebuff.hxx
@@ -26,11 +26,10 @@
 #include "root.hxx"
 #include "xiroot.hxx"
 #include <refdata.hxx>
+#include <tokenarray.hxx>
 
 #include <unordered_map>
 
-class ScTokenArray;
-
 class StringHashEntry
 {
 private:
@@ -59,7 +58,7 @@ inline bool StringHashEntry::operator ==( const 
StringHashEntry& r ) const
  */
 class SharedFormulaBuffer : public ExcRoot
 {
-    typedef std::unordered_map<ScAddress, std::unique_ptr<ScTokenArray>, 
ScAddressHashFunctor> TokenArraysType;
+    typedef std::unordered_map<ScAddress, ScTokenArray, ScAddressHashFunctor> 
TokenArraysType;
     TokenArraysType maTokenArrays;
 
 public:

Reply via email to