[Libreoffice-commits] core.git: sc/inc sc/source

László Németh laszlo.nemeth at collabora.com
Fri Feb 27 16:59:52 PST 2015


 sc/inc/dociter.hxx              |    5 -
 sc/source/core/data/dociter.cxx |  187 +++++++++++++++++-----------------------
 2 files changed, 88 insertions(+), 104 deletions(-)

New commits:
commit 3d586d61d6a2b314783203d92fb0c1b62ea0e95e
Author: László Németh <laszlo.nemeth at collabora.com>
Date:   Sat Feb 28 01:40:13 2015 +0100

    tdf#89436 ScHorizontalAttrIterator cleanup
    
    + optimization (removing cycle on cells with default attributes)
    
    Change-Id: I4441fab13cb8ba6251d8524db4045e22514436fa

diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx
index 65023b0..838c100 100644
--- a/sc/inc/dociter.hxx
+++ b/sc/inc/dociter.hxx
@@ -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 );
diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index 77cf693..6ab77bc 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -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);
     }
 }
 


More information about the Libreoffice-commits mailing list