summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
authorJustin Luth <justin_luth@sil.org>2017-02-08 19:08:07 +0300
committerBartosz Kosiorek <gang65@poczta.onet.pl>2017-02-15 16:00:07 +0000
commit854bae75ab891423182f11604aedc42c6bfa334e (patch)
treee5e7fd2871ccdcb529c1bf8128481e20356251d1 /sc/source
parent05116fb49efa563610f6486d0c3f6216624dcd13 (diff)
Optimize Excel GetOrCreateRow: reduce loops
for ( size_t nFrom = maRowMap.size(); nFrom <= nXclRow; ++nFrom ) This previous code worked best under the assumption that every row is added to the map. However, the size of the map actually has no correlation to the row numbers contained in it when many rows are identical to each other (think silly formatting and empty rows - related to tdf#105840) Thus row 1,000,000 could occupy slot 2, and every access of that row would then trigger nearly 1 million redundant loops. Optimize: -check to see if the row already exists - if so do nothing. -existance of higher rows indicates there are no missing rows. -build missing rows from the previously-mapped row. Reviewed-on: https://gerrit.libreoffice.org/34038 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl> Conflicts: sc/source/filter/excel/xetable.cxx Change-Id: Ib02520a1bf0f77b5ca0ec5ad3165ff7ea879515f Reviewed-on: https://gerrit.libreoffice.org/34275 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/filter/excel/xetable.cxx37
1 files changed, 27 insertions, 10 deletions
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx
index fe39f238d4f9..9f8eec1c4294 100644
--- a/sc/source/filter/excel/xetable.cxx
+++ b/sc/source/filter/excel/xetable.cxx
@@ -2374,22 +2374,39 @@ void XclExpRowBuffer::SaveXml( XclExpXmlStream& rStrm )
XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysEmpty )
{
- RowMap::iterator itr = maRowMap.begin();
- ScDocument& rDoc = GetRoot().GetDoc();
- SCTAB nScTab = GetRoot().GetCurrScTab();
- for ( size_t nFrom = maRowMap.size(); nFrom <= nXclRow; ++nFrom )
+ RowMap::iterator itr = maRowMap.lower_bound( nXclRow );
+ const bool bFound = itr != maRowMap.end();
+ // bFoundHigher: nXclRow was identical to the previous entry, so not explicitly created earlier
+ const bool bFoundHigher = bFound && itr != maRowMap.find( nXclRow );
+ if( !bFound || bFoundHigher )
{
- itr = maRowMap.find(nFrom);
- if ( itr == maRowMap.end() )
+ size_t nFrom = 0;
+ if( itr != maRowMap.begin() )
+ {
+ --itr;
+ if( bFoundHigher )
+ nFrom = nXclRow;
+ else
+ nFrom = itr->first + 1;
+ }
+
+ const ScDocument& rDoc = GetRoot().GetDoc();
+ const SCTAB nScTab = GetRoot().GetCurrScTab();
+ // create the missing rows first
+ while( nFrom <= nXclRow )
{
// only create RowMap entries if it is first row in spreadsheet,
// if it is the desired row, for rows that height differ from previous,
// if row is collapsed, has outline level (tdf#100347), or row is hidden (tdf#98106).
- if ( !nFrom || ( nFrom == nXclRow ) ||
- ( rDoc.GetRowHeight(nFrom, nScTab, false) != rDoc.GetRowHeight(nFrom - 1, nScTab, false) ) ||
+ const bool bHidden = rDoc.RowHidden(nFrom, nScTab);
+ // Always get the actual row height even if the manual size flag is
+ // not set, to correctly export the heights of rows with wrapped
+ // texts.
+ const sal_uInt16 nHeight = rDoc.GetRowHeight(nFrom, nScTab, false);
+ if ( !nFrom || ( nFrom == nXclRow ) || bHidden ||
( maOutlineBfr.IsCollapsed() ) ||
( maOutlineBfr.GetLevel() != 0 ) ||
- ( rDoc.RowHidden(nFrom, nScTab) ) )
+ ( nHeight != rDoc.GetRowHeight(nFrom - 1, nScTab, false) ) )
{
if( maOutlineBfr.GetLevel() > mnHighestOutlineLevel )
{
@@ -2398,11 +2415,11 @@ XclExpRow& XclExpRowBuffer::GetOrCreateRow( sal_uInt32 nXclRow, bool bRowAlwaysE
RowRef p(new XclExpRow(GetRoot(), nFrom, maOutlineBfr, bRowAlwaysEmpty));
maRowMap.insert(RowMap::value_type(nFrom, p));
}
+ ++nFrom;
}
}
itr = maRowMap.find(nXclRow);
return *itr->second;
-
}
// Cell Table