Resolves tdf#100709 Optimize SheetDataBuffer::addColXfStyle

The insertion of RowRanges into the sorted set was done by iterating through the
set until the correct insertion point was found.  By using set.lower_bound(),
the complexity goes from O(N) to (log N) for a single insert.

Regarding tdf#100709: the import time for the attached example document reduces by 12x.

Change-Id: Ifb03d58a0e46a936ab61a5f0b512e956c87e5e2b
Reviewed-on: https://gerrit.libreoffice.org/28510
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins <ci@libreoffice.org>
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index d5f29af..1ebf76c 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -370,59 +370,48 @@ void SheetDataBuffer::addColXfStyle( sal_Int32 nXfId, sal_Int32 nFormatId, const
            maStylesPerColumn[ nCol ].insert( aStyleRows );
        else
        {
            RowStyles& rRowStyles =  maStylesPerColumn[ nCol ];
            RowStyles& rRowStyles = maStylesPerColumn[ nCol ];
            // Reset row range for each column
            aStyleRows.mnStartRow = rAddress.StartRow;
            aStyleRows.mnEndRow = rAddress.EndRow;

            // If the rowrange style includes rows already
            // allocated to a style then we need to split
            // the range style Rows into sections ( to
            // occupy only rows that have no style definition )
            // If aStyleRows includes rows already allocated to a style
            // in rRowStyles, then we need to split it into parts.
            // ( to occupy only rows that have no style definition)

            // We don't want to set any rowstyle 'rows'
            // for rows where there is an existing 'style' )
            std::vector< RowRangeStyle > aRangeRowsSplits;

            RowStyles::iterator rows_it = rRowStyles.begin();
            // Start iterating at the first element that is not completely before aStyleRows
            RowStyles::iterator rows_it = rRowStyles.lower_bound(aStyleRows);
            RowStyles::iterator rows_end = rRowStyles.end();
            bool bAddRange = true;
            for ( ; rows_it != rows_end; ++rows_it )
            {
                const RowRangeStyle& r = *rows_it;
                // if row is completely within existing style, discard it
                if ( aStyleRows.mnStartRow >= r.mnStartRow && aStyleRows.mnEndRow <= r.mnEndRow )
                    bAddRange = false;
                else if ( aStyleRows.mnStartRow <= r.mnStartRow )

                // Add the part of aStyleRows that does not overlap with r
                if ( aStyleRows.mnStartRow < r.mnStartRow )
                {
                    // not intersecting at all?, if so finish as none left
                    // to check ( row ranges are in ascending order
                    if ( aStyleRows.mnEndRow < r.mnStartRow )
                        break;
                    else if ( aStyleRows.mnEndRow <= r.mnEndRow )
                    {
                        aStyleRows.mnEndRow = r.mnStartRow - 1;
                        break;
                    }
                    if ( aStyleRows.mnStartRow < r.mnStartRow )
                    {
                        RowRangeStyle aSplit = aStyleRows;
                        aSplit.mnEndRow = r.mnStartRow - 1;
                        aRangeRowsSplits.push_back( aSplit );
                    }
                    RowRangeStyle aSplit = aStyleRows;
                    aSplit.mnEndRow = std::min(aStyleRows.mnEndRow, r.mnStartRow - 1);
                    // Insert with hint that aSplit comes directly before the current position
                    rRowStyles.insert( rows_it, aSplit );
                }
                if ( aStyleRows.mnStartRow <= r.mnEndRow && r.mnEndRow < aStyleRows.mnEndRow )
                    aStyleRows.mnStartRow = r.mnEndRow + 1;

                // Done if no part of aStyleRows extends beyond r
                if ( aStyleRows.mnEndRow <= r.mnEndRow )
                {
                    bAddRange = false;
                    break;
                }

                // Cut off the part aStyleRows that was handled above
                aStyleRows.mnStartRow = r.mnEndRow + 1;
            }
            std::vector< RowRangeStyle >::iterator splits_it = aRangeRowsSplits.begin();
            std::vector< RowRangeStyle >::iterator splits_end = aRangeRowsSplits.end();
            for ( ; splits_it != splits_end; ++splits_it )
                rRowStyles.insert( *splits_it );
            if ( bAddRange )
                rRowStyles.insert( aStyleRows );
        }
    }
}

void SheetDataBuffer::finalizeImport()
{
    // create all array formulas