summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2014-03-25 09:40:27 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-03-25 09:47:17 +0100
commitf5ae42f9344a523e586fdcca4f0e670ee2a4d821 (patch)
treed3da7cc164644c254c9de0943823549d038f6c2b
parent0a9cc5ce4d2d814587dba16ed8acc7eb38e347c8 (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.cxx43
-rw-r--r--writerfilter/source/ooxml/OOXMLStreamImpl.hxx5
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,