sw/source/filter/xml/xmlimp.cxx | 3 ++- sw/source/filter/xml/xmlimp.hxx | 7 +++++++ sw/source/filter/xml/xmltbli.cxx | 14 +++++++++++++- 3 files changed, 22 insertions(+), 2 deletions(-)
New commits: commit 2d3a182c1e311977764d97a4a7d1dce796ec9b18 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Mar 31 10:51:32 2023 +0300 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Wed Apr 5 11:06:27 2023 +0200 tdf#154486: use importer-local map to deduplicate table names ... instead of SwDoc::GetUniqueTableName. The latter is expensive with many tables, has O(n^2) complexity with rather large O, and in corner cases of thousands tables with no or duplicate names, is unacceptably slow. Changes the test case import time from 39 s to 23 s on my system. Change-Id: Ia461c860d56cbbfdcb25bacbb9cca4961ced885e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149817 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149960 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index 2cb58cf2aa47..5ef66a1bf36f 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -324,7 +324,8 @@ SwXMLImport::SwXMLImport( m_bBlock( false ), m_bOrganizerMode( false ), m_bInititedXForms( false ), - m_pDoc( nullptr ) + m_pDoc( nullptr ), + m_sDefTableName(SwResId(STR_TABLE_DEFNAME)) { InitItemImport(); } diff --git a/sw/source/filter/xml/xmlimp.hxx b/sw/source/filter/xml/xmlimp.hxx index 22f012c4dbfc..8791958fc69c 100644 --- a/sw/source/filter/xml/xmlimp.hxx +++ b/sw/source/filter/xml/xmlimp.hxx @@ -84,6 +84,10 @@ class SwXMLImport: public SvXMLImport SwDoc* m_pDoc; // cached for getDoc() + // Optimization for new table name lookup + OUString m_sDefTableName; // See STR_TABLE_DEFNAME + std::map<OUString, sal_uInt32> m_aTableNameMap; // Last used indices for duplicating table names + void InitItemImport(); void FinitItemImport(); void UpdateTextCollConditions( SwDoc *pDoc ); @@ -167,6 +171,9 @@ public: const SwDoc* getDoc() const; SwDoc* getDoc(); + + const OUString& GetDefTableName() { return m_sDefTableName; } + std::map<OUString, sal_uInt32>& GetTableNameMap() { return m_aTableNameMap; } }; inline const SvXMLImportItemMapper& SwXMLImport::GetTableItemMapper() const diff --git a/sw/source/filter/xml/xmltbli.cxx b/sw/source/filter/xml/xmltbli.cxx index 44ae125d30b0..fec24079defc 100644 --- a/sw/source/filter/xml/xmltbli.cxx +++ b/sw/source/filter/xml/xmltbli.cxx @@ -1178,7 +1178,19 @@ SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport, } if( sTableName.isEmpty() ) { - sTableName = pDoc->GetUniqueTableName(); + // Optimization: use import's own map to create unique names, because + // SwDoc::GetUniqueTableName scans all the already present tables, + // builds a bitset using rather complex rules, and that has quadratic + // complexity. Try once, then fallback to SwDoc::GetUniqueTableName + auto& tableNameMap = rImport.GetTableNameMap(); + sal_Int32 nextIx = ++tableNameMap[aName]; + OUString test = aName.isEmpty() + ? OUString(rImport.GetDefTableName() + OUString::number(nextIx)) + : OUString(aName + "_" + OUString::number(nextIx)); + if (const SwTableFormat* pExisting = pDoc->FindTableFormatByName(test); !pExisting) + sTableName = test; + else + sTableName = pDoc->GetUniqueTableName(); GetImport().GetTextImport() ->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_TABLE, aName, sTableName ); }