summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorPierre-Eric Pelloux-Prayer <pierre-eric@lanedo.com>2013-08-16 16:28:54 +0200
committerPetr Mladek <pmladek@suse.cz>2013-08-19 16:07:05 +0000
commite5d9477e87837fb771cf6dcb3bde872873bc50a8 (patch)
tree6c014d7fe8b64d1873508f8d4ba35e5e0ccfff76 /sc
parentda40cdd0e8a2a4ce2b3636f39c91b7129f1a6ed4 (diff)
sc/externalrefmgr: batch same-type cells copy
Change-Id: I5726261c9fbe479e2b5be6862324d23a30d4ab40 Reviewed-on: https://gerrit.libreoffice.org/5452 Reviewed-by: Petr Mladek <pmladek@suse.cz> Tested-by: Petr Mladek <pmladek@suse.cz>
Diffstat (limited to 'sc')
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx81
1 files changed, 73 insertions, 8 deletions
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 9c40b8ea2f8c..8ab55db2a17d 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -1301,6 +1301,68 @@ static FormulaToken* convertToToken( ScRefCellValue& rCell )
return NULL;
}
+template<class T>
+struct ColumnBatch
+{
+ std::vector<T> maStorage;
+ CellType meType1;
+ CellType meType2;
+ SCROW mnRowStart;
+
+ ColumnBatch(CellType eType1, CellType eType2) :
+ meType1(eType1), meType2(eType2), mnRowStart(-1) {}
+
+ void update(ScRefCellValue& raCell, const SCCOL nCol, const SCROW nRow, ScMatrixRef& xMat)
+ {
+ if (raCell.meType == meType1 || raCell.meType == meType2)
+ {
+ if (mnRowStart < 0)
+ mnRowStart = nRow;
+ maStorage.push_back(getValue(raCell));
+ }
+ else
+ {
+ flush(nCol, xMat);
+ }
+ }
+
+ void flush(const SCCOL nCol, ScMatrixRef& xMat)
+ {
+ if (maStorage.empty())
+ return;
+ putValues(xMat, nCol);
+ mnRowStart = -1;
+ maStorage.clear();
+ }
+
+ T getValue(ScRefCellValue& raCell) const;
+ void putValues(ScMatrixRef& xMat, const SCCOL nCol) const;
+};
+
+template<>
+inline OUString ColumnBatch<OUString>::getValue(ScRefCellValue& raCell) const
+{
+ return raCell.getString(NULL);
+}
+
+template<class T>
+inline T ColumnBatch<T>::getValue(ScRefCellValue& raCell) const
+{
+ return raCell.mfValue;
+}
+
+template<>
+inline void ColumnBatch<OUString>::putValues(ScMatrixRef& xMat, const SCCOL nCol) const
+{
+ xMat->PutString(maStorage.data(), maStorage.size(), nCol, mnRowStart);
+}
+
+template<class T>
+inline void ColumnBatch<T>::putValues(ScMatrixRef& xMat, const SCCOL nCol) const
+{
+ xMat->PutDouble(maStorage.data(), maStorage.size(), nCol, mnRowStart);
+}
+
static ScTokenArray* convertToTokenArray(
ScDocument* pSrcDoc, ScRange& rRange, vector<ScExternalRefCache::SingleRangeData>& rCacheData )
{
@@ -1348,27 +1410,27 @@ static ScTokenArray* convertToTokenArray(
static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1));
ScRefCellValue aCell;
+ ColumnBatch<OUString> stringBatch(CELLTYPE_STRING, CELLTYPE_EDIT);
+ ColumnBatch<double> doubleBatch(CELLTYPE_VALUE, CELLTYPE_VALUE);
+
for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
{
+ const SCSIZE nC = nCol - nCol1;
for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
{
- SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
+ const SCSIZE nR = nRow - nRow1;
aCell.assign(*pSrcDoc, ScAddress(nCol, nRow, nTab));
+ stringBatch.update(aCell, nC, nR, xMat);
+ doubleBatch.update(aCell, nC, nR, xMat);
+
if (aCell.hasEmptyValue())
// Skip empty cells. Matrix's default values are empty elements.
continue;
switch (aCell.meType)
{
- case CELLTYPE_EDIT:
- case CELLTYPE_STRING:
- xMat->PutString(aCell.getString(NULL), nC, nR);
- break;
- case CELLTYPE_VALUE:
- xMat->PutDouble(aCell.mfValue, nC, nR);
- break;
case CELLTYPE_FORMULA:
{
ScFormulaCell* pFCell = aCell.mpFormula;
@@ -1391,6 +1453,9 @@ static ScTokenArray* convertToTokenArray(
OSL_FAIL("attempted to convert an unknown cell type.");
}
}
+
+ stringBatch.flush(nC, xMat);
+ doubleBatch.flush(nC, xMat);
}
if (!bFirstTab)
pArray->AddOpCode(ocSep);