[Libreoffice-commits] .: oox/inc oox/source

Muthu Subramanian sumuthu at kemper.freedesktop.org
Thu Jun 9 23:56:23 PDT 2011


 oox/inc/oox/xls/sheetdatabuffer.hxx |   12 ++--
 oox/source/xls/sheetdatabuffer.cxx  |   98 ++++++++++++++++--------------------
 2 files changed, 51 insertions(+), 59 deletions(-)

New commits:
commit 1b66e024f9fe8c01c0f04731d26ce1d94824bbc9
Author: Muthu Subramanian <sumuthu at novell.com>
Date:   Thu Jun 9 19:15:17 2011 +0530

    n#683578: Performance improvements for xlsx imports.
    
    Specifically reduces the number of UNO calls for
    importing cell attributes.

diff --git a/oox/inc/oox/xls/sheetdatabuffer.hxx b/oox/inc/oox/xls/sheetdatabuffer.hxx
index 82ee27f..b8a9397 100755
--- a/oox/inc/oox/xls/sheetdatabuffer.hxx
+++ b/oox/inc/oox/xls/sheetdatabuffer.hxx
@@ -274,10 +274,9 @@ private:
 
     /** Writes all cell formatting attributes to the passed row range. */
     void                writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const;
-    /** Writes all cell formatting attributes to the passed cell range. */
-    void                writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const;
-    /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */
-    void                mergeXfIdRanges();
+
+    /** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */
+    void                writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const;
 
     /** Merges the passed merged range and updates right/bottom cell borders. */
     void                finalizeMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange );
@@ -317,7 +316,8 @@ private:
         bool                tryExpand( const ::com::sun::star::table::CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId );
         bool                tryMerge( const XfIdRange& rXfIdRange );
     };
-    typedef ::std::map< BinAddress, XfIdRange > XfIdRangeMap;
+    typedef ::std::pair< sal_Int32, sal_Int32 > XfIdNumFmtKey;
+    typedef ::std::map< XfIdNumFmtKey, ApiCellRangeList > XfIdRangeListMap;
 
     /** Stores information about a merged cell range. */
     struct MergedRange
@@ -340,7 +340,7 @@ private:
                         maSharedFmlaAddr;       /// Address of a cell containing a pending shared formula.
     BinAddress          maSharedBaseAddr;       /// Base address of the pending shared formula.
     XfIdRowRange        maXfIdRowRange;         /// Cached XF identifier for a range of rows.
-    XfIdRangeMap        maXfIdRanges;           /// Collected XF identifiers for cell ranges.
+    XfIdRangeListMap    maXfIdRangeLists;       /// Collected XF identifiers for cell rangelists.
     MergedRangeList     maMergedRanges;         /// Merged cell ranges.
     MergedRangeList     maCenterFillRanges;     /// Merged cell ranges from 'center across' or 'fill' alignment.
     bool                mbPendingSharedFmla;    /// True = maSharedFmlaAddr and maSharedBaseAddr are valid.
diff --git a/oox/source/xls/sheetdatabuffer.cxx b/oox/source/xls/sheetdatabuffer.cxx
index 76790d6..d97b382 100755
--- a/oox/source/xls/sheetdatabuffer.cxx
+++ b/oox/source/xls/sheetdatabuffer.cxx
@@ -545,11 +545,8 @@ void SheetDataBuffer::finalizeImport()
     // write default formatting of remaining row range
     writeXfIdRowRangeProperties( maXfIdRowRange );
 
-    // try to merge remaining inserted ranges
-    mergeXfIdRanges();
-    // write all formatting
-    for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt )
-        writeXfIdRangeProperties( aIt->second );
+    for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; aIt++ )
+        writeXfIdRangeListProperties( aIt->first.first, aIt->first.second, aIt->second );
 
     // merge all cached merged ranges and update right/bottom cell borders
     for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt )
