[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - configure.ac download.lst external/mdds sc/inc sc/source

Eike Rathke erack at redhat.com
Wed Jan 8 10:45:58 PST 2014


 configure.ac                                           |    2 
 download.lst                                           |    2 
 external/mdds/0001-Workaround-for-an-old-gcc-bug.patch |   27 ---
 external/mdds/UnpackedTarball_mdds.mk                  |    1 
 sc/inc/scmatrix.hxx                                    |   12 +
 sc/source/core/inc/jumpmatrix.hxx                      |   31 ++++
 sc/source/core/tool/interpr1.cxx                       |   71 +++++-----
 sc/source/core/tool/jumpmatrix.cxx                     |  119 ++++++++++++++++-
 sc/source/core/tool/scmatrix.cxx                       |   78 +++++++++++
 9 files changed, 271 insertions(+), 72 deletions(-)

New commits:
commit e1023ab62a62bb76b73841c02e44eacaba699d0e
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Jan 7 15:47:43 2014 -0500

    resolved fdo#72929 buffer jump matrix' result matrix blocks
    
    Update mdds to 0.10.1, set it as the required baseline.
    
    Patch mdds to make available a method to empty multiple elements in one call.
    
    This is for multi_type_matrix.
    
    (cherry picked from commit 47a7565315dcfc4271c2b2c205225d914a1a5094)
    
    Update mdds to 0.10.1, set it as the required baseline.
    
    This update will obsolete two patches that were previously applied.
    
    (cherry picked from commit 12890dd7adfc70bc562bb2760084515cc1269a38)
    
    Conflicts:
    	download.lst
    
    resolved fdo#72929 buffer jump matrix' result matrix blocks
    
    (cherry picked from commit ae4dc8e0ea3b78d804d1022905501a56030073c0)
    
    Change-Id: I7b1fcf6b16b5addbb76078506536542cddede25f
    Reviewed-on: https://gerrit.libreoffice.org/7320
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    Tested-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/configure.ac b/configure.ac
index 637b3d9..41b1cba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8701,7 +8701,7 @@ AC_SUBST(SYSTEM_BOOST)
 dnl ===================================================================
 dnl Check for system mdds
 dnl ===================================================================
-libo_CHECK_SYSTEM_MODULE([mdds], [MDDS], [mdds >= 0.9.1])
+libo_CHECK_SYSTEM_MODULE([mdds], [MDDS], [mdds >= 0.10.1])
 
 dnl ===================================================================
 dnl Determine which hash container mdds shall use
diff --git a/download.lst b/download.lst
index aaa4da6..1cf4224 100644
--- a/download.lst
+++ b/download.lst
@@ -80,7 +80,7 @@ export LIBXML_TARBALL := 9c0cfef285d5c4a5c80d00904ddab380-libxml2-2.9.1.tar.gz
 export LIBXSLT_TARBALL := 9667bf6f9310b957254fdcf6596600b7-libxslt-1.1.28.tar.gz
 export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
 export MARIADB_TARBALL := 05f84c95b610c21c5fd510d10debcabf-mariadb-native-client-1.0.0.tar.bz2
-export MDDS_TARBALL := 8c853024fbcff39113d9285250dafc66-mdds_0.9.1.tar.bz2
+export MDDS_TARBALL := 01a380acfec23bf617117ce98e318f3d-mdds_0.10.1.tar.bz2
 export MYSQLCPPCONN_TARBALL := 0981bda6548a8c8233ffce2b6e4b2a23-mysql-connector-c++-1.1.0.tar.gz
 export MYTHES_TARBALL := 46e92b68e31e858512b680b3b61dc4c1-mythes-1.2.3.tar.gz
 export NEON_TARBALL := ff369e69ef0f0143beb5626164e87ae2-neon-0.29.5.tar.gz
diff --git a/external/mdds/0001-Workaround-for-an-old-gcc-bug.patch b/external/mdds/0001-Workaround-for-an-old-gcc-bug.patch
deleted file mode 100644
index 8529fbf..0000000
--- a/external/mdds/0001-Workaround-for-an-old-gcc-bug.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 3e3a5c483217fe05b5bd556bf1b2c6f3ec297cb1 Mon Sep 17 00:00:00 2001
-From: Kohei Yoshida <kohei.yoshida at gmail.com>
-Date: Sat, 22 Jun 2013 21:30:13 -0400
-Subject: [PATCH] Workaround for an old gcc bug.
-
-c.f. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44963
----
- include/mdds/multi_type_vector_types.hpp | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/include/mdds/multi_type_vector_types.hpp b/include/mdds/multi_type_vector_types.hpp
-index c4b2772..44af655 100644
---- a/include/mdds/multi_type_vector_types.hpp
-+++ b/c/d/include/mdds/multi_type_vector_types.hpp
-@@ -278,7 +278,8 @@ public:
- #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
-         d.reserve(d.size() + len);
- #endif
--        std::copy(its.first, its.second, std::back_inserter(d));
-+        for (; its.first != its.second; ++its.first)
-+            d.push_back(*its.first);
-     }
- 
-     static void assign_values_from_block(
--- 
-1.8.1.4
-
diff --git a/external/mdds/UnpackedTarball_mdds.mk b/external/mdds/UnpackedTarball_mdds.mk
index 1ccfc2a..387b8bc 100644
--- a/external/mdds/UnpackedTarball_mdds.mk
+++ b/external/mdds/UnpackedTarball_mdds.mk
@@ -15,7 +15,6 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,mdds,3))
 
 $(eval $(call gb_UnpackedTarball_add_patches,mdds,\
 	external/mdds/mdds_0.6.0.patch \
-	external/mdds/0001-Workaround-for-an-old-gcc-bug.patch \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 93105dd..1db1641 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -269,6 +269,18 @@ public:
     void FillDouble( double fVal,
             SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
 
+    /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
+    void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR );
+
+    /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
+    void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR );
+
+    /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
+    void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+
+    /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
+    void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+
     /** May be used before obtaining the double value of an element to avoid
         passing its NAN around.
         @ATTENTION: MUST NOT be used if the element is a string!
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index 30391f9..959a865 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -67,6 +67,29 @@ class ScJumpMatrix
     SCSIZE              nResMatRows;
     bool                bStarted;
 
+    // Buffer result ranges to be able to set a range of identically typed
+    // values at the result matrix in order to avoid multiple shrinks and
+    // growths of multi_type_vector segments, which is a major performance
+    // bottleneck, see fdo#72929
+    ::std::vector< svl::SharedString >  mvBufferStrings;
+    ::std::vector< double >             mvBufferDoubles;
+    SCSIZE                              mnBufferCol;
+    SCSIZE                              mnBufferRowStart;
+    SCSIZE                              mnBufferEmptyCount;
+    SCSIZE                              mnBufferEmptyPathCount;
+
+    enum BufferType
+    {
+        BUFFER_NONE,
+        BUFFER_DOUBLE,
+        BUFFER_STRING,
+        BUFFER_EMPTY,
+        BUFFER_EMPTYPATH
+    };
+
+    /** Flush different types or non-consecutive buffers. */
+    void FlushBufferOtherThan( BufferType eType, SCSIZE nC, SCSIZE nR );
+
     // not implemented, prevent usage
     ScJumpMatrix( const ScJumpMatrix& );
     ScJumpMatrix& operator=( const ScJumpMatrix& );
@@ -80,11 +103,17 @@ public:
     void SetAllJumps( double fBool, short nStart, short nNext, short nStop = SHRT_MAX );
     void SetJumpParameters( ScTokenVec* p );
     const ScTokenVec* GetJumpParameters() const;
-    ScMatrix* GetResultMatrix() const;
+    bool HasResultMatrix() const;
+    ScMatrix* GetResultMatrix();        ///< also applies pending buffered values
     void GetPos( SCSIZE& rCol, SCSIZE& rRow ) const;
     bool Next( SCSIZE& rCol, SCSIZE& rRow );
     void GetResMatDimensions( SCSIZE& rCols, SCSIZE& rRows );
     void SetNewResMat( SCSIZE nNewCols, SCSIZE nNewRows );
+
+    void PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR );
+    void PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR );
+    void PutResultEmpty( SCSIZE nC, SCSIZE nR );
+    void PutResultEmptyPath( SCSIZE nC, SCSIZE nR );
 };
 
 #endif // SC_JUMPMATRIX_HXX
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 19179a7..2a048ae 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -216,20 +216,20 @@ void ScInterpreter::ScIfJump()
     is the result matrix of a jump matrix. All arguments must be valid and are
     not checked. */
 static void lcl_storeJumpMatResult(
-    const ScMatrix* pMat, ScMatrix* pResMat, SCSIZE nC, SCSIZE nR )
+    const ScMatrix* pMat, ScJumpMatrix* pJumpMat, SCSIZE nC, SCSIZE nR )
 {
     if ( pMat->IsValue( nC, nR ) )
     {
         double fVal = pMat->GetDouble( nC, nR );
-        pResMat->PutDouble( fVal, nC, nR );
+        pJumpMat->PutResultDouble( fVal, nC, nR );
     }
     else if ( pMat->IsEmpty( nC, nR ) )
     {
-        pResMat->PutEmpty( nC, nR );
+        pJumpMat->PutResultEmpty( nC, nR );
     }
     else
     {
-        pResMat->PutString(pMat->GetString(nC, nR), nC, nR);
+        pJumpMat->PutResultString(pMat->GetString(nC, nR), nC, nR);
     }
 }
 
