summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2012-05-14 18:18:25 +0200
committerEike Rathke <erack@redhat.com>2012-05-14 18:18:52 +0200
commit435c117c1c684d4603f557ed821c1fd5ee057086 (patch)
treeef8ebdfb4cb970999adcc3416b967511a53af490
parent904763b1134bdd84a4e64de1e037da5cac192f27 (diff)
some optimization of ScAttrArray::GetLastVisibleAttr()
Method assumed that not much attribution happens below data and started from the end of attribution, in the case of not much attribution it worked fine. For the case of many differently formatted areas with a sufficiently large area of visibly equal attribution near data end it was a bottle neck looping over unnecessarily many comparisons. Start at data end instead. For the case of not much attribution it doesn't really matter, and for the case of no sufficiently large area below data end it doesn't matter at all and compares the same number of entries. The drawback would be a large area near attribution end with many small areas between data end and the large area. Observed with test case of fdo#46160
-rw-r--r--sc/source/core/data/attarray.cxx53
1 files changed, 34 insertions, 19 deletions
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 72d08fc0013b..9de2b0211519 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -1762,6 +1762,8 @@ const SCROW SC_VISATTR_STOP = 84;
bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bFullFormattedArea ) const
{
+ OSL_ENSURE( nCount, "nCount == 0" );
+
// #i30830# changed behavior:
// ignore all attributes starting with the first run of SC_VISATTR_STOP equal rows
// below the last content cell
@@ -1772,36 +1774,49 @@ bool ScAttrArray::GetLastVisibleAttr( SCROW& rLastRow, SCROW nLastData, bool bFu
return true;
}
- bool bFound = false;
-
- // loop backwards from the end instead of using Search, assuming that
- // there usually aren't many attributes below the last cell
-
- SCSIZE nPos = nCount;
- while ( nPos > 0 && pData[nPos-1].nRow > nLastData )
+ // Quick check: last data row in or immediately preceding a run that is the
+ // last attribution down to the end, e.g. default style or column style.
+ SCSIZE nPos = nCount - 1;
+ SCROW nStartRow = (nPos ? pData[nPos-1].nRow + 1 : 0);
+ if (nStartRow <= nLastData + 1)
{
- SCSIZE nEndPos = nPos - 1;
- SCSIZE nStartPos = nEndPos; // find range of visually equal formats
- while ( nStartPos > 0 &&
- pData[nStartPos-1].nRow > nLastData &&
- pData[nStartPos-1].pPattern->IsVisibleEqual(*pData[nStartPos].pPattern) )
- --nStartPos;
+ if (bFullFormattedArea && pData[nPos].pPattern->IsVisible())
+ {
+ rLastRow = pData[nPos].nRow;
+ return true;
+ }
+ else
+ {
+ // Ignore here a few rows if data happens to end within
+ // SC_VISATTR_STOP rows before MAXROW.
+ rLastRow = nLastData;
+ return false;
+ }
+ }
+ // Find a run below last data row.
+ bool bFound = false;
+ Search( nLastData, nPos );
+ while ( nPos < nCount )
+ {
+ // find range of visually equal formats
+ SCSIZE nStartPos = nPos;
+ SCSIZE nEndPos = nStartPos + 1;
+ while ( nEndPos < nCount-1 &&
+ pData[nEndPos].pPattern->IsVisibleEqual( *pData[nEndPos+1].pPattern))
+ ++nEndPos;
SCROW nAttrStartRow = ( nStartPos > 0 ) ? ( pData[nStartPos-1].nRow + 1 ) : 0;
if ( nAttrStartRow <= nLastData )
nAttrStartRow = nLastData + 1;
SCROW nAttrSize = pData[nEndPos].nRow + 1 - nAttrStartRow;
if ( nAttrSize >= SC_VISATTR_STOP && !bFullFormattedArea )
- {
- bFound = false; // ignore this range and below
- }
- else if ( !bFound && pData[nEndPos].pPattern->IsVisible() )
+ break; // while, ignore this range and below
+ else if ( pData[nEndPos].pPattern->IsVisible() )
{
rLastRow = pData[nEndPos].nRow;
bFound = true;
}
-
- nPos = nStartPos; // look further from the top of the range
+ nPos = nEndPos;
}
return bFound;