@@ -786,35 +783,50 @@ void SheetDataBuffer::setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtI
 {
     if( (rModel.mnXfId >= 0) || (nNumFmtId >= 0) )
     {
-        // try to merge existing ranges and to write some formatting properties
-        if( !maXfIdRanges.empty() )
+        ApiCellRangeList::reverse_iterator aIt = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rbegin();
+        ApiCellRangeList::reverse_iterator aItEnd = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rend();
+        /* The xlsx sheet data contains row wise information.
+         * It is sufficient to check if the row range size is one
+         */
+        if(     aIt                 != aItEnd &&
+                aIt->Sheet          == rModel.maCellAddr.Sheet &&
+                aIt->StartRow       == aIt->EndRow &&
+                aIt->StartRow       == rModel.maCellAddr.Row &&
+                (aIt->EndColumn+1)  == rModel.maCellAddr.Column )
         {
-            // get row index of last inserted cell
-            sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
-            // row changed - try to merge ranges of last row with existing ranges
-            if( rModel.maCellAddr.Row != nLastRow )
+            aIt->EndColumn++;       // Expand Column
+        }
+        else
+        {
+            maXfIdRangeLists[ XfIdNumFmtKey (rModel.mnXfId, nNumFmtId ) ].push_back(
+                              CellRangeAddress( rModel.maCellAddr.Sheet, rModel.maCellAddr.Column, rModel.maCellAddr.Row,
+                              rModel.maCellAddr.Column, rModel.maCellAddr.Row ) );
+        }
+
+        aIt = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rbegin();
+        aItEnd = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rend();
+        ApiCellRangeList::reverse_iterator aItM = aIt+1;
+        while( aItM != aItEnd )
+        {
+            if( aIt->Sheet == aItM->Sheet )
             {
-                mergeXfIdRanges();
-                // write format properties of all ranges above last row and remove them
-                XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end();
-                while( aIt != aEnd )
+                /* Try to merge this with the previous range */
+                if( aIt->StartRow == (aItM->EndRow + 1) &&
+                        aIt->StartColumn == aItM->StartColumn &&
+                        aIt->EndColumn == aItM->EndColumn)
                 {
-                    // check that range cannot be merged with current row, and that range is not in cached row range
-                    if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) )
-                    {
-                        writeXfIdRangeProperties( aIt->second );
-                        maXfIdRanges.erase( aIt++ );
-                    }
-                    else
-                        ++aIt;
+                    aItM->EndRow = aIt->EndRow;
+                    maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].pop_back();
+                    break;
                 }
+                else if( aIt->StartRow > aItM->EndRow + 1 )
+                    break; // Un-necessary to check with any other rows
             }
+            else
+                break;
+            aItM++;
         }
 
-        // try to expand last existing range, or create new range entry
-        if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel.maCellAddr, rModel.mnXfId, nNumFmtId ) )
-            maXfIdRanges[ BinAddress( rModel.maCellAddr ) ].set( rModel.maCellAddr, rModel.mnXfId, nNumFmtId );
-
         // update merged ranges for 'center across selection' and 'fill'
         if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() )
         {
@@ -846,38 +858,18 @@ void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowR
     }
 }
 
-void SheetDataBuffer::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const
+void SheetDataBuffer::writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const
 {
     StylesBuffer& rStyles = getStyles();
     PropertyMap aPropMap;
-    if( rXfIdRange.mnXfId >= 0 )
-        rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId );
-    if( rXfIdRange.mnNumFmtId >= 0 )
-        rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId );
-    PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) );
+    if( nXfId >= 0 )
+        rStyles.writeCellXfToPropertyMap( aPropMap, nXfId );
+    if( nNumFmtId >= 0 )
+        rStyles.writeNumFmtToPropertyMap( aPropMap, nNumFmtId );
+    PropertySet aPropSet( getCellRangeList( rRanges ) );
     aPropSet.setProperties( aPropMap );
 }
 
-void SheetDataBuffer::mergeXfIdRanges()
-{
-    if( !maXfIdRanges.empty() )
-    {
-        // get row index of last range
-        sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
-        // process all ranges located in the same row of the last range
-        XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end();
-        while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) )
-        {
-            const XfIdRange& rMergeXfIdRange = aMergeIt->second;
-            // try to find a range that can be merged with rMergeRange
-            bool bFound = false;
-            for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt )
-                if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true )
-                    maXfIdRanges.erase( aMergeIt++ );
-        }
-    }
-}
-
 void SheetDataBuffer::finalizeMergedRange( const CellRangeAddress& rRange )
 {
     bool bMultiCol = rRange.StartColumn < rRange.EndColumn;


More information about the Libreoffice-commits mailing list