@@ -334,7 +334,6 @@ void ScInterpreter::ScIfError( bool bNAonly )
                 {
                     const ScMatrix* pMatPtr = pMat.get();
                     ScJumpMatrix* pJumpMat = new ScJumpMatrix( nCols, nRows );
-                    ScMatrix* pResMatPtr = pJumpMat->GetResultMatrix();
                     // Init all jumps to no error to save single calls. Error
                     // is the exceptional condition.
                     const double fFlagResult = CreateDoubleError( errJumpMatHasResult);
@@ -346,7 +345,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
                     {
                         for ( ; nR < nRows && (nC != nErrorCol || nR != nErrorRow); ++nR)
                         {
-                            lcl_storeJumpMatResult(pMatPtr, pResMatPtr, nC, nR);
+                            lcl_storeJumpMatResult(pMatPtr, pJumpMat, nC, nR);
                         }
                         if (nC != nErrorCol || nR != nErrorRow)
                             ++nC;
@@ -363,7 +362,7 @@ void ScInterpreter::ScIfError( bool bNAonly )
                             }
                             else
                             {   // FALSE, EMPTY path, store result instead
-                                lcl_storeJumpMatResult(pMatPtr, pResMatPtr, nC, nR);
+                                lcl_storeJumpMatResult(pMatPtr, pJumpMat, nC, nR);
                             }
                         }
                     }
