Kaydet (Commit) 4de4f1fd authored tarafından László Németh's avatar László Németh

tdf#89436 fix ScHorizontalAttrIterator performance

Change-Id: I69be1a85b74ede8f02788a6370d4ebb40bddbe11
üst 4ed53dff
...@@ -487,11 +487,14 @@ private: ...@@ -487,11 +487,14 @@ private:
SCROW nEndRow; SCROW nEndRow;
SCROW* pNextEnd; SCROW* pNextEnd;
SCCOL* pPrevColEnd;
SCSIZE* pIndices; SCSIZE* pIndices;
const ScPatternAttr** ppPatterns; const ScPatternAttr** ppPatterns;
SCCOL nCol; SCCOL nCol;
SCROW nRow; SCROW nRow;
bool bRowEmpty; bool bRowEmpty;
bool bRepeatedRow;
SCROW nMinNextEnd;
public: public:
ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable, ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
......
...@@ -2235,12 +2235,14 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB ...@@ -2235,12 +2235,14 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
nRow = nStartRow; nRow = nStartRow;
nCol = nStartCol; nCol = nStartCol;
bRowEmpty = false; bRowEmpty = false;
bRepeatedRow = false;
pIndices = new SCSIZE[nEndCol-nStartCol+1]; pIndices = new SCSIZE[nEndCol-nStartCol+1];
pNextEnd = new SCROW[nEndCol-nStartCol+1]; pNextEnd = new SCROW[nEndCol-nStartCol+1];
pPrevColEnd = new SCCOL[nEndCol-nStartCol+1];
ppPatterns = new const ScPatternAttr*[nEndCol-nStartCol+1]; ppPatterns = new const ScPatternAttr*[nEndCol-nStartCol+1];
SCROW nSkipTo = MAXROW; nMinNextEnd = MAXROW;
bool bEmpty = true; bool bEmpty = true;
for (i=nStartCol; i<=nEndCol; i++) for (i=nStartCol; i<=nEndCol; i++)
{ {
...@@ -2253,12 +2255,12 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB ...@@ -2253,12 +2255,12 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern; const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
SCROW nThisEnd = pArray->pData[nIndex].nRow; SCROW nThisEnd = pArray->pData[nIndex].nRow;
if ( nThisEnd < nMinNextEnd )
nMinNextEnd = nThisEnd; // nMinNextEnd can be set here already
if ( IsDefaultItem( pPattern ) ) if ( IsDefaultItem( pPattern ) )
{
pPattern = NULL; pPattern = NULL;
if ( nThisEnd < nSkipTo )
nSkipTo = nThisEnd; // nSkipTo can be set here already
}
else else
bEmpty = false; // Found attributes bEmpty = false; // Found attributes
...@@ -2268,7 +2270,7 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB ...@@ -2268,7 +2270,7 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
} }
if (bEmpty) if (bEmpty)
nRow = nSkipTo; // Skip until end of next section nRow = nMinNextEnd; // Skip until end of next section
bRowEmpty = bEmpty; bRowEmpty = bEmpty;
} }
...@@ -2277,6 +2279,7 @@ ScHorizontalAttrIterator::~ScHorizontalAttrIterator() ...@@ -2277,6 +2279,7 @@ ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
{ {
delete[] ppPatterns; delete[] ppPatterns;
delete[] pNextEnd; delete[] pNextEnd;
delete[] pPrevColEnd;
delete[] pIndices; delete[] pIndices;
} }
...@@ -2297,8 +2300,15 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo ...@@ -2297,8 +2300,15 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol]; const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
rRow = nRow; rRow = nRow;
rCol1 = nCol; rCol1 = nCol;
while ( nCol < nEndCol && ppPatterns[nCol+1-nStartCol] == pPat ) if ( bRepeatedRow )
++nCol; nCol = pPrevColEnd[nCol];
else
{
while ( nCol < nEndCol && ( ppPatterns[nCol+1-nStartCol] == pPat) )
++nCol;
// store the result to avoid the previous very expensive comparisons
pPrevColEnd[rCol1] = nCol;
}
rCol2 = nCol; rCol2 = nCol;
++nCol; // Count up for next call ++nCol; // Count up for next call
return pPat; // Found it! return pPat; // Found it!
...@@ -2309,7 +2319,13 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo ...@@ -2309,7 +2319,13 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
++nRow; ++nRow;
if ( nRow > nEndRow ) // Already at the end? if ( nRow > nEndRow ) // Already at the end?
return NULL; // Found nothing return NULL; // Found nothing
nCol = nStartCol; // Start at the left again
if ( bRepeatedRow && ! nMinNextEnd < nRow ) // use the data of the previous row
continue;
bRepeatedRow = true; // ppPatterns is not modified
nMinNextEnd = MAXROW;
bool bEmpty = true; bool bEmpty = true;
SCCOL i; SCCOL i;
...@@ -2319,6 +2335,7 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo ...@@ -2319,6 +2335,7 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
if ( pNextEnd[nPos] < nRow ) if ( pNextEnd[nPos] < nRow )
{ {
const ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray; const ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
bRepeatedRow = false;
SCSIZE nIndex = ++pIndices[nPos]; SCSIZE nIndex = ++pIndices[nPos];
if ( nIndex < pArray->nCount ) if ( nIndex < pArray->nCount )
...@@ -2344,19 +2361,15 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo ...@@ -2344,19 +2361,15 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
} }
else if ( ppPatterns[nPos] ) else if ( ppPatterns[nPos] )
bEmpty = false; // Area not at the end yet bEmpty = false; // Area not at the end yet
if ( nMinNextEnd > pNextEnd[nPos] )
nMinNextEnd = pNextEnd[nPos];
} }
if (bEmpty) if (bEmpty)
{ nRow = nMinNextEnd; // Skip empty rows
SCCOL nCount = nEndCol-nStartCol+1;
SCROW nSkipTo = pNextEnd[0]; // Search next end of area
for (i=1; i<nCount; i++)
if ( pNextEnd[i] < nSkipTo )
nSkipTo = pNextEnd[i];
nRow = nSkipTo; // Skip empty rows
}
bRowEmpty = bEmpty; bRowEmpty = bEmpty;
nCol = nStartCol; // Start at the left again
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment