[ooo-build-commit] patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Dec 28 20:48:05 PST 2009


 patches/dev300/apply                                   |    6 
 patches/dev300/calc-xlsx-import-default-cellstyle.diff |   31 ++
 patches/dev300/xlsx-export-perf-rowbuffer.diff         |  235 +++++++++++++++++
 3 files changed, 272 insertions(+)

New commits:
commit 12ca48e767f294ba92dfff7e5d84d2a15ab6439a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Dec 28 23:29:07 2009 -0500

    Improve performance of xlsx export.
    
    * patches/dev300/apply: added two new patches.
    
    * patches/dev300/calc-xlsx-import-default-cellstyle.diff: the xlsx
      import filter was importing Excel's 'Normal' cell style as non-default
      style.  Import it as a default style which improves xlsx export
      performance considerably. (n#558577)
    
    * patches/dev300/xlsx-export-perf-rowbuffer.diff: don't create buffers
      for empty rows.  We only need to export non-empty rows anyway.
      (n#558577)

diff --git a/patches/dev300/apply b/patches/dev300/apply
index d4d2c8f..15e0f7d 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -840,6 +840,9 @@ calc-perf-filtering-with-notes.diff, n#556927, kohei
 # Use current range separator for range lists.
 calc-formula-range-separator-fix.diff, n#556268, kohei
 
+# import xlsx's Normal cell style into Calc's 'Default' style.
+calc-xlsx-import-default-cellstyle.diff, n#558577, kohei
+
 # Support PHONETIC function to display asian phonetic guide.
 # LATER: I'll take care of this later.  --kohei
 # calc-formula-asian-phonetic.diff, i#80764, i#80765, i#80766, kohei
@@ -3106,6 +3109,9 @@ xlsx-export-row-limit-fix.diff, n#504623, kohei
 # No more SvStream/SotStorage as they conflict with their UNO counterparts.
 xlsx-export-no-more-svstream-sotstorage.diff, n#566581, kohei
 
+# Only process rows with non-empty cells, to improve performance.
+xlsx-export-perf-rowbuffer.diff, n#558577, kohei
+
 [ OOXMLExport ]
 # hack to ignore writerfilter when odf-converter is present
 odf-converter-ignore-writerfilter.diff, n#348471, n#502173, jholesov
diff --git a/patches/dev300/calc-xlsx-import-default-cellstyle.diff b/patches/dev300/calc-xlsx-import-default-cellstyle.diff
new file mode 100644
index 0000000..11633ba
--- /dev/null
+++ b/patches/dev300/calc-xlsx-import-default-cellstyle.diff
@@ -0,0 +1,31 @@
+diff --git oox/source/xls/stylesbuffer.cxx oox/source/xls/stylesbuffer.cxx
+index 242387c..d910767 100644
+--- oox/source/xls/stylesbuffer.cxx
++++ oox/source/xls/stylesbuffer.cxx
+@@ -2949,6 +2949,9 @@ void CellStyleBuffer::finalizeImport()
+     for( CellStyleVector::iterator aIt = maBuiltinStyles.begin(), aEnd = maBuiltinStyles.end(); aIt != aEnd; ++aIt )
+     {
+         const CellStyleModel& rModel = (*aIt)->getModel();
++        if (rModel.isDefaultStyle())
++            continue;
++
+         OUString aStyleName = lclGetBuiltinStyleName( rModel.mnBuiltinId, rModel.maName, rModel.mnLevel );
+         OSL_ENSURE( bReserveAll || (aCellStyles.count( aStyleName ) == 0),
+             "CellStyleBuffer::finalizeImport - multiple styles with equal built-in identifier" );
+@@ -2989,6 +2992,16 @@ void CellStyleBuffer::finalizeImport()
+ 
+     // set final names and create user-defined and modified built-in cell styles
+     aCellStyles.forEachMemWithKey( &CellStyle::finalizeImport );
++
++    if (mxDefStyle)
++    {
++        Reference<XNameAccess> xNA(getStyleFamily(false), UNO_QUERY_THROW);
++        if (xNA->hasByName(CREATE_OUSTRING("Default")))
++        {
++            PropertySet aPropSet(xNA->getByName(CREATE_OUSTRING("Default")));
++            getStyles().writeStyleXfToPropertySet(aPropSet, mxDefStyle->getModel().mnXfId);
++        }
++    }
+ }
+ 
+ sal_Int32 CellStyleBuffer::getDefaultXfId() const
diff --git a/patches/dev300/xlsx-export-perf-rowbuffer.diff b/patches/dev300/xlsx-export-perf-rowbuffer.diff
new file mode 100644
index 0000000..e71a900
--- /dev/null
+++ b/patches/dev300/xlsx-export-perf-rowbuffer.diff
@@ -0,0 +1,235 @@
+diff --git sc/source/filter/xlsx/xetable.hxx sc/source/filter/xlsx/xetable.hxx
+index 66a9e06..2abf6a4 100644
+--- sc/source/filter/xlsx/xetable.hxx
++++ sc/source/filter/xlsx/xetable.hxx
+@@ -41,6 +41,9 @@
+ #include "xeformula.hxx"
+ #include "xestyle.hxx"
+ 
++#include <boost/shared_ptr.hpp>
++#include <map>
++
+ /* ============================================================================
+ Export of cell tables including row and column description.
+ - Managing all used and formatted cells in a sheet.
+@@ -1005,14 +1008,12 @@ private:
+     XclExpRow&          GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty );
+ 
+ private:
+-    typedef XclExpRecordList< XclExpRow >   XclExpRowList;
+-    typedef XclExpRowList::RecordRefType    XclExpRowRef;
+-
+-    XclExpRowList       maRowList;          /// List of all ROW records.
++    typedef ::boost::shared_ptr<XclExpRow>  RowRef;
++    typedef ::std::map<sal_uInt32, RowRef>  RowMap;
++    
++    RowMap              maRowMap;
+     XclExpRowOutlineBuffer maOutlineBfr;    /// Buffer for row outline groups.
+     XclExpDimensions    maDimensions;       /// DIMENSIONS record for used area.
+-    XclExpRow*          mpLastUsedRow;      /// Last used row for faster access.
+-    sal_uInt32          mnLastUsedXclRow;   /// Last used row for faster access.
+ };
+ 
+ // ============================================================================
+diff --git sc/source/filter/xlsx/xlsx-xetable.cxx sc/source/filter/xlsx/xlsx-xetable.cxx
+index 36de8e5..6abe5b5 100644
+--- sc/source/filter/xlsx/xlsx-xetable.cxx
++++ sc/source/filter/xlsx/xlsx-xetable.cxx
+@@ -47,6 +47,7 @@
+ #include "xeescher.hxx"
+ 
+ #include <oox/core/tokens.hxx>
++#include "svx/fontitem.hxx"
+ 
+ using ::rtl::OString;
+ using ::rtl::OUString;
+@@ -2091,9 +2092,7 @@ void XclExpRow::SaveXml( XclExpXmlStream& rStrm )
+ XclExpRowBuffer::XclExpRowBuffer( const XclExpRoot& rRoot ) :
+     XclExpRoot( rRoot ),
+     maOutlineBfr( rRoot ),
+-    maDimensions( rRoot ),
+-    mpLastUsedRow( 0 ),
+-    mnLastUsedXclRow( 0 )
++    maDimensions( rRoot )
+ {
+ }
+ 
+@@ -2111,63 +2110,34 @@ void XclExpRowBuffer::CreateRows( SCROW nFirstFreeScRow )
+ 
+ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt16Vec& rColXFIndexes )
+ {
+-    size_t nPos, nSize;
+-
+     // *** Finalize all rows *** ----------------------------------------------
+ 
+     GetProgressBar().ActivateFinalRowsSegment();
+ 
+-    // unused blank cell records will be removed
+-    for( nPos = 0, nSize = maRowList.GetSize(); nPos < nSize; ++nPos )
+-        maRowList.GetRecord( nPos )->Finalize( rColXFIndexes );
++    RowMap::iterator itr, itrBeg = maRowMap.begin(), itrEnd = maRowMap.end();
++    for (itr = itrBeg; itr != itrEnd; ++itr)
++        itr->second->Finalize(rColXFIndexes);
+ 
+     // *** Default row format *** ---------------------------------------------
+ 
+     typedef ::std::map< XclExpDefaultRowData, size_t > XclExpDefRowDataMap;
+     XclExpDefRowDataMap aDefRowMap;
+ 
+-    // find default row format for rows beyond used area
+-    sal_uInt32 nDefaultXclRow = maRowList.IsEmpty() ? 0 : (maRowList.GetLastRecord()->GetXclRow() + 1);
+     XclExpDefaultRowData aMaxDefData;
+     size_t nMaxDefCount = 0;
+-    /*  #i30411# Files saved with SO7/OOo1.x with nonstandard default column
+-        formatting cause big Excel files, because all rows from row 1 to row
+-        32000 are exported. Now, if the used area goes exactly to row 32000,
+-        ignore all rows >32000.
+-        #i59220# Tolerance of +-128 rows for inserted/removed rows. */
+-    if( (nDefaultXclRow < 31872) || (nDefaultXclRow > 32128) )
+-    {
+-        sal_uInt32 nLastXclRow = static_cast< sal_uInt32 >( GetMaxPos().Row() );
+-        if( nDefaultXclRow <= nLastXclRow )
+-        {
+-            // create a dummy ROW record and fill aMaxDefData
+-            XclExpRowOutlineBuffer aOutlineBfr( GetRoot() );
+-            XclExpRow aRow( GetRoot(), nLastXclRow, aOutlineBfr, true );
+-            aMaxDefData = XclExpDefaultRowData( aRow );
+-            aDefRowMap[ aMaxDefData ] = nMaxDefCount =
+-                static_cast< size_t >( nLastXclRow - nDefaultXclRow + 1 );
+-        }
+-    }
+-
+     // only look for default format in existing rows, if there are more than unused
+-    nSize = maRowList.GetSize();
+-    if( nMaxDefCount < nSize )
++    for (itr = itrBeg; itr != itrEnd; ++itr)
+     {
+-        for( nPos = 0; nPos < nSize; ++nPos )
++        const RowRef& rRow = itr->second;
++        if (rRow->IsDefaultable())
+         {
+-            XclExpRowRef xRow = maRowList.GetRecord( nPos );
+-            /*  Collect formats of unused rows (rows without cells), which are able
+-                to be defaulted (i.e. no explicit format or outline level). */
+-            if( xRow->IsDefaultable() )
++            XclExpDefaultRowData aDefData( *rRow );
++            size_t& rnDefCount = aDefRowMap[ aDefData ];
++            ++rnDefCount;
++            if( rnDefCount > nMaxDefCount )
+             {
+-                XclExpDefaultRowData aDefData( *xRow );
+-                size_t& rnDefCount = aDefRowMap[ aDefData ];
+-                ++rnDefCount;
+-                if( rnDefCount > nMaxDefCount )
+-                {
+-                    nMaxDefCount = rnDefCount;
+-                    aMaxDefData = aDefData;
+-                }
++                nMaxDefCount = rnDefCount;
++                aMaxDefData = aDefData;
+             }
+         }
+     }
+@@ -2182,24 +2152,23 @@ void XclExpRowBuffer::Finalize( XclExpDefaultRowData& rDefRowData, const ScfUInt
+     sal_uInt32 nFirstUsedXclRow = SAL_MAX_UINT32;
+     sal_uInt32 nFirstFreeXclRow = 0;
+ 
+-    for( nPos = 0, nSize = maRowList.GetSize(); nPos < nSize; ++nPos )
++    for (itr = itrBeg; itr != itrEnd; ++itr)
+     {
+-        XclExpRowRef xRow = maRowList.GetRecord( nPos );
+-
++        const RowRef& rRow = itr->second;
+         // disable unused rows
+-        xRow->DisableIfDefault( aMaxDefData );
++        rRow->DisableIfDefault( aMaxDefData );
+ 
+         // find used column range
+-        if( !xRow->IsEmpty() )      // empty rows return (0...0) as used range
++        if( !rRow->IsEmpty() )      // empty rows return (0...0) as used range
+         {
+-            nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, xRow->GetFirstUsedXclCol() );
+-            nFirstFreeXclCol = ::std::max( nFirstFreeXclCol, xRow->GetFirstFreeXclCol() );
++            nFirstUsedXclCol = ::std::min( nFirstUsedXclCol, rRow->GetFirstUsedXclCol() );
++            nFirstFreeXclCol = ::std::max( nFirstFreeXclCol, rRow->GetFirstFreeXclCol() );
+         }
+ 
+         // find used row range
+-        if( xRow->IsEnabled() )
++        if( rRow->IsEnabled() )
+         {
+-            sal_uInt32 nXclRow = xRow->GetXclRow();
++            sal_uInt32 nXclRow = rRow->GetXclRow();
+             nFirstUsedXclRow = ::std::min< sal_uInt32 >( nFirstUsedXclRow, nXclRow );
+             nFirstFreeXclRow = ::std::max< sal_uInt32 >( nFirstFreeXclRow, nXclRow + 1 );
+         }
+@@ -2250,23 +2219,22 @@ void XclExpRowBuffer::Save( XclExpStream& /*rStrm*/ )
+ void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
+ {
+     sal_Int32 nNonEmpty = 0;
+-
+-    size_t nRows = maRowList.GetSize();
+-    for( size_t i = 0; i < nRows; ++i)
+-        if( maRowList.GetRecord( i )->IsEnabled() )
++    RowMap::iterator itr = maRowMap.begin(), itrEnd = maRowMap.end();
++    for (; itr != itrEnd; ++itr)
++        if (itr->second->IsEnabled())
+             ++nNonEmpty;
+ 
+-    if( nNonEmpty == 0 )
+-    {
++    if (nNonEmpty == 0)
++    {    
+         rStrm.GetCurrentStream()->singleElement( XML_sheetData, FSEND );
++        return;
+     }
+-    else
+-    {
+-        sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
+-        rWorksheet->startElement( XML_sheetData, FSEND );
+-        maRowList.SaveXml( rStrm );
+-        rWorksheet->endElement( XML_sheetData );
+-    }
++
++    sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
++    rWorksheet->startElement( XML_sheetData, FSEND );
++    for (itr = maRowMap.begin(); itr != itrEnd; ++itr)
++        itr->second->SaveXml(rStrm);
++    rWorksheet->endElement( XML_sheetData );
+ }
+ 
+ XclExpDimensions* XclExpRowBuffer::GetDimensions() 
+@@ -2276,18 +2244,14 @@ XclExpDimensions* XclExpRowBuffer::GetDimensions()
+ 
+ XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty )
+ {
+-    if( !mpLastUsedRow || (mnLastUsedXclRow != nXclRow) )
++    RowMap::iterator itr = maRowMap.find(nXclRow);
++    if (itr == maRowMap.end())
+     {
+-        // fill up missing ROW records
+-        // do not use sal_uInt16 for nFirstFreeXclRow, would cause loop in full sheets
+-        for( size_t nFirstFreeXclRow = maRowList.GetSize(); nFirstFreeXclRow <= nXclRow; ++nFirstFreeXclRow )
+-            maRowList.AppendNewRecord( new XclExpRow(
+-                GetRoot(), static_cast< sal_uInt32 >( nFirstFreeXclRow ), maOutlineBfr, bRowAlwaysEmpty ) );
+-
+-        mpLastUsedRow = maRowList.GetRecord( nXclRow ).get();
+-        mnLastUsedXclRow = nXclRow;
++        RowRef p(new XclExpRow(GetRoot(), nXclRow, maOutlineBfr, bRowAlwaysEmpty));
++        ::std::pair<RowMap::iterator, bool> r = maRowMap.insert(RowMap::value_type(nXclRow, p));
++        itr = r.first;
+     }
+-    return *mpLastUsedRow;
++    return *itr->second;
+ }
+ 
+ // ============================================================================
+@@ -2354,7 +2318,7 @@ XclExpCellTable::XclExpCellTable( const XclExpRoot& rRoot ) :
+ 
+     // range for cell iterator
+     SCCOL nLastIterScCol = nMaxScCol;
+-    SCROW nLastIterScRow = ulimit_cast< SCROW >( nLastUsedScRow + 128, nMaxScRow );
++    SCROW nLastIterScRow = ulimit_cast< SCROW >( nLastUsedScRow, nMaxScRow );
+     ScUsedAreaIterator aIt( &rDoc, nScTab, 0, 0, nLastIterScCol, nLastIterScRow );
+ 
+     // activate the correct segment and sub segment at the progress bar


More information about the ooo-build-commit mailing list