@@ -492,7 +491,7 @@ void ScInterpreter::ScChoseJump()
         aCode.Jump( pJump[ nJumpCount ], pJump[ nJumpCount ] );
 }
 
-static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SCSIZE nParmCols, SCSIZE nParmRows )
+static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, SCSIZE nParmCols, SCSIZE nParmRows )
 {
     SCSIZE nJumpCols, nJumpRows;
     SCSIZE nResCols, nResRows;
@@ -518,14 +517,13 @@ static void lcl_AdjustJumpMatrix( ScJumpMatrix* pJumpM, ScMatrixRef& pResMat, SC
             nAdjustRows = nParmRows;
         }
         pJumpM->SetNewResMat( nAdjustCols, nAdjustRows );
-        pResMat = pJumpM->GetResultMatrix();
     }
 }
 
 bool ScInterpreter::JumpMatrix( short nStackLevel )
 {
     pJumpMatrix = static_cast<ScToken*>(pStack[sp-nStackLevel])->GetJumpMatrix();
-    ScMatrixRef pResMat = pJumpMatrix->GetResultMatrix();
+    bool bHasResMat = pJumpMatrix->HasResultMatrix();
     SCSIZE nC, nR;
     if ( nStackLevel == 2 )
     {
@@ -536,7 +534,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
             OSL_FAIL( "ScInterpreter::JumpMatrix: pop goes the weasel" );
         }
 
-        if ( !pResMat )
+        if ( !bHasResMat )
         {
             Pop();
             SetError( errUnknownStackVariable );
@@ -554,7 +552,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
                     }
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
                 break;
                 case svString:
@@ -562,12 +560,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     svl::SharedString aStr = GetString();
                     if ( nGlobalError )
                     {
-                        pResMat->PutDouble( CreateDoubleError( nGlobalError),
+                        pJumpMatrix->PutResultDouble( CreateDoubleError( nGlobalError),
                                 nC, nR);
                         nGlobalError = 0;
                     }
                     else
-                        pResMat->PutString(aStr, nC, nR);
+                        pJumpMatrix->PutResultString(aStr, nC, nR);
                 }
                 break;
                 case svSingleRef:
@@ -576,7 +574,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     PopSingleRef( aAdr );
                     if ( nGlobalError )
                     {
-                        pResMat->PutDouble( CreateDoubleError( nGlobalError),
+                        pJumpMatrix->PutResultDouble( CreateDoubleError( nGlobalError),
                                 nC, nR);
                         nGlobalError = 0;
                     }
@@ -585,7 +583,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                         ScRefCellValue aCell;
                         aCell.assign(*pDok, aAdr);
                         if (aCell.hasEmptyValue())
-                            pResMat->PutEmpty( nC, nR );
+                            pJumpMatrix->PutResultEmpty( nC, nR );
                         else if (aCell.hasNumeric())
                         {
                             double fVal = GetCellValue(aAdr, aCell);
@@ -595,7 +593,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                         nGlobalError);
                                 nGlobalError = 0;
                             }
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                         }
                         else
                         {
@@ -603,12 +601,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             GetCellString(aStr, aCell);
                             if ( nGlobalError )
                             {
-                                pResMat->PutDouble( CreateDoubleError(
+                                pJumpMatrix->PutResultDouble( CreateDoubleError(
                                             nGlobalError), nC, nR);
                                 nGlobalError = 0;
                             }
                             else
-                                pResMat->PutString(aStr, nC, nR);
+                                pJumpMatrix->PutResultString(aStr, nC, nR);
                         }
                     }
                 }
