writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 43 +++++++++++++++++++++++--- writerfilter/source/ooxml/OOXMLStreamImpl.hxx | 5 +++ 2 files changed, 44 insertions(+), 4 deletions(-)
New commits: commit f5ae42f9344a523e586fdcca4f0e670ee2a4d821 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Mar 25 09:40:27 2014 +0100 fdo#76563 DOCX import: speed up importing lots of hyperlinks The problem was that in writerfilter::ooxml::OOXMLStreamImpl::lcl_getTarget(), we went over the list of all hyperlinks for each request. Instead, let's do it once, and in the remaining cases just look up the result from a map. Numbers before on my machine (ms, load time): 2215, 2243, 2205 After: 1362, 1358, 1358 So that causes about 39% speedup for a non-debug build. Change-Id: Ib4718abbe834c5ba49a85469148b656e3c808041 diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index 6f639e6..284d369 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -93,6 +93,42 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> const OUString & rId, OUString & rDocumentTarget) { + static OUString sId("Id"); + static OUString sTarget("Target"); + static OUString sTargetMode("TargetMode"); + static OUString sExternal("External"); + if (maIdCache.empty()) + { + // Cache is empty? Then let's build it! + uno::Sequence< uno::Sequence<beans::StringPair> >aSeqs = xRelationshipAccess->getAllRelationships(); + for (sal_Int32 i = 0; i < aSeqs.getLength(); ++i) + { + const uno::Sequence<beans::StringPair>& rSeq = aSeqs[i]; + OUString aId; + OUString aTarget; + bool bExternal = false; + for (sal_Int32 j = 0; j < rSeq.getLength(); ++j) + { + const beans::StringPair& rPair = rSeq[j]; + if (rPair.First == sId) + aId = rPair.Second; + else if (rPair.First == sTarget) + aTarget = rPair.Second; + else if (rPair.First == sTargetMode && rPair.Second == sExternal) + bExternal = true; + } + // Only cache external targets, internal ones are more complex (see below) + if (bExternal) + maIdCache[aId] = aTarget; + } + } + + if (maIdCache.find(rId) != maIdCache.end()) + { + rDocumentTarget = maIdCache[rId]; + return true; + } + bool bFound = false; static uno::Reference< com::sun::star::uri::XUriReferenceFactory > xFac = ::com::sun::star::uri::UriReferenceFactory::create( mxContext ); // use '/' to representent the root of the zip package ( and provide a 'file' scheme to @@ -101,7 +137,6 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> uno::Reference< com::sun::star::uri::XUriReference > xBase = xFac->parse( OUString( "file:///" ) + msPath ); static OUString sType("Type"); - static OUString sId("Id"); static OUString sDocumentType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"); static OUString sStylesType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"); static OUString sNumberingType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"); @@ -142,9 +177,6 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> static OUString sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer"); static OUString sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header"); static OUString sOleObjectTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/oleObject"); - static OUString sTarget("Target"); - static OUString sTargetMode("TargetMode"); - static OUString sExternal("External"); static OUString sVBAProjectType("http://schemas.microsoft.com/office/2006/relationships/vbaProject"); OUString sStreamType; @@ -348,6 +380,9 @@ void OOXMLStreamImpl::init() openStreamElementByHierarchicalName (msTarget, embed::ElementModes::SEEKABLEREAD)); aAny >>= mxDocumentStream; + // Non-cached ID lookup works by accessing mxDocumentStream as an embed::XRelationshipAccess. + // So when it changes, we should empty the cache. + maIdCache.clear(); } } } diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx index 4db03a2..2230944 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.hxx @@ -19,6 +19,8 @@ #ifndef INCLUDED_OOXML_STREAM_IMPL_HXX #define INCLUDED_OOXML_STREAM_IMPL_HXX +#include <map> + #include <ooxml/OOXMLDocument.hxx> #include <comphelper/storagehelper.hxx> #include <com/sun/star/embed/XRelationshipAccess.hpp> @@ -51,6 +53,9 @@ class OOXMLStreamImpl : public OOXMLStream OUString msPath; OUString msTarget; + /// Cache holding an Id <-> Target map of external relations. + std::map<OUString, OUString> maIdCache; + bool lcl_getTarget(uno::Reference<embed::XRelationshipAccess> xRelationshipAccess, StreamType_t nStreamType, _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits