[Libreoffice-commits] core.git: writerfilter/source
Miklos Vajna
vmiklos at collabora.co.uk
Tue Mar 25 01:47:43 PDT 2014
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 <vmiklos at 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,
More information about the Libreoffice-commits
mailing list