@@ -622,7 +620,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     {
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else
                     {
@@ -637,7 +635,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                     aRange.aEnd.Row() != aRange.aStart.Row()))
                           {
                             fVal = CreateDoubleError( NOTAVAILABLE );
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                           }
                           else
                           {
@@ -653,7 +651,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             ScRefCellValue aCell;
                             aCell.assign(*pDok, aAdr);
                             if (aCell.hasEmptyValue())
-                                pResMat->PutEmpty( nC, nR );
+                                pJumpMatrix->PutResultEmpty( nC, nR );
                             else if (aCell.hasNumeric())
                               {
                                 double fCellVal = GetCellValue(aAdr, aCell);
@@ -663,7 +661,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                             nGlobalError);
                                     nGlobalError = 0;
                                 }
-                                pResMat->PutDouble( fCellVal, nC, nR );
+                                pJumpMatrix->PutResultDouble( fCellVal, nC, nR );
                               }
                               else
                               {
@@ -671,17 +669,17 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                                 GetCellString(aStr, aCell);
                                 if ( nGlobalError )
                                 {
-                                    pResMat->PutDouble( CreateDoubleError(
+                                    pJumpMatrix->PutResultDouble( CreateDoubleError(
                                                 nGlobalError), nC, nR);
                                     nGlobalError = 0;
                                 }
                                 else
-                                    pResMat->PutString(aStr, nC, nR);
+                                    pJumpMatrix->PutResultString(aStr, nC, nR);
                             }
                           }
                         SCSIZE nParmCols = aRange.aEnd.Col() - aRange.aStart.Col() + 1;
                         SCSIZE nParmRows = aRange.aEnd.Row() - aRange.aStart.Row() + 1;
-                        lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nParmCols, nParmRows );
+                        lcl_AdjustJumpMatrix( pJumpMatrix, nParmCols, nParmRows );
                     }
                 }
                 break;
