diff options
author | Eike Rathke <erack@redhat.com> | 2014-01-07 15:47:43 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-01-11 16:02:53 +0000 |
commit | b7adbad0176da2528229d2ea166b5ae58ef18649 (patch) | |
tree | f35db308092c495bee00d74adf8def4f3e556212 | |
parent | cfb3455bba641f43178abd2600ffc57b05930bf6 (diff) |
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/7321
Reviewed-by: Kohei Yoshida <libreoffice@kohei.us>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | download.lst | 2 | ||||
-rw-r--r-- | external/mdds/0001-Workaround-for-an-old-gcc-bug.patch | 27 | ||||
-rw-r--r-- | external/mdds/UnpackedTarball_mdds.mk | 1 | ||||
-rw-r--r-- | sc/inc/scmatrix.hxx | 12 | ||||
-rw-r--r-- | sc/source/core/inc/jumpmatrix.hxx | 31 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 71 | ||||
-rw-r--r-- | sc/source/core/tool/jumpmatrix.cxx | 119 | ||||
-rw-r--r-- | sc/source/core/tool/scmatrix.cxx | 78 |
9 files changed, 271 insertions, 72 deletions
diff --git a/configure.ac b/configure.ac index 3fbc362b6e6d..2094c194045c 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 aaa4da665183..1cf422496ebd 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 8529fbfc2adf..000000000000 --- 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@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 1ccfc2a85f3d..387b8bcfacf9 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 93105dd316df..1db16417d7da 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 30391f94b016..959a86516c62 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 19179a70505b..2a048ae90a0a 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 6a8b4a72fb2d..adac4f68f6a3 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 1a5ebbbdafc4..132923decf7e 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(); |