diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-06-23 08:51:05 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-06-30 17:53:36 +0200 |
commit | cf15c4dad74e31a035c0d1ca899dfbef4da90ad2 (patch) | |
tree | c0f2704bc1388420e5ca9167eb12f91bb96771a6 /sw/source/core | |
parent | d2cbf5d1aba6a2a74b0e6ca99cb27242f9582a94 (diff) |
tdf#135316 optimise SwCharFormats::FindFormatByName
reduces load time by 10%
Change-Id: Ic5c90588825592245d09f8ebe03b13e34676496a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117699
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'sw/source/core')
-rw-r--r-- | sw/source/core/doc/docfmt.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/doc/number.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/txtnode/chrfmt.cxx | 77 | ||||
-rw-r--r-- | sw/source/core/undo/rolbck.cxx | 2 | ||||
-rw-r--r-- | sw/source/core/unocore/unosett.cxx | 13 | ||||
-rw-r--r-- | sw/source/core/unocore/unostyle.cxx | 2 |
7 files changed, 91 insertions, 22 deletions
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index f6ccbb799b92..7f07cf62e99c 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -845,7 +845,7 @@ SwCharFormat *SwDoc::MakeCharFormat( const OUString &rFormatName, bool bBroadcast ) { SwCharFormat *pFormat = new SwCharFormat( GetAttrPool(), rFormatName, pDerivedFrom ); - mpCharFormatTable->push_back( pFormat ); + mpCharFormatTable->insert( pFormat ); pFormat->SetAuto(false); getIDocumentState().SetModified(); @@ -1926,7 +1926,11 @@ void SwDoc::RenameFormat(SwFormat & rFormat, const OUString & sNewName, } } - rFormat.SetName(sNewName); + // name change means the o3tl::sorted_array is not property sorted + if (rFormat.Which() == RES_CHRFMT) + mpCharFormatTable->SetFormatNameAndReindex(static_cast<SwCharFormat*>(&rFormat), sNewName); + else + rFormat.SetName(sNewName); if (bBroadcast) BroadcastStyleOperation(sNewName, eFamily, SfxHintId::StyleSheetModified); diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index ae2f24a92a8a..b1ed62e0bccc 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -113,6 +113,8 @@ using namespace ::com::sun::star; using namespace ::com::sun::star::document; +constexpr OUStringLiteral DEFAULT_CHAR_FORMAT_NAME = u"Character style"; + /* * global functions... */ @@ -223,7 +225,7 @@ SwDoc::SwDoc() mpDfltFrameFormat( new SwFrameFormat( GetAttrPool(), "Frameformat", nullptr ) ), mpEmptyPageFormat( new SwFrameFormat( GetAttrPool(), "Empty Page", mpDfltFrameFormat.get() ) ), mpColumnContFormat( new SwFrameFormat( GetAttrPool(), "Columncontainer", mpDfltFrameFormat.get() ) ), - mpDfltCharFormat( new SwCharFormat( GetAttrPool(), "Character style", nullptr ) ), + mpDfltCharFormat( new SwCharFormat( GetAttrPool(), DEFAULT_CHAR_FORMAT_NAME, nullptr ) ), mpDfltTextFormatColl( new SwTextFormatColl( GetAttrPool(), "Paragraph style" ) ), mpDfltGrfFormatColl( new SwGrfFormatColl( GetAttrPool(), "Graphikformatvorlage" ) ), mpFrameFormatTable( new SwFrameFormats() ), @@ -296,7 +298,7 @@ SwDoc::SwDoc() */ /* Formats */ mpFrameFormatTable->push_back(mpDfltFrameFormat.get()); - mpCharFormatTable->push_back(mpDfltCharFormat.get()); + mpCharFormatTable->insert(mpDfltCharFormat.get()); /* FormatColls */ // TXT @@ -531,7 +533,6 @@ SwDoc::~SwDoc() * now. */ mpFrameFormatTable->erase( mpFrameFormatTable->begin() ); - mpCharFormatTable->erase( mpCharFormatTable->begin() ); #if HAVE_FEATURE_DBCONNECTIVITY // On load, SwDBManager::setEmbeddedName() may register a data source. @@ -728,7 +729,7 @@ void SwDoc::ClearDoc() mpTextFormatCollTable->DeleteAndDestroy(2, mpTextFormatCollTable->size()); mpTextFormatCollTable->DeleteAndDestroy(1, mpTextFormatCollTable->size()); mpGrfFormatCollTable->DeleteAndDestroy(1, mpGrfFormatCollTable->size()); - mpCharFormatTable->DeleteAndDestroy(1, mpCharFormatTable->size()); + mpCharFormatTable->DeleteAndDestroyAll(/*keepDefault*/true); if( getIDocumentLayoutAccess().GetCurrentViewShell() ) { diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx index 9bd2f27283b9..045d58f63fde 100644 --- a/sw/source/core/doc/number.cxx +++ b/sw/source/core/doc/number.cxx @@ -872,7 +872,7 @@ SwNumRule& SwNumRule::CopyNumRule( SwDoc& rDoc, const SwNumRule& rNumRule ) { Set( n, rNumRule.maFormats[ n ].get() ); if( maFormats[ n ] && maFormats[ n ]->GetCharFormat() && - !rDoc.GetCharFormats()->IsAlive(maFormats[n]->GetCharFormat())) + !rDoc.GetCharFormats()->ContainsFormat(maFormats[n]->GetCharFormat())) { // If we copy across different Documents, then copy the // corresponding CharFormat into the new Document. diff --git a/sw/source/core/txtnode/chrfmt.cxx b/sw/source/core/txtnode/chrfmt.cxx index 04301067ec23..3ee46ee3e8e8 100644 --- a/sw/source/core/txtnode/chrfmt.cxx +++ b/sw/source/core/txtnode/chrfmt.cxx @@ -20,7 +20,7 @@ #include <libxml/xmlwriter.h> #include <charfmt.hxx> -#include <docary.hxx> +#include <charformats.hxx> void SwCharFormat::dumpAsXml(xmlTextWriterPtr pWriter) const { @@ -39,4 +39,79 @@ void SwCharFormats::dumpAsXml(xmlTextWriterPtr pWriter) const (void)xmlTextWriterEndElement(pWriter); } +SwCharFormats::SwCharFormats() + : m_PosIndex(m_Array.get<0>()) + , m_NameIndex(m_Array.get<1>()) +{ +} + +SwCharFormats::~SwCharFormats() +{ + // default char format is owned by SwDoc + DeleteAndDestroyAll(true); +} + +SwCharFormats::const_iterator SwCharFormats::find(const SwCharFormat* x) const +{ + ByName::iterator it + = m_NameIndex.find(boost::make_tuple(x->GetName(), const_cast<SwCharFormat*>(x))); + return m_Array.project<0>(it); +} + +SwCharFormats::ByName::const_iterator SwCharFormats::findByName(const OUString& name) const +{ + return m_NameIndex.find(boost::make_tuple(name)); +} + +SwCharFormat* SwCharFormats::FindFormatByName(const OUString& rName) const +{ + auto it = findByName(rName); + if (it != m_NameIndex.end()) + return *it; + return nullptr; +} + +void SwCharFormats::DeleteAndDestroyAll(bool keepDefault) +{ + if (empty()) + return; + const int _offset = keepDefault ? 1 : 0; + for (const_iterator it = begin() + _offset; it != end(); ++it) + { + assert(!(*it)->HasName(u"Character style")); + delete *it; + } + if (_offset) + m_PosIndex.erase(begin() + _offset, end()); + else + m_Array.clear(); +} + +void SwCharFormats::insert(SwCharFormat* x) +{ + assert(!ContainsFormat(x)); + m_PosIndex.push_back(x); +} + +void SwCharFormats::erase(const_iterator const& position) { m_PosIndex.erase(position); } + +bool SwCharFormats::ContainsFormat(SwCharFormat* x) const { return find(x) != end(); } + +bool SwCharFormats::IsAlive(SwCharFormat const* const p) const { return find(p) != end(); } + +/** Need to call this when the format name changes */ +void SwCharFormats::SetFormatNameAndReindex(SwCharFormat* v, const OUString& sNewName) +{ + auto it = find(v); + erase(it); + v->SetName(sNewName); + insert(v); +} + +size_t SwCharFormats::GetPos(const SwCharFormat* p) const +{ + auto it = find(p); + return it == end() ? SIZE_MAX : it - begin(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx index 402f1486654b..cf308182c60b 100644 --- a/sw/source/core/undo/rolbck.cxx +++ b/sw/source/core/undo/rolbck.cxx @@ -254,7 +254,7 @@ void SwHistorySetText::SetInDoc( SwDoc* pDoc, bool ) if ( RES_TXTATR_CHARFMT == m_pAttr->Which() ) { // ask the Doc if the CharFormat still exists - if (!pDoc->GetCharFormats()->IsAlive(static_cast<SwFormatCharFormat&>(*m_pAttr).GetCharFormat())) + if (!pDoc->GetCharFormats()->ContainsFormat(static_cast<SwFormatCharFormat&>(*m_pAttr).GetCharFormat())) return; // do not set, format does not exist } diff --git a/sw/source/core/unocore/unosett.cxx b/sw/source/core/unocore/unosett.cxx index 186b0e98116e..101a70f10ada 100644 --- a/sw/source/core/unocore/unosett.cxx +++ b/sw/source/core/unocore/unosett.cxx @@ -1589,21 +1589,10 @@ void SwXNumberingRules::SetPropertiesToNumFormat( } else if (pLocalDoc) { - const SwCharFormats* pFormats = pLocalDoc->GetCharFormats(); - const size_t nChCount = pFormats->size(); - SwCharFormat* pCharFormat = nullptr; if (!sCharFormatName.isEmpty()) { - for(size_t j = 0; j< nChCount; ++j) - { - SwCharFormat* pTmp = (*pFormats)[j]; - if(pTmp->GetName() == sCharFormatName) - { - pCharFormat = pTmp; - break; - } - } + pCharFormat = pLocalDoc->FindCharFormatByName(sCharFormatName); if(!pCharFormat) { diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx index a6a14abef2dc..86d9381b8573 100644 --- a/sw/source/core/unocore/unostyle.cxx +++ b/sw/source/core/unocore/unostyle.cxx @@ -891,7 +891,7 @@ uno::Any XStyleFamily::getByName(const OUString& rName) throw uno::RuntimeException(); SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName, m_rEntry.m_eFamily); if(!pBase) - throw container::NoSuchElementException(); + throw container::NoSuchElementException(rName); uno::Reference<style::XStyle> xStyle = FindStyle(sStyleName); if(!xStyle.is()) xStyle = m_rEntry.m_fCreateStyle(m_pBasePool, m_pDocShell, m_rEntry.m_eFamily == SfxStyleFamily::Frame ? pBase->GetName() : sStyleName); |