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

tdf#89436 ScHorizontalAttrIterator cleanup

+ optimization (removing cycle on cells with default attributes)

Change-Id: I4441fab13cb8ba6251d8524db4045e22514436fa
üst f5b00ec9
......@@ -487,7 +487,7 @@ private:
SCROW nEndRow;
SCROW* pNextEnd;
SCCOL* pPrevColEnd;
SCCOL* pHorizEnd;
SCSIZE* pIndices;
const ScPatternAttr** ppPatterns;
SCCOL nCol;
......@@ -496,6 +496,9 @@ private:
bool bRepeatedRow;
SCROW nMinNextEnd;
void InitForNextRow(bool bInitialization);
bool InitForNextAttr();
public:
ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB nTable,
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
......
......@@ -2230,8 +2230,6 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
OSL_FAIL("try to access index out of bounds, FIX IT");
OSL_ENSURE( pDoc->maTabs[nTab], "Table does not exist" );
SCCOL i;
nRow = nStartRow;
nCol = nStartCol;
bRowEmpty = false;
......@@ -2239,49 +2237,97 @@ ScHorizontalAttrIterator::ScHorizontalAttrIterator( ScDocument* pDocument, SCTAB
pIndices = new SCSIZE[nEndCol-nStartCol+1];
pNextEnd = new SCROW[nEndCol-nStartCol+1];
pPrevColEnd = new SCCOL[nEndCol-nStartCol+1];
pHorizEnd = new SCCOL[nEndCol-nStartCol+1];
ppPatterns = new const ScPatternAttr*[nEndCol-nStartCol+1];
nMinNextEnd = MAXROW;
InitForNextRow(true);
}
ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
{
delete[] ppPatterns;
delete[] pHorizEnd;
delete[] pNextEnd;
delete[] pIndices;
}
void ScHorizontalAttrIterator::InitForNextRow(bool bInitialization)
{
bool bEmpty = true;
for (i=nStartCol; i<=nEndCol; i++)
nMinNextEnd = MAXROW;
SCCOL nThisHead = 0;
for (SCCOL i=nStartCol; i<=nEndCol; i++)
{
SCCOL nPos = i - nStartCol;
const ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
OSL_ENSURE( pArray, "pArray == 0" );
if ( bInitialization || pNextEnd[nPos] < nRow )
{
const ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
OSL_ENSURE( pArray, "pArray == 0" );
SCSIZE nIndex;
if (bInitialization)
{
pArray->Search( nStartRow, nIndex );
pIndices[nPos] = nIndex;
pHorizEnd[nPos] = MAXCOL+1; // only for OSL_ENSURE
}
else
nIndex = ++pIndices[nPos];
SCSIZE nIndex;
pArray->Search( nStartRow, nIndex );
if ( nIndex < pArray->nCount )
{
const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
SCROW nThisEnd = pArray->pData[nIndex].nRow;
const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
SCROW nThisEnd = pArray->pData[nIndex].nRow;
if ( IsDefaultItem( pPattern ) )
pPattern = NULL;
else
bEmpty = false; // Found attributes
if ( nThisEnd < nMinNextEnd )
nMinNextEnd = nThisEnd; // nMinNextEnd can be set here already
pNextEnd[nPos] = nThisEnd;
OSL_ENSURE( pNextEnd[nPos] >= nRow, "Sequence out of order" );
ppPatterns[nPos] = pPattern;
}
else
{
OSL_FAIL("AttrArray does not range to MAXROW");
pNextEnd[nPos] = MAXROW;
ppPatterns[nPos] = NULL;
}
}
else if ( ppPatterns[nPos] )
bEmpty = false; // Area not at the end yet
if ( IsDefaultItem( pPattern ) )
pPattern = NULL;
else
bEmpty = false; // Found attributes
if ( nMinNextEnd > pNextEnd[nPos] )
nMinNextEnd = pNextEnd[nPos];
pIndices[nPos] = nIndex;
pNextEnd[nPos] = nThisEnd;
pPrevColEnd[nPos] = MAXCOL+1; // only for OSL_ENSURE
ppPatterns[nPos] = pPattern;
// store positions of ScHorizontalAttrIterator elements (minimizing expensive ScPatternAttr comparisons)
if (i > nStartCol && ppPatterns[nThisHead] != ppPatterns[nPos])
{
pHorizEnd[nThisHead] = i - 1;
nThisHead = nPos; // start position of the next horizontal group
}
}
if (bEmpty)
nRow = nMinNextEnd; // Skip until end of next section
else
pHorizEnd[nThisHead] = nEndCol; // set the end position of the last horizontal group, too
bRowEmpty = bEmpty;
}
ScHorizontalAttrIterator::~ScHorizontalAttrIterator()
bool ScHorizontalAttrIterator::InitForNextAttr()
{
delete[] ppPatterns;
delete[] pNextEnd;
delete[] pPrevColEnd;
delete[] pIndices;
if ( !ppPatterns[nCol-nStartCol] ) // Skip default items
{
OSL_ENSURE( pHorizEnd[nCol-nStartCol] < MAXCOL+1, "missing stored data" );
nCol = pHorizEnd[nCol-nStartCol] + 1;
if ( nCol > nEndCol )
return false;
}
return true;
}
const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2, SCROW& rRow )
......@@ -2290,35 +2336,16 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
OSL_FAIL("try to access index out of bounds, FIX IT");
for (;;)
{
if (!bRowEmpty)
if ( !bRowEmpty && nCol <= nEndCol && InitForNextAttr() )
{
// Search in this row
while ( nCol <= nEndCol && !ppPatterns[nCol-nStartCol] )
++nCol;
if ( nCol <= nEndCol )
{
const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
rRow = nRow;
rCol1 = nCol;
if ( bRepeatedRow )
{
OSL_ENSURE( pPrevColEnd[nCol-nStartCol] < MAXCOL+1, "missing stored data" );
nCol = pPrevColEnd[nCol-nStartCol]; // use the result stored before
}
else
{
while ( nCol < nEndCol && ( ppPatterns[nCol+1-nStartCol] == pPat) )
++nCol;
// store the result to avoid the previous very expensive comparisons
pPrevColEnd[rCol1-nStartCol] = nCol;
}
rCol2 = nCol;
++nCol; // Count up for next call
return pPat; // Found it!
}
bRepeatedRow = true; // we can use the stored row data next time
const ScPatternAttr* pPat = ppPatterns[nCol-nStartCol];
rRow = nRow;
rCol1 = nCol;
OSL_ENSURE( pHorizEnd[nCol-nStartCol] < MAXCOL+1, "missing stored data" );
nCol = pHorizEnd[nCol-nStartCol];
rCol2 = nCol;
++nCol; // Count up for next call
return pPat; // Found it!
}
// Next row
......@@ -2327,54 +2354,8 @@ const ScPatternAttr* ScHorizontalAttrIterator::GetNext( SCCOL& rCol1, SCCOL& rCo
return NULL; // Found nothing
nCol = nStartCol; // Start at the left again
if ( bRepeatedRow && nRow <= nMinNextEnd ) // use only the stored data of the previous row
continue;
bRepeatedRow = false;
nMinNextEnd = MAXROW;
bool bEmpty = true;
SCCOL i;
for ( i = nStartCol; i <= nEndCol; i++)
{
SCCOL nPos = i-nStartCol;
if ( pNextEnd[nPos] < nRow )
{
const ScAttrArray* pArray = pDoc->maTabs[nTab]->aCol[i].pAttrArray;
SCSIZE nIndex = ++pIndices[nPos];
if ( nIndex < pArray->nCount )
{
const ScPatternAttr* pPattern = pArray->pData[nIndex].pPattern;
SCROW nThisEnd = pArray->pData[nIndex].nRow;
if ( IsDefaultItem( pPattern ) )
pPattern = NULL;
else
bEmpty = false; // Found attributes
pNextEnd[nPos] = nThisEnd;
ppPatterns[nPos] = pPattern;
OSL_ENSURE( pNextEnd[nPos] >= nRow, "Sequence out of order" );
}
else
{
OSL_FAIL("AttrArray does not range to MAXROW");
pNextEnd[nPos] = MAXROW;
ppPatterns[nPos] = NULL;
}
}
else if ( ppPatterns[nPos] )
bEmpty = false; // Area not at the end yet
if ( nMinNextEnd > pNextEnd[nPos] )
nMinNextEnd = pNextEnd[nPos];
}
if (bEmpty)
nRow = nMinNextEnd; // Skip empty rows
bRowEmpty = bEmpty;
if ( bRowEmpty || nRow > nMinNextEnd )
InitForNextRow(false);
}
}
......
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