sc/inc/attrib.hxx | 13 ++++++---- sc/inc/document.hxx | 4 ++- sc/qa/unit/ucalc_condformat.cxx | 10 ++++---- sc/source/core/data/attarray.cxx | 47 ++++++++++++++++++++++++--------------- sc/source/core/data/attrib.cxx | 32 +++++++++++++++----------- sc/source/core/data/column3.cxx | 2 - sc/source/core/data/column4.cxx | 2 - sc/source/core/data/documen4.cxx | 8 +++--- sc/source/core/data/fillinfo.cxx | 4 +-- sc/source/core/data/table2.cxx | 2 - sc/source/core/data/table4.cxx | 4 +-- sc/source/ui/unoobj/cellsuno.cxx | 2 - sc/source/ui/view/cellsh1.cxx | 2 - 13 files changed, 77 insertions(+), 55 deletions(-)
New commits: commit aae39e5dbfde76726e3ad6a2e99874490515da58 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Sat Apr 20 19:08:10 2019 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Sun Apr 21 16:24:10 2019 +0200 tdf#81765 slow loading of .ods with >1000 of conditional formats, part 3 This takes the loading time from 14s to 13s Use a o3tl::sorted_vector to reduce searching time Change-Id: I947a3e5001fe1058cf9bffc9509d026af4122ef4 Reviewed-on: https://gerrit.libreoffice.org/71035 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx index e03d1a223d66..cecc587c8df3 100644 --- a/sc/inc/attrib.hxx +++ b/sc/inc/attrib.hxx @@ -25,6 +25,7 @@ #include <svl/poolitem.hxx> #include <svl/intitem.hxx> #include <svl/eitem.hxx> +#include <o3tl/sorted_vector.hxx> #include <o3tl/typed_flags_set.hxx> #include "scdllapi.h" #include "global.hxx" @@ -260,11 +261,15 @@ private: sal_uInt16 mnHeight; }; +typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; + class ScCondFormatItem : public SfxPoolItem { public: explicit ScCondFormatItem(); - explicit ScCondFormatItem(const std::vector<sal_uInt32>& nIndex); + explicit ScCondFormatItem(sal_uInt32 nIndex); + explicit ScCondFormatItem(const ScCondFormatIndexes& ); + explicit ScCondFormatItem(ScCondFormatIndexes&& ); virtual ~ScCondFormatItem() override; @@ -273,14 +278,12 @@ public: virtual bool IsSortable() const override { return true; } virtual ScCondFormatItem* Clone( SfxItemPool* = nullptr ) const override; - const std::vector<sal_uInt32>& GetCondFormatData() const { return maIndex;} - void AddCondFormatData( sal_uInt32 nIndex ); - void SetCondFormatData( const std::vector<sal_uInt32>& aIndex ); + const ScCondFormatIndexes& GetCondFormatData() const { return maIndex;} virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override; private: - std::vector<sal_uInt32> maIndex; + ScCondFormatIndexes maIndex; }; #endif diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 615760e87c3a..3d6b87b155fd 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -36,6 +36,7 @@ #include "calcmacros.hxx" #include "calcconfig.hxx" #include <o3tl/deleter.hxx> +#include <o3tl/sorted_vector.hxx> #include <svl/hint.hxx> #include <svl/typedwhich.hxx> #include <svl/zforlist.hxx> @@ -195,6 +196,7 @@ enum class ScSheetEventId; class BitmapEx; class ScColumnsRange; struct ScFilterEntries; +typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; namespace sc { @@ -1693,7 +1695,7 @@ public: SC_DLLPUBLIC const SfxItemSet* GetCondResult( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; const SfxItemSet* GetCondResult( ScRefCellValue& rCell, const ScAddress& rPos, const ScConditionalFormatList& rList, - const std::vector<sal_uInt32>& rIndex ) const; + const ScCondFormatIndexes& rIndex ) const; const SfxPoolItem* GetEffItem( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich ) const; template<class T> const T* GetEffItem( SCCOL nCol, SCROW nRow, SCTAB nTab, TypedWhichId<T> nWhich ) const { diff --git a/sc/qa/unit/ucalc_condformat.cxx b/sc/qa/unit/ucalc_condformat.cxx index 836f5bcfee65..7392943f7f3e 100644 --- a/sc/qa/unit/ucalc_condformat.cxx +++ b/sc/qa/unit/ucalc_condformat.cxx @@ -305,7 +305,7 @@ void Test::testCondCopyPaste() CPPUNIT_ASSERT(pCondFormatItem); CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size()); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().at(0)); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front()); m_pDoc->DeleteTab(0); } @@ -344,7 +344,7 @@ void Test::testCondCopyPasteSingleCell() CPPUNIT_ASSERT(pCondFormatItem); CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size()); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().at(0) ); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front() ); m_pDoc->DeleteTab(0); } @@ -387,7 +387,7 @@ void Test::testCondCopyPasteSingleCellToRange() CPPUNIT_ASSERT(pCondFormatItem); CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size()); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().at(0) ); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front() ); } } @@ -426,7 +426,7 @@ void Test::testCondCopyPasteSingleCellIntoSameFormatRange() CPPUNIT_ASSERT(pCondFormatItem); CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size()); - CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().at(0)); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(nIndex), pCondFormatItem->GetCondFormatData().front()); m_pDoc->DeleteTab(0); } @@ -542,7 +542,7 @@ void Test::testCondCopyPasteSheet() CPPUNIT_ASSERT(pCondFormatItem); CPPUNIT_ASSERT_EQUAL(size_t(1), pCondFormatItem->GetCondFormatData().size()); - CPPUNIT_ASSERT_EQUAL( nKey, pCondFormatItem->GetCondFormatData().at(0) ); + CPPUNIT_ASSERT_EQUAL( nKey, pCondFormatItem->GetCondFormatData().front() ); m_pDoc->DeleteTab(1); m_pDoc->DeleteTab(0); diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 282f6ce666cf..7559331533ff 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -299,24 +299,29 @@ void ScAttrArray::AddCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 nInd nTempEndRow = std::min<SCROW>( nPatternEndRow, nEndRow ); const SfxPoolItem* pItem = nullptr; pPattern->GetItemSet().GetItemState( ATTR_CONDITIONAL, true, &pItem ); - std::vector< sal_uInt32 > aCondFormatData; if(pItem) - aCondFormatData = static_cast<const ScCondFormatItem*>(pItem)->GetCondFormatData(); - if (std::find(aCondFormatData.begin(), aCondFormatData.end(), nIndex) - == aCondFormatData.end()) { - aCondFormatData.push_back(nIndex); - - ScCondFormatItem aItem; - aItem.SetCondFormatData( aCondFormatData ); + ScCondFormatIndexes const & rCondFormatData = static_cast<const ScCondFormatItem*>(pItem)->GetCondFormatData(); + if (rCondFormatData.find(nIndex) == rCondFormatData.end()) + { + ScCondFormatIndexes aNewCondFormatData; + aNewCondFormatData.reserve(rCondFormatData.size()+1); + aNewCondFormatData = rCondFormatData; + aNewCondFormatData.insert(nIndex); + ScCondFormatItem aItem( std::move(aNewCondFormatData) ); + pNewPattern->GetItemSet().Put( aItem ); + } + } + else + { + ScCondFormatItem aItem(nIndex); pNewPattern->GetItemSet().Put( aItem ); } } else { pNewPattern.reset( new ScPatternAttr( pDocument->GetPool() ) ); - ScCondFormatItem aItem; - aItem.AddCondFormatData(nIndex); + ScCondFormatItem aItem(nIndex); pNewPattern->GetItemSet().Put( aItem ); nTempEndRow = nEndRow; } @@ -355,19 +360,25 @@ void ScAttrArray::RemoveCondFormat( SCROW nStartRow, SCROW nEndRow, sal_uInt32 n if(pItem) { auto pPatternAttr = std::make_unique<ScPatternAttr>( *pPattern ); - std::vector< sal_uInt32 > aCondFormatData = static_cast<const ScCondFormatItem*>(pItem)->GetCondFormatData(); - std::vector<sal_uInt32>::iterator itr = std::find(aCondFormatData.begin(), aCondFormatData.end(), nIndex); - if(itr != aCondFormatData.end() || nIndex == 0) + if (nIndex == 0) { ScCondFormatItem aItem; - if (nIndex == 0) - aCondFormatData.clear(); - else - aCondFormatData.erase(itr); - aItem.SetCondFormatData( aCondFormatData ); pPatternAttr->GetItemSet().Put( aItem ); SetPatternArea( nTempStartRow, nTempEndRow, std::move(pPatternAttr), true ); } + else + { + ScCondFormatIndexes const & rCondFormatData = static_cast<const ScCondFormatItem*>(pItem)->GetCondFormatData(); + auto itr = rCondFormatData.find(nIndex); + if(itr != rCondFormatData.end()) + { + ScCondFormatIndexes aNewCondFormatData(rCondFormatData); + aNewCondFormatData.erase(nIndex); + ScCondFormatItem aItem( std::move(aNewCondFormatData) ); + pPatternAttr->GetItemSet().Put( aItem ); + SetPatternArea( nTempStartRow, nTempEndRow, std::move(pPatternAttr), true ); + } + } } } else diff --git a/sc/source/core/data/attrib.cxx b/sc/source/core/data/attrib.cxx index 37c9c51b612d..cf6a61663a59 100644 --- a/sc/source/core/data/attrib.cxx +++ b/sc/source/core/data/attrib.cxx @@ -670,12 +670,24 @@ ScCondFormatItem::ScCondFormatItem(): { } -ScCondFormatItem::ScCondFormatItem( const std::vector<sal_uInt32>& rIndex ): +ScCondFormatItem::ScCondFormatItem( sal_uInt32 nIndex ): + SfxPoolItem( ATTR_CONDITIONAL ) +{ + maIndex.insert(nIndex); +} + +ScCondFormatItem::ScCondFormatItem( const ScCondFormatIndexes& rIndex ): SfxPoolItem( ATTR_CONDITIONAL ), maIndex( rIndex ) { } +ScCondFormatItem::ScCondFormatItem( ScCondFormatIndexes&& aIndex ): + SfxPoolItem( ATTR_CONDITIONAL ), + maIndex( std::move(aIndex) ) +{ +} + ScCondFormatItem::~ScCondFormatItem() { } @@ -683,9 +695,11 @@ ScCondFormatItem::~ScCondFormatItem() bool ScCondFormatItem::operator==( const SfxPoolItem& rCmp ) const { auto const & other = static_cast<const ScCondFormatItem&>(rCmp); + if (maIndex.empty() && other.maIndex.empty()) + return true; // memcmp is faster than operator< on std::vector return maIndex.size() == other.maIndex.size() - && memcmp(maIndex.data(), other.maIndex.data(), maIndex.size() * sizeof(sal_uInt32)) == 0; + && memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * sizeof(sal_uInt32)) == 0; } bool ScCondFormatItem::operator<( const SfxPoolItem& rCmp ) const @@ -695,8 +709,10 @@ bool ScCondFormatItem::operator<( const SfxPoolItem& rCmp ) const return true; if ( maIndex.size() > other.maIndex.size() ) return false; + if (maIndex.empty() && other.maIndex.empty()) + return false; // memcmp is faster than operator< on std::vector - return memcmp(maIndex.data(), other.maIndex.data(), maIndex.size() * sizeof(sal_uInt32)) < 0; + return memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * sizeof(sal_uInt32)) < 0; } ScCondFormatItem* ScCondFormatItem::Clone(SfxItemPool*) const @@ -704,16 +720,6 @@ ScCondFormatItem* ScCondFormatItem::Clone(SfxItemPool*) const return new ScCondFormatItem(maIndex); } -void ScCondFormatItem::AddCondFormatData( sal_uInt32 nIndex ) -{ - maIndex.push_back(nIndex); -} - -void ScCondFormatItem::SetCondFormatData( const std::vector<sal_uInt32>& rIndex ) -{ - maIndex = rIndex; -} - void ScCondFormatItem::dumpAsXml(xmlTextWriterPtr pWriter) const { xmlTextWriterStartElement(pWriter, BAD_CAST("ScCondFormatItem")); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 8e728cbe2916..a760f1428336 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -771,7 +771,7 @@ bool ScColumn::UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow, sc::CellSt { const ScCondFormatItem& rItem = pPattern->GetItem(ATTR_CONDITIONAL); - const std::vector<sal_uInt32>& rData = rItem.GetCondFormatData(); + const ScCondFormatIndexes& rData = rItem.GetCondFormatData(); pCondSet = pDocument->GetCondResult(aCell, aPos, *pCFList, rData); } diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index 162537f169a8..d0e54711a5b7 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -1009,7 +1009,7 @@ private: { maPos.SetRow(nRow); const ScCondFormatItem& rItem = pPat->GetItem(ATTR_CONDITIONAL); - const std::vector<sal_uInt32>& rData = rItem.GetCondFormatData(); + const ScCondFormatIndexes& rData = rItem.GetCondFormatData(); pCondSet = mrCol.GetDoc()->GetCondResult(rCell, maPos, *mpCFList, rData); } diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index b89f2f3d3ebd..a1f5a6861db2 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -752,7 +752,7 @@ const SfxPoolItem* ScDocument::GetEffItem( const SfxPoolItem* pItem; if ( rSet.GetItemState( ATTR_CONDITIONAL, true, &pItem ) == SfxItemState::SET ) { - const std::vector<sal_uInt32>& rIndex = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); + const ScCondFormatIndexes& rIndex = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); ScConditionalFormatList* pCondFormList = GetCondFormList( nTab ); if (!rIndex.empty() && pCondFormList) { @@ -791,7 +791,7 @@ const SfxItemSet* ScDocument::GetCondResult( SCCOL nCol, SCROW nRow, SCTAB nTab ScAddress aPos(nCol, nRow, nTab); ScRefCellValue aCell(const_cast<ScDocument&>(*this), aPos); const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab ); - const std::vector<sal_uInt32>& rIndex = + const ScCondFormatIndexes& rIndex = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); return GetCondResult(aCell, aPos, *pFormatList, rIndex); @@ -799,7 +799,7 @@ const SfxItemSet* ScDocument::GetCondResult( SCCOL nCol, SCROW nRow, SCTAB nTab const SfxItemSet* ScDocument::GetCondResult( ScRefCellValue& rCell, const ScAddress& rPos, const ScConditionalFormatList& rList, - const std::vector<sal_uInt32>& rIndex ) const + const ScCondFormatIndexes& rIndex ) const { for (const auto& rItem : rIndex) { @@ -827,7 +827,7 @@ ScConditionalFormat* ScDocument::GetCondFormat( SCCOL nCol, SCROW nRow, SCTAB nTab ) const { sal_uInt32 nIndex = 0; - const std::vector<sal_uInt32>& rCondFormats = GetAttr(nCol, nRow, nTab, ATTR_CONDITIONAL)->GetCondFormatData(); + const ScCondFormatIndexes& rCondFormats = GetAttr(nCol, nRow, nTab, ATTR_CONDITIONAL)->GetCondFormatData(); if(!rCondFormats.empty()) nIndex = rCondFormats[0]; diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 678709a6657e..aef2e64ce579 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -272,7 +272,7 @@ void initColWidths(RowInfo* pRowInfo, const ScDocument* pDoc, double fColScale, } } -bool handleConditionalFormat(ScConditionalFormatList& rCondFormList, const std::vector<sal_uInt32>& rCondFormats, +bool handleConditionalFormat(ScConditionalFormatList& rCondFormList, const ScCondFormatIndexes& rCondFormats, CellInfo* pInfo, ScStyleSheetPool* pStlPool, const ScAddress& rAddr, bool& bHidden, bool& bHideFormula, bool bTabProtect) { @@ -522,7 +522,7 @@ void ScDocument::FillInfo( else bHidden = bHideFormula = false; - const std::vector<sal_uInt32>& rCondFormats = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); + const ScCondFormatIndexes& rCondFormats = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); bool bContainsCondFormat = !rCondFormats.empty(); do diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index f4656246bf22..2cff749ce135 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2181,7 +2181,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC // Run through all formats, so that each cell does not have to be // handled individually - const std::vector<sal_uInt32>& rCondFormatData = static_cast<const ScCondFormatItem*>(pCondItem)->GetCondFormatData(); + const ScCondFormatIndexes& rCondFormatData = static_cast<const ScCondFormatItem*>(pCondItem)->GetCondFormatData(); ScStyleSheetPool* pStylePool = pDocument->GetStyleSheetPool(); if (mpCondFormatList && pStylePool && !rCondFormatData.empty()) { diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 41754592410c..d0e8bb3e987d 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -631,7 +631,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, } const ScCondFormatItem& rCondFormatItem = pSrcPattern->GetItem(ATTR_CONDITIONAL); - const std::vector<sal_uInt32>& rCondFormatIndex = rCondFormatItem.GetCondFormatData(); + const ScCondFormatIndexes& rCondFormatIndex = rCondFormatItem.GetCondFormatData(); if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered ) { @@ -1648,7 +1648,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScPatternAttr* pSrcPattern = aCol[nCol].GetPattern(static_cast<SCROW>(nRow)); const ScCondFormatItem& rCondFormatItem = pSrcPattern->GetItem(ATTR_CONDITIONAL); - const std::vector<sal_uInt32>& rCondFormatIndex = rCondFormatItem.GetCondFormatData(); + const ScCondFormatIndexes& rCondFormatIndex = rCondFormatItem.GetCondFormatData(); if (bVertical) { diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index af0c0614e4d6..0c726ab498af 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -2551,7 +2551,7 @@ void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pE formula::FormulaGrammar::Grammar eGrammar = (bXML ? rDoc.GetStorageGrammar() : formula::FormulaGrammar::mapAPItoGrammar( bEnglish, bXML)); - const std::vector<sal_uInt32>& rIndex = + const ScCondFormatIndexes& rIndex = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); sal_uLong nIndex = 0; if(!rIndex.empty()) diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 23014303a12d..fdeadf51d9ab 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1962,7 +1962,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) const ScConditionalFormat* pCondFormat = nullptr; const ScPatternAttr* pPattern = pDoc->GetPattern(aPos.Col(), aPos.Row(), aPos.Tab()); ScConditionalFormatList* pList = pDoc->GetCondFormList(aPos.Tab()); - const std::vector<sal_uInt32>& rCondFormats = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); + const ScCondFormatIndexes& rCondFormats = pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData(); bool bContainsCondFormat = !rCondFormats.empty(); bool bCondFormatDlg = false; bool bContainsExistingCondFormat = false; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits