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 1dd71d79e15bd8098e7c17c8fcea3748592a902f Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Mar 31 10:51:32 2023 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Fri Mar 31 09:01:02 2023 +0000 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> diff --git a/sw/source/filter/xml/xmlimp.cxx b/sw/source/filter/xml/xmlimp.cxx index a0dc24ed5162..6ea193f2bc3f 100644 --- a/sw/source/filter/xml/xmlimp.cxx +++ b/sw/source/filter/xml/xmlimp.cxx @@ -323,7 +323,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 e23c7399d5ea..4c528155f24c 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 ); @@ -163,6 +167,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 1dadf0bcedda..08bcd27d11b8 100644 --- a/sw/source/filter/xml/xmltbli.cxx +++ b/sw/source/filter/xml/xmltbli.cxx @@ -1173,7 +1173,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 ); }