@@ -693,12 +691,12 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     {
                         fVal = CreateDoubleError( nGlobalError );
                         nGlobalError = 0;
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else if ( !pMat )
                     {
                         fVal = CreateDoubleError( errUnknownVariable );
-                        pResMat->PutDouble( fVal, nC, nR );
+                        pJumpMatrix->PutResultDouble( fVal, nC, nR );
                     }
                     else
                     {
@@ -708,13 +706,13 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                             (nRows <= nR && nRows != 1))
                         {
                             fVal = CreateDoubleError( NOTAVAILABLE );
-                            pResMat->PutDouble( fVal, nC, nR );
+                            pJumpMatrix->PutResultDouble( fVal, nC, nR );
                         }
                         else
                         {
-                            lcl_storeJumpMatResult(pMat.get(), pResMat.get(), nC, nR);
+                            lcl_storeJumpMatResult(pMat.get(), pJumpMatrix, nC, nR);
                         }
-                        lcl_AdjustJumpMatrix( pJumpMatrix, pResMat, nCols, nRows );
+                        lcl_AdjustJumpMatrix( pJumpMatrix, nCols, nRows );
                     }
                 }
                 break;
@@ -723,14 +721,14 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
                     PopError();
                     double fVal = CreateDoubleError( nGlobalError);
                     nGlobalError = 0;
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
                 break;
                 default:
                 {
                     Pop();
                     double fVal = CreateDoubleError( errIllegalArgument);
-                    pResMat->PutDouble( fVal, nC, nR );
+                    pJumpMatrix->PutResultDouble( fVal, nC, nR );
                 }
             }
         }
