diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-25 09:40:27 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-03-25 09:47:17 +0100 |
commit | f5ae42f9344a523e586fdcca4f0e670ee2a4d821 (patch) | |
tree | d3da7cc164644c254c9de0943823549d038f6c2b | |
parent | 0a9cc5ce4d2d814587dba16ed8acc7eb38e347c8 (diff) |
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
-rw-r--r-- | writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 43 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLStreamImpl.hxx | 5 |
2 files changed, 44 insertions, 4 deletions
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index 6f639e624261..284d369381a0 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 4db03a29ada4..2230944efef0 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, |