@@ -743,13 +741,13 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
         pJumpMatrix->GetJump( nC, nR, fBool, nStart, nNext, nStop );
         while ( bCont && nStart == nNext )
         {   // push all results that have no jump path
-            if ( pResMat && (GetDoubleErrorValue( fBool) != errJumpMatHasResult) )
+            if ( bHasResMat && (GetDoubleErrorValue( fBool) != errJumpMatHasResult) )
             {
                 // a false without path results in an empty path value
                 if ( fBool == 0.0 )
-                    pResMat->PutEmptyPath( nC, nR );
+                    pJumpMatrix->PutResultEmptyPath( nC, nR );
                 else
-                    pResMat->PutDouble( fBool, nC, nR );
+                    pJumpMatrix->PutResultDouble( fBool, nC, nR );
             }
             bCont = pJumpMatrix->Next( nC, nR );
             if ( bCont )
@@ -774,6 +772,7 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
     }
     if ( !bCont )
     {   // we're done with it, throw away jump matrix, keep result
+        ScMatrix* pResMat = pJumpMatrix->GetResultMatrix();
         pJumpMatrix = NULL;
         Pop();
         PushMatrix( pResMat );
diff --git a/sc/source/core/tool/jumpmatrix.cxx b/sc/source/core/tool/jumpmatrix.cxx
index 6a8b4a7..adac4f6 100644
--- a/sc/source/core/tool/jumpmatrix.cxx
+++ b/sc/source/core/tool/jumpmatrix.cxx
@@ -20,6 +20,11 @@
 #include "jumpmatrix.hxx"
 #include "scmatrix.hxx"
 
+namespace {
+// Don't bother with buffer overhead for less than y rows.
+const SCSIZE kBufferThreshhold = 128;
+}
+
 ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
     : pJump(new ScJumpMatrixEntry[nColsP * nRowsP])
     , pMat(new ScMatrix(nColsP, nRowsP))
@@ -31,6 +36,10 @@ ScJumpMatrix::ScJumpMatrix(SCSIZE nColsP, SCSIZE nRowsP)
     , nResMatCols(nColsP)
     , nResMatRows(nRowsP)
     , bStarted(false)
+    , mnBufferCol(0)
+    , mnBufferRowStart(0)
+    , mnBufferEmptyCount(0)
+    , mnBufferEmptyPathCount(0)
 {
     // Initialize result matrix in case of
     // a premature end of the interpreter
@@ -106,11 +115,6 @@ const ScTokenVec* ScJumpMatrix::GetJumpParameters() const
     return pParams;
 }
 
-ScMatrix* ScJumpMatrix::GetResultMatrix() const
-{
-    return pMat.get();
-}
-
 void ScJumpMatrix::GetPos(SCSIZE& rCol, SCSIZE& rRow) const
 {
     rCol = nCurCol;
@@ -146,6 +150,7 @@ void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows)
 {
     if (nNewCols > nResMatCols || nNewRows > nResMatRows)
     {
+        FlushBufferOtherThan( BUFFER_NONE, 0, 0);
         pMat = pMat->CloneAndExtend(nNewCols, nNewRows);
         if (nResMatCols < nNewCols)
         {
@@ -169,5 +174,109 @@ void ScJumpMatrix::SetNewResMat(SCSIZE nNewCols, SCSIZE nNewRows)
     }
 }
 
+bool ScJumpMatrix::HasResultMatrix() const
+{
+    // We now always have a matrix but caller logic may still want to check it.
+    return pMat.get() != NULL;
+}
+
+void ScJumpMatrix::FlushBufferOtherThan( ScJumpMatrix::BufferType eType, SCSIZE nC, SCSIZE nR )
+{
+    if (!mvBufferDoubles.empty() &&
+            (eType != BUFFER_DOUBLE || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferDoubles.size()))
+    {
+        pMat->PutDoubleVector( mvBufferDoubles, mnBufferCol, mnBufferRowStart);
+        mvBufferDoubles.clear();
+    }
+    if (!mvBufferStrings.empty() &&
+            (eType != BUFFER_STRING || nC != mnBufferCol || nR != mnBufferRowStart + mvBufferStrings.size()))
+    {
+        pMat->PutStringVector( mvBufferStrings, mnBufferCol, mnBufferRowStart);
+        mvBufferStrings.clear();
+    }
+    if (mnBufferEmptyCount &&
+            (eType != BUFFER_EMPTY || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyCount))
+    {
+        pMat->PutEmptyVector( mnBufferEmptyCount, mnBufferCol, mnBufferRowStart);
+        mnBufferEmptyCount = 0;
+    }
+    if (mnBufferEmptyPathCount &&
+            (eType != BUFFER_EMPTYPATH || nC != mnBufferCol || nR != mnBufferRowStart + mnBufferEmptyPathCount))
+    {
+        pMat->PutEmptyPathVector( mnBufferEmptyPathCount, mnBufferCol, mnBufferRowStart);
+        mnBufferEmptyPathCount = 0;
+    }
+}
+
+ScMatrix* ScJumpMatrix::GetResultMatrix()
+{
+    if (nResMatRows >= kBufferThreshhold)
+        FlushBufferOtherThan( BUFFER_NONE, 0, 0);
+    return pMat.get();
+}
+
+void ScJumpMatrix::PutResultDouble( double fVal, SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutDouble( fVal, nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_DOUBLE, nC, nR);
+        if (mvBufferDoubles.empty())
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        mvBufferDoubles.push_back( fVal);
+    }
+}
+
+void ScJumpMatrix::PutResultString( const svl::SharedString& rStr, SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutString( rStr, nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_STRING, nC, nR);
+        if (mvBufferStrings.empty())
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        mvBufferStrings.push_back( rStr);
+    }
+}
+
+void ScJumpMatrix::PutResultEmpty( SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutEmpty( nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_EMPTY, nC, nR);
+        if (!mnBufferEmptyCount)
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        ++mnBufferEmptyCount;
+    }
+}
+
+void ScJumpMatrix::PutResultEmptyPath( SCSIZE nC, SCSIZE nR )
+{
+    if (nResMatRows < kBufferThreshhold)
+        pMat->PutEmptyPath( nC, nR);
+    else
+    {
+        FlushBufferOtherThan( BUFFER_EMPTYPATH, nC, nR);
+        if (!mnBufferEmptyPathCount)
+        {
+            mnBufferCol = nC;
+            mnBufferRowStart = nR;
+        }
+        ++mnBufferEmptyPathCount;
+    }
+}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 1a5ebbb..132923d 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -252,6 +252,10 @@ public:
     void MatCopy(ScMatrixImpl& mRes) const;
     void MatTrans(ScMatrixImpl& mRes) const;
     void FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSIZE nR2 );
+    void PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR );
+    void PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR );
+    void PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
+    void PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR );
     void CompareEqual();
     void CompareNotEqual();
     void CompareLess();
@@ -764,6 +768,60 @@ void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2,
     }
 }
 
+void ScMatrixImpl::PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    if (!rVec.empty() && ValidColRow( nC, nR) && ValidColRow( nC, nR + rVec.size() - 1))
+    {
+        maMat.set(nR, nC, rVec.begin(), rVec.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutDoubleVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    if (!rVec.empty() && ValidColRow( nC, nR) && ValidColRow( nC, nR + rVec.size() - 1))
+    {
+        maMat.set(nR, nC, rVec.begin(), rVec.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutStringVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    if (nCount && ValidColRow( nC, nR) && ValidColRow( nC, nR + nCount - 1))
+    {
+        maMat.set_empty(nR, nC, nCount);
+        // zero flag to indicate that this is 'empty', not 'empty path'.
+        std::vector<bool> aVals(nCount, false);
+        maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutEmptyVector: dimension error");
+    }
+}
+
+void ScMatrixImpl::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    if (nCount && ValidColRow( nC, nR) && ValidColRow( nC, nR + nCount - 1))
+    {
+        maMat.set_empty(nR, nC, nCount);
+        // non-zero flag to indicate empty 'path'.
+        std::vector<bool> aVals(nCount, true);
+        maMatFlag.set(nR, nC, aVals.begin(), aVals.end());
+    }
+    else
+    {
+        OSL_FAIL("ScMatrixImpl::PutEmptyPathVector: dimension error");
+    }
+}
+
 void ScMatrixImpl::CompareEqual()
 {
     MatrixImplType::size_pair_type aSize = maMat.size();
@@ -2032,6 +2090,26 @@ void ScMatrix::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2, SCSI
     pImpl->FillDouble(fVal, nC1, nR1, nC2, nR2);
 }
 
+void ScMatrix::PutDoubleVector( const ::std::vector< double > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutDoubleVector(rVec, nC, nR);
+}
+
+void ScMatrix::PutStringVector( const ::std::vector< svl::SharedString > & rVec, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutStringVector(rVec, nC, nR);
+}
+
+void ScMatrix::PutEmptyVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutEmptyVector(nCount, nC, nR);
+}
+
+void ScMatrix::PutEmptyPathVector( SCSIZE nCount, SCSIZE nC, SCSIZE nR )
+{
+    pImpl->PutEmptyPathVector(nCount, nC, nR);
+}
+
 void ScMatrix::CompareEqual()
 {
     pImpl->CompareEqual();


More information about the Libreoffice-commits mailing list