[Libreoffice-commits] core.git: 9 commits - configmgr/source filter/source vcl/source

Michael Meeks michael.meeks at collabora.com
Sat Jun 28 06:36:18 PDT 2014


 configmgr/source/access.cxx                |   75 ++++++++++++---
 configmgr/source/access.hxx                |    8 +
 configmgr/source/childaccess.cxx           |   41 +++++---
 configmgr/source/childaccess.hxx           |    5 -
 configmgr/source/components.cxx            |    2 
 configmgr/source/data.cxx                  |   10 --
 configmgr/source/data.hxx                  |    3 
 configmgr/source/groupnode.cxx             |    2 
 configmgr/source/localizedpropertynode.cxx |    2 
 configmgr/source/localizedvaluenode.cxx    |   10 +-
 configmgr/source/localizedvaluenode.hxx    |    8 +
 configmgr/source/node.hxx                  |    5 -
 configmgr/source/nodemap.cxx               |   20 +++-
 configmgr/source/nodemap.hxx               |   42 ++++++++
 configmgr/source/propertynode.cxx          |    7 +
 configmgr/source/propertynode.hxx          |    1 
 configmgr/source/setnode.cxx               |    2 
 configmgr/source/valueparser.cxx           |   67 +++++++-------
 configmgr/source/writemodfile.cxx          |    2 
 configmgr/source/xcuparser.cxx             |    6 -
 filter/source/config/cache/filtercache.cxx |  136 ++++++++++++++++++-----------
 filter/source/config/cache/filtercache.hxx |    5 +
 vcl/source/app/settings.cxx                |    4 
 vcl/source/app/svapp.cxx                   |    8 +
 24 files changed, 320 insertions(+), 151 deletions(-)

New commits:
commit 5fd43384a443aee09dd4c98ffd79572f44f13000
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Jun 28 14:29:34 2014 +0100

    configmgr: accelerate getPropertyValue.
    
    Change-Id: Ie0460c8db6b1e7fcc9bab1f5e9ae1fbd00987994

diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx
index 6aeabb4..7402897 100644
--- a/configmgr/source/access.cxx
+++ b/configmgr/source/access.cxx
@@ -734,12 +734,12 @@ css::uno::Any Access::getPropertyValue(OUString const & PropertyName)
 {
     assert(thisIs(IS_GROUP));
     osl::MutexGuard g(*lock_);
-    rtl::Reference< ChildAccess > child(getChild(PropertyName));
-    if (!child.is()) {
+
+    css::uno::Any value;
+    if (!getByNameFast(PropertyName, value))
         throw css::beans::UnknownPropertyException(
             PropertyName, static_cast< cppu::OWeakObject * >(this));
-    }
-    return child->asValue();
+    return value;
 }
 
 void Access::addPropertyChangeListener(
commit 546c7baec791aa3027a45cdde6c4c02bc073d002
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Jun 28 14:19:30 2014 +0100

    vcl: don't do expensive desktop probing in headless mode.
    
    Change-Id: I10d6493997b4f3bfab769340c990c01a26f3da20

diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index f9fee0b..80ca354 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1599,7 +1599,13 @@ bool Application::GetShowImeStatusWindowDefault()
 
 const OUString& Application::GetDesktopEnvironment()
 {
-    return SalGetDesktopEnvironment();
+    if (IsHeadlessModeEnabled())
+    {
+        static OUString aNone("none");
+        return aNone;
+    }
+    else
+        return SalGetDesktopEnvironment();
 }
 
 void Application::AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType, const OUString& rDocumentService)
commit 879aa54e895a56cb65f93ae98e6a9e7b08981a47
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Jun 28 14:18:32 2014 +0100

    configmgr: accelerate simple config key fetches.
    
    Avoid heap allocating UNO object wrappers for the underlying Node
    structures only to convert to Any and immediately free them agian
    when we can.
    
    Change-Id: Iae4612e9602f872f5d8cca2e516df594c9f1118c

diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx
index 665b3cd..6aeabb4 100644
--- a/configmgr/source/access.cxx
+++ b/configmgr/source/access.cxx
@@ -344,6 +344,42 @@ sal_Bool Access::hasElements() throw (css::uno::RuntimeException, std::exception
     return !getAllChildren().empty(); //TODO: optimize
 }
 
+bool Access::getByNameFast(const OUString & name, css::uno::Any & value)
+{
+    bool bGotValue = false;
+    rtl::Reference< ChildAccess > child;
+
+    if (getNode()->kind() != Node::KIND_LOCALIZED_PROPERTY)
+    { // try to get it directly
+        ModifiedChildren::iterator i(modifiedChildren_.find(name));
+        if (i != modifiedChildren_.end())
+        {
+            child = getModifiedChild(i);
+            if (child.is())
+            {
+                value = child->asValue();
+                bGotValue = true;
+            }
+        }
+        else
+        {
+            rtl::Reference< Node > node(getNode()->getMember(name));
+            if (!node.is())
+                return false;
+            bGotValue = ChildAccess::asSimpleValue(node, value, components_);
+        }
+    }
+
+    if (!bGotValue)
+    {
+        child = getChild(name);
+        if (!child.is())
+            return false;
+        value = child->asValue();
+    }
+    return true;
+}
+
 css::uno::Any Access::getByName(OUString const & aName)
     throw (
         css::container::NoSuchElementException,
@@ -352,12 +388,11 @@ css::uno::Any Access::getByName(OUString const & aName)
     assert(thisIs(IS_ANY));
     osl::MutexGuard g(*lock_);
     checkLocalizedPropertyAccess();
-    rtl::Reference< ChildAccess > child(getChild(aName));
-    if (!child.is()) {
+    css::uno::Any value;
+    if (!getByNameFast(aName, value))
         throw css::container::NoSuchElementException(
             aName, static_cast< cppu::OWeakObject * >(this));
-    }
-    return child->asValue();
+    return value;
 }
 
 css::uno::Sequence< OUString > Access::getElementNames()
@@ -852,15 +887,15 @@ css::uno::Sequence< css::uno::Any > Access::getPropertyValues(
     assert(thisIs(IS_GROUP));
     osl::MutexGuard g(*lock_);
     css::uno::Sequence< css::uno::Any > vals(aPropertyNames.getLength());
-    for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i) {
-        rtl::Reference< ChildAccess > child(getChild(aPropertyNames[i]));
-        if (!child.is()) {
+
+    for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i)
+    {
+        if (!getByNameFast(aPropertyNames[i], vals[i]))
             throw css::uno::RuntimeException(
                 "configmgr getPropertyValues inappropriate property name",
                 static_cast< cppu::OWeakObject * >(this));
-        }
-        vals[i] = child->asValue();
     }
+
     return vals;
 }
 
@@ -1988,6 +2023,15 @@ rtl::Reference< ChildAccess > Access::getModifiedChild(
         ? childIterator->second.child : rtl::Reference< ChildAccess >();
 }
 
+rtl::Reference< ChildAccess > Access::createUnmodifiedChild(
+                const OUString &name, const rtl::Reference< Node > &node)
+{
+    rtl::Reference< ChildAccess > child(
+        new ChildAccess(components_, getRootAccess(), this, name, node));
+    cachedChildren_[name] = child.get();
+    return child;
+}
+
 rtl::Reference< ChildAccess > Access::getUnmodifiedChild(
     OUString const & name)
 {
@@ -2008,10 +2052,7 @@ rtl::Reference< ChildAccess > Access::getUnmodifiedChild(
             return child;
         }
     }
-    rtl::Reference< ChildAccess > child(
-        new ChildAccess(components_, getRootAccess(), this, name, node));
-    cachedChildren_[name] = child.get();
-    return child;
+    return createUnmodifiedChild(name,node);
 }
 
 rtl::Reference< ChildAccess > Access::getSubChild(OUString const & path) {
diff --git a/configmgr/source/access.hxx b/configmgr/source/access.hxx
index 4dbc14e..de35555 100644
--- a/configmgr/source/access.hxx
+++ b/configmgr/source/access.hxx
@@ -497,10 +497,14 @@ private:
     rtl::Reference< ChildAccess > getSubChild(OUString const & path);
 
     bool setChildProperty(
-        OUString const & name, com::sun::star::uno::Any const & value,
+        OUString const & name, css::uno::Any const & value,
         Modifications * localModifications);
 
-    com::sun::star::beans::Property asProperty();
+    css::beans::Property asProperty();
+
+    bool getByNameFast(const OUString & name, css::uno::Any & value);
+    rtl::Reference< ChildAccess > createUnmodifiedChild(const OUString &name,
+                                                        const rtl::Reference< Node > &node);
 
     void checkFinalized();
 
diff --git a/configmgr/source/childaccess.cxx b/configmgr/source/childaccess.cxx
index dc7822e..259d968 100644
--- a/configmgr/source/childaccess.cxx
+++ b/configmgr/source/childaccess.cxx
@@ -252,33 +252,48 @@ void ChildAccess::setProperty(
     localModifications->add(getRelativePath());
 }
 
-css::uno::Any ChildAccess::asValue() {
+
+css::uno::Any ChildAccess::asValue()
+{
     if (changedValue_.get() != 0) {
         return *changedValue_;
     }
-    switch (node_->kind()) {
-    case Node::KIND_PROPERTY:
-        return static_cast< PropertyNode * >(node_.get())->getValue(
-            getComponents());
-    case Node::KIND_LOCALIZED_PROPERTY:
+    css::uno::Any value;
+    if (!asSimpleValue(node_, value, getComponents()))
+    {
+        if (node_->kind() == Node::KIND_LOCALIZED_PROPERTY)
         {
             OUString locale(getRootAccess()->getLocale());
             if (!Components::allLocales(locale)) {
                 rtl::Reference< ChildAccess > child(getChild("*" + locale));
                 // As a last resort, return a nil value even though it may be
                 // illegal for the given property:
-                return child.is() ? child->asValue() : css::uno::Any();
+                if (child.is())
+                    return child->asValue();
             }
         }
-        break;
+        value = css::uno::makeAny(
+                        css::uno::Reference< css::uno::XInterface >(
+                                static_cast< cppu::OWeakObject * >(this)));
+    }
+    return value;
+}
+
+/// Can we quickly extract a simple value into value ? if so returns true
+bool ChildAccess::asSimpleValue(const rtl::Reference< Node > &rNode,
+                                css::uno::Any &value,
+                                Components &components)
+{
+    switch (rNode->kind()) {
+    case Node::KIND_PROPERTY:
+        value = static_cast< PropertyNode * >(rNode.get())->getValue(components);
+        return true;
     case Node::KIND_LOCALIZED_VALUE:
-        return static_cast< LocalizedValueNode * >(node_.get())->getValue();
+        value = static_cast< LocalizedValueNode * >(rNode.get())->getValue();
+        return true;
     default:
-        break;
+        return false;
     }
-    return css::uno::makeAny(
-        css::uno::Reference< css::uno::XInterface >(
-            static_cast< cppu::OWeakObject * >(this)));
 }
 
 void ChildAccess::commitChanges(bool valid, Modifications * globalModifications)
diff --git a/configmgr/source/childaccess.hxx b/configmgr/source/childaccess.hxx
index 1f14d67..ee336fa 100644
--- a/configmgr/source/childaccess.hxx
+++ b/configmgr/source/childaccess.hxx
@@ -113,7 +113,10 @@ public:
         com::sun::star::uno::Any const & value,
         Modifications * localModifications);
 
-    com::sun::star::uno::Any asValue();
+    css::uno::Any asValue();
+    static bool asSimpleValue(const rtl::Reference< Node > &rNode,
+                              css::uno::Any &value,
+                              Components &components);
 
     void commitChanges(bool valid, Modifications * globalModifications);
 
commit e820df579d9be4c1f9bb1ad8f02a8072c69b52da
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Sat Jun 28 09:36:20 2014 +0100

    filters: Batch fetch filter config properties.
    
    Also re-use a single set of OUString property names in
    a sequence rather than re-allocating them constantly.
    
    Change-Id: I7f0afc52363e57ea0c63f46f1e1f63cb752bb302

diff --git a/filter/source/config/cache/filtercache.cxx b/filter/source/config/cache/filtercache.cxx
index def3991..ba84e5c 100644
--- a/filter/source/config/cache/filtercache.cxx
+++ b/filter/source/config/cache/filtercache.cxx
@@ -33,6 +33,8 @@
 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
 #include <com/sun/star/beans/NamedValue.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
 #include <com/sun/star/beans/XProperty.hpp>
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <com/sun/star/beans/Property.hpp>
@@ -58,10 +60,53 @@ FilterCache::FilterCache()
     : BaseLock    (                                        )
     , m_eFillState(E_CONTAINS_NOTHING                      )
 {
+    int i = 0;
+    OUString sStandardProps[9];
+
+    sStandardProps[i++] = PROPNAME_USERDATA;
+    sStandardProps[i++] = PROPNAME_TEMPLATENAME;
+    // E_READ_UPDATE only above
+    sStandardProps[i++] = PROPNAME_TYPE;
+    sStandardProps[i++] = PROPNAME_FILEFORMATVERSION;
+    sStandardProps[i++] = PROPNAME_UICOMPONENT;
+    sStandardProps[i++] = PROPNAME_FILTERSERVICE;
+    sStandardProps[i++] = PROPNAME_DOCUMENTSERVICE;
+    sStandardProps[i++] = PROPNAME_EXPORTEXTENSION;
+    sStandardProps[i++] = PROPNAME_FLAGS; // must be last.
+    assert(i == SAL_N_ELEMENTS(sStandardProps));
+
+    // E_READ_NOTHING -> creative nothingness.
+    m_aStandardProps[E_READ_STANDARD] =
+        css::uno::Sequence< OUString >(sStandardProps + 2, 7);
+    m_aStandardProps[E_READ_UPDATE] =
+        css::uno::Sequence< OUString >(sStandardProps, 2);
+    m_aStandardProps[E_READ_ALL] =
+        css::uno::Sequence< OUString >(sStandardProps,
+                                       SAL_N_ELEMENTS(sStandardProps));
+
+    i = 0;
+    OUString sTypeProps[7];
+    sTypeProps[i++] = PROPNAME_MEDIATYPE;
+    // E_READ_UPDATE only above
+    sTypeProps[i++] = PROPNAME_PREFERREDFILTER;
+    sTypeProps[i++] = PROPNAME_DETECTSERVICE;
+    sTypeProps[i++] = PROPNAME_URLPATTERN;
+    sTypeProps[i++] = PROPNAME_EXTENSIONS;
+    sTypeProps[i++] = PROPNAME_PREFERRED;
+    sTypeProps[i++] = PROPNAME_CLIPBOARDFORMAT;
+    assert(i == SAL_N_ELEMENTS(sTypeProps));
+
+    // E_READ_NOTHING -> more creative nothingness.
+    m_aTypeProps[E_READ_STANDARD] =
+        css::uno::Sequence< OUString >(sTypeProps + 1, 6);
+    m_aTypeProps[E_READ_UPDATE] =
+        css::uno::Sequence< OUString >(sTypeProps, 1);
+    m_aTypeProps[E_READ_ALL] =
+        css::uno::Sequence< OUString >(sTypeProps,
+                                       SAL_N_ELEMENTS(sTypeProps));
 }
 
 
-
 FilterCache::~FilterCache()
 {
     if (m_xTypesChglisteners.is())
@@ -1615,79 +1660,71 @@ CacheItem FilterCache::impl_loadItem(const css::uno::Reference< css::container::
     {
         case E_TYPE :
         {
-            // read standard properties of a type
-            if (
-                (eOption == E_READ_STANDARD) ||
-                (eOption == E_READ_ALL     )
-               )
+            assert(eOption >= 0 && eOption <= E_READ_ALL);
+            css::uno::Sequence< OUString > &rNames = m_aTypeProps[eOption];
+
+            // read standard properties of a filter
+            if (rNames.getLength() > 0)
             {
-                aItem[PROPNAME_PREFERREDFILTER] = xItem->getByName(PROPNAME_PREFERREDFILTER);
-                aItem[PROPNAME_DETECTSERVICE  ] = xItem->getByName(PROPNAME_DETECTSERVICE  );
-                aItem[PROPNAME_URLPATTERN     ] = xItem->getByName(PROPNAME_URLPATTERN     );
-                aItem[PROPNAME_EXTENSIONS     ] = xItem->getByName(PROPNAME_EXTENSIONS     );
-                aItem[PROPNAME_PREFERRED      ] = xItem->getByName(PROPNAME_PREFERRED      );
-                aItem[PROPNAME_CLIPBOARDFORMAT] = xItem->getByName(PROPNAME_CLIPBOARDFORMAT);
+                css::uno::Reference< css::beans::XMultiPropertySet >
+                    xPropSet( xItem, css::uno::UNO_QUERY_THROW);
+                css::uno::Sequence< css::uno::Any > aValues;
+                aValues = xPropSet->getPropertyValues(rNames);
+
+                for (sal_Int32 i = 0; i < aValues.getLength(); i++)
+                    aItem[rNames[i]] = aValues[i];
             }
+
             // read optional properties of a type
             // no else here! Is an additional switch ...
-            if (
-                (eOption == E_READ_UPDATE) ||
-                (eOption == E_READ_ALL   )
-               )
-            {
-                aItem[PROPNAME_MEDIATYPE      ] = xItem->getByName(PROPNAME_MEDIATYPE      );
+            if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
                 impl_readPatchUINames(xItem, aItem);
-            }
         }
         break;
 
 
         case E_FILTER :
         {
+            assert(eOption >= 0 && eOption <= E_READ_ALL);
+            css::uno::Sequence< OUString > &rNames = m_aStandardProps[eOption];
+
             // read standard properties of a filter
-            if (
-                (eOption == E_READ_STANDARD) ||
-                (eOption == E_READ_ALL     )
-               )
+            if (rNames.getLength() > 0)
             {
-                aItem[PROPNAME_TYPE             ] = xItem->getByName(PROPNAME_TYPE             );
-                aItem[PROPNAME_FILEFORMATVERSION] = xItem->getByName(PROPNAME_FILEFORMATVERSION);
-                aItem[PROPNAME_UICOMPONENT      ] = xItem->getByName(PROPNAME_UICOMPONENT      );
-                aItem[PROPNAME_FILTERSERVICE    ] = xItem->getByName(PROPNAME_FILTERSERVICE    );
-                aItem[PROPNAME_DOCUMENTSERVICE  ] = xItem->getByName(PROPNAME_DOCUMENTSERVICE  );
-                aItem[PROPNAME_EXPORTEXTENSION  ] = xItem->getByName(PROPNAME_EXPORTEXTENSION  );
-
-                // special handling for flags! Convert it from a list of names to its
-                // int representation ...
-                css::uno::Sequence< OUString > lFlagNames;
-                if (xItem->getByName(PROPNAME_FLAGS) >>= lFlagNames)
-                    aItem[PROPNAME_FLAGS] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
+                css::uno::Reference< css::beans::XMultiPropertySet >
+                    xPropSet( xItem, css::uno::UNO_QUERY_THROW);
+                css::uno::Sequence< css::uno::Any > aValues;
+                aValues = xPropSet->getPropertyValues(rNames);
+
+                for (sal_Int32 i = 0; i < rNames.getLength(); i++)
+                {
+                    OUString &rPropName = rNames[i];
+                    if (i != rNames.getLength() - 1 || rPropName != PROPNAME_FLAGS)
+                        aItem[rPropName] = aValues[i];
+                    else
+                    {
+                        assert(rPropName == PROPNAME_FLAGS);
+                        // special handling for flags! Convert it from a list of names to its
+                        // int representation ...
+                        css::uno::Sequence< OUString > lFlagNames;
+                        if (aValues[i] >>= lFlagNames)
+                            aItem[rPropName] <<= FilterCache::impl_convertFlagNames2FlagField(lFlagNames);
+                    }
+                }
             }
-            // read optional properties of a filter
-            // no else here! Is an additional switch ...
-            if (
-                (eOption == E_READ_UPDATE) ||
-                (eOption == E_READ_ALL   )
-               )
-            {
-                aItem[PROPNAME_USERDATA    ] = xItem->getByName(PROPNAME_USERDATA    );
-                aItem[PROPNAME_TEMPLATENAME] = xItem->getByName(PROPNAME_TEMPLATENAME);
 //TODO remove it if moving of filter uinames to type uinames
 //       will be finished really
 #ifdef AS_ENABLE_FILTER_UINAMES
+            if (eOption == E_READ_UPDATE || eOption == E_READ_ALL)
                 impl_readPatchUINames(xItem, aItem);
 #endif // AS_ENABLE_FILTER_UINAMES
-            }
         }
         break;
 
-
         case E_FRAMELOADER :
         case E_CONTENTHANDLER :
-        {
             aItem[PROPNAME_TYPES] = xItem->getByName(PROPNAME_TYPES);
-        }
-        break;
+            break;
         default: break;
     }
 
@@ -2275,7 +2312,6 @@ OUString FilterCache::impl_searchContentHandlerForType(const OUString& sType) co
         const OUString& sItem = pIt->first;
         ::comphelper::SequenceAsHashMap lProps(pIt->second);
         OUStringList                    lTypes(lProps[PROPNAME_TYPES]);
-
         if (::std::find(lTypes.begin(), lTypes.end(), sType) != lTypes.end())
             return sItem;
     }
diff --git a/filter/source/config/cache/filtercache.hxx b/filter/source/config/cache/filtercache.hxx
index d405161..9a3a96d 100644
--- a/filter/source/config/cache/filtercache.hxx
+++ b/filter/source/config/cache/filtercache.hxx
@@ -235,6 +235,11 @@ class FilterCache : public BaseLock
         OUStringList m_lChangedFrameLoaders;
         OUStringList m_lChangedContentHandlers;
 
+        /// standard property names for filter config keyed by EReadOption
+        css::uno::Sequence< OUString > m_aStandardProps[4];
+
+        /// type property names for filter config keyed by EReadOption
+        css::uno::Sequence< OUString > m_aTypeProps[4];
 
         /// readonly acccess to the module configuration of OOo
         css::uno::Reference< css::container::XNameAccess > m_xModuleCfg;
commit f55ddffd7e81cc8f3314047a6aa62991e2d293b1
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Jun 26 15:12:04 2014 +0100

    configmgr: implement a single item cache for node lookup.
    
    Saves 13.5m cycles on a headless start, 1.3%.
    
    Change-Id: I73f0dd8a523f84c765a217ee95aea9bcc3db1b5d

diff --git a/configmgr/source/nodemap.cxx b/configmgr/source/nodemap.cxx
index 3c7c79a..4d823ce 100644
--- a/configmgr/source/nodemap.cxx
+++ b/configmgr/source/nodemap.cxx
@@ -32,16 +32,20 @@ namespace configmgr {
 void NodeMap::cloneInto(NodeMap * target) const
 {
     assert(target != 0 && target->empty());
-    NodeMapImpl clone(aImpl);
+    NodeMapImpl clone(maImpl);
     for (NodeMapImpl::iterator i(clone.begin()); i != clone.end(); ++i) {
         i->second = i->second->clone(true);
     }
-    std::swap(clone, target->aImpl);
+    std::swap(clone, target->maImpl);
+    target->clearCache();
 }
 
 rtl::Reference< Node > NodeMap::findNode(int layer, OUString const & name) const
 {
-    const_iterator i(aImpl.find(name));
+    const_iterator i;
+    if (maCache == end() || maCache->first != name)
+        maCache = const_cast< NodeMap *>(this)->maImpl.find(name);
+    i = maCache;
     return i == end() || i->second->getLayer() > layer
         ? rtl::Reference< Node >() : i->second;
 }
diff --git a/configmgr/source/nodemap.hxx b/configmgr/source/nodemap.hxx
index 3745b862..9742054 100644
--- a/configmgr/source/nodemap.hxx
+++ b/configmgr/source/nodemap.hxx
@@ -30,34 +30,41 @@ namespace configmgr {
 typedef std::map< OUString, rtl::Reference< Node > > NodeMapImpl;
 class NodeMap
 {
-    NodeMapImpl aImpl;
+    NodeMapImpl maImpl;
+
     NodeMap(const NodeMap &rMap) :
-        aImpl(rMap.aImpl) {}
+        maImpl(rMap.maImpl) { clearCache(); }
 
   public:
     typedef NodeMapImpl::iterator iterator;
     typedef NodeMapImpl::const_iterator const_iterator;
     typedef NodeMapImpl::value_type value_type;
 
-     NodeMap() {}
+     NodeMap() { clearCache(); }
     ~NodeMap() {}
-    void clear() { aImpl.clear(); }
-    bool empty() const { return aImpl.empty(); }
-    void erase(const iterator &it) { aImpl.erase(it); }
-    void erase(const OUString &aStr) { aImpl.erase(aStr); }
-    iterator find(const OUString &aStr) { return aImpl.find( aStr ); }
+    bool empty() const { return maImpl.empty(); }
+    iterator find(const OUString &aStr) { return maImpl.find( aStr ); }
+
+    const_iterator find(const OUString &aStr) const { return maImpl.find( aStr ); }
+    iterator begin() { return maImpl.begin(); }
+    const_iterator begin() const { return maImpl.begin(); }
 
-    const_iterator find(const OUString &aStr) const { return aImpl.find( aStr ); }
-    rtl::Reference<Node> &operator[](const OUString &aStr) { return aImpl[aStr]; }
-    iterator begin() { return aImpl.begin(); }
-    const_iterator begin() const { return aImpl.begin(); }
+    iterator end() { return maImpl.end(); }
+    const_iterator end() const { return maImpl.end(); }
 
-    iterator end() { return aImpl.end(); }
-    const_iterator end() const { return aImpl.end(); }
-    std::pair<iterator,bool> insert(const value_type &vt) { return aImpl.insert(vt); }
+    rtl::Reference<Node> &operator[](const OUString &aStr) { return maImpl[aStr]; clearCache(); }
+    std::pair<iterator,bool> insert(const value_type &vt) { return maImpl.insert(vt); clearCache(); }
+    void clear() { maImpl.clear(); clearCache(); }
+    void erase(const iterator &it) { maImpl.erase(it); clearCache(); }
+    void erase(const OUString &aStr) { maImpl.erase(aStr); clearCache(); }
 
     rtl::Reference< Node > findNode(int layer, OUString const & name) const;
     void cloneInto(NodeMap * target) const;
+
+private:
+    // We get a large number of repeated identical lookups.
+    mutable const_iterator maCache;
+    void clearCache() { maCache = maImpl.end(); }
 };
 
 }
commit 8bfdc161e6417a4f057f66af6c44299e22ad5a9c
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Jun 26 14:49:38 2014 +0100

    configmgr: re-factor findNode and clone into NodeMap.
    
    Change-Id: Ib170b3cec17402e38bf5555e21f83f44d70bb574

diff --git a/configmgr/source/components.cxx b/configmgr/source/components.cxx
index c9abcef..8dcf88d 100644
--- a/configmgr/source/components.cxx
+++ b/configmgr/source/components.cxx
@@ -357,7 +357,7 @@ void Components::removeExtensionXcuFile(
             rtl::Reference< Node > node;
             for (Path::const_iterator j(i->begin()); j != i->end(); ++j) {
                 parent = node;
-                node = Data::findNode(Data::NO_LAYER, *map, *j);
+                node = map->findNode(Data::NO_LAYER, *j);
                 if (!node.is()) {
                     break;
                 }
diff --git a/configmgr/source/data.cxx b/configmgr/source/data.cxx
index 7337a3f..2383940 100644
--- a/configmgr/source/data.cxx
+++ b/configmgr/source/data.cxx
@@ -179,14 +179,6 @@ bool Data::equalTemplateNames(
     }
 }
 
-rtl::Reference< Node > Data::findNode(
-    int layer, NodeMap const & map, OUString const & name)
-{
-    NodeMap::const_iterator i(map.find(name));
-    return i == map.end() || i->second->getLayer() > layer
-        ? rtl::Reference< Node >() : i->second;
-}
-
 Data::Data(): root_(new RootNode) {}
 
 rtl::Reference< Node > Data::resolvePathRepresentation(
@@ -298,7 +290,7 @@ rtl::Reference< Node > Data::resolvePathRepresentation(
 rtl::Reference< Node > Data::getTemplate(
     int layer, OUString const & fullName) const
 {
-    return findNode(layer, templates, fullName);
+    return templates.findNode(layer, fullName);
 }
 
 NodeMap & Data::getComponents() const {
diff --git a/configmgr/source/data.hxx b/configmgr/source/data.hxx
index 1dd6f0a..2e564d9 100644
--- a/configmgr/source/data.hxx
+++ b/configmgr/source/data.hxx
@@ -67,9 +67,6 @@ struct Data: private boost::noncopyable {
     static bool equalTemplateNames(
         OUString const & shortName, OUString const & longName);
 
-    static rtl::Reference< Node > findNode(
-        int layer, NodeMap const & map, OUString const & name);
-
     Data();
 
     rtl::Reference< Node > resolvePathRepresentation(
diff --git a/configmgr/source/groupnode.cxx b/configmgr/source/groupnode.cxx
index a1d5b58..dabade5 100644
--- a/configmgr/source/groupnode.cxx
+++ b/configmgr/source/groupnode.cxx
@@ -59,7 +59,7 @@ int GroupNode::getMandatory() const {
 GroupNode::GroupNode(GroupNode const & other, bool keepTemplateName):
     Node(other), extensible_(other.extensible_), mandatory_(other.mandatory_)
 {
-    cloneNodeMap(other.members_, &members_);
+    other.members_.cloneInto(&members_);
     if (keepTemplateName) {
         templateName_ = other.templateName_;
     }
diff --git a/configmgr/source/localizedpropertynode.cxx b/configmgr/source/localizedpropertynode.cxx
index ed861d1..3b55dcf 100644
--- a/configmgr/source/localizedpropertynode.cxx
+++ b/configmgr/source/localizedpropertynode.cxx
@@ -50,7 +50,7 @@ LocalizedPropertyNode::LocalizedPropertyNode(
     LocalizedPropertyNode const & other):
     Node(other), staticType_(other.staticType_), nillable_(other.nillable_)
 {
-    cloneNodeMap(other.members_, &members_);
+    other.members_.cloneInto(&members_);
 }
 
 LocalizedPropertyNode::~LocalizedPropertyNode() {}
diff --git a/configmgr/source/nodemap.cxx b/configmgr/source/nodemap.cxx
index 683dc70..3c7c79a 100644
--- a/configmgr/source/nodemap.cxx
+++ b/configmgr/source/nodemap.cxx
@@ -29,13 +29,21 @@
 
 namespace configmgr {
 
-void cloneNodeMap(NodeMap const & source, NodeMap * target) {
+void NodeMap::cloneInto(NodeMap * target) const
+{
     assert(target != 0 && target->empty());
-    NodeMap clone(source);
-    for (NodeMap::iterator i(clone.begin()); i != clone.end(); ++i) {
+    NodeMapImpl clone(aImpl);
+    for (NodeMapImpl::iterator i(clone.begin()); i != clone.end(); ++i) {
         i->second = i->second->clone(true);
     }
-    std::swap(clone, *target);
+    std::swap(clone, target->aImpl);
+}
+
+rtl::Reference< Node > NodeMap::findNode(int layer, OUString const & name) const
+{
+    const_iterator i(aImpl.find(name));
+    return i == end() || i->second->getLayer() > layer
+        ? rtl::Reference< Node >() : i->second;
 }
 
 }
diff --git a/configmgr/source/nodemap.hxx b/configmgr/source/nodemap.hxx
index 7b8d126..3745b862 100644
--- a/configmgr/source/nodemap.hxx
+++ b/configmgr/source/nodemap.hxx
@@ -31,6 +31,9 @@ typedef std::map< OUString, rtl::Reference< Node > > NodeMapImpl;
 class NodeMap
 {
     NodeMapImpl aImpl;
+    NodeMap(const NodeMap &rMap) :
+        aImpl(rMap.aImpl) {}
+
   public:
     typedef NodeMapImpl::iterator iterator;
     typedef NodeMapImpl::const_iterator const_iterator;
@@ -39,7 +42,7 @@ class NodeMap
      NodeMap() {}
     ~NodeMap() {}
     void clear() { aImpl.clear(); }
-    bool empty() { return aImpl.empty(); }
+    bool empty() const { return aImpl.empty(); }
     void erase(const iterator &it) { aImpl.erase(it); }
     void erase(const OUString &aStr) { aImpl.erase(aStr); }
     iterator find(const OUString &aStr) { return aImpl.find( aStr ); }
@@ -52,9 +55,10 @@ class NodeMap
     iterator end() { return aImpl.end(); }
     const_iterator end() const { return aImpl.end(); }
     std::pair<iterator,bool> insert(const value_type &vt) { return aImpl.insert(vt); }
-};
 
-void cloneNodeMap(NodeMap const & source, NodeMap * target);
+    rtl::Reference< Node > findNode(int layer, OUString const & name) const;
+    void cloneInto(NodeMap * target) const;
+};
 
 }
 
diff --git a/configmgr/source/setnode.cxx b/configmgr/source/setnode.cxx
index d00253b..ad259cc 100644
--- a/configmgr/source/setnode.cxx
+++ b/configmgr/source/setnode.cxx
@@ -95,7 +95,7 @@ SetNode::SetNode(SetNode const & other, bool keepTemplateName):
     additionalTemplateNames_(other.additionalTemplateNames_),
     mandatory_(other.mandatory_)
 {
-    cloneNodeMap(other.members_, &members_);
+    other.members_.cloneInto(&members_);
     if (keepTemplateName) {
         templateName_ = other.templateName_;
     }
diff --git a/configmgr/source/writemodfile.cxx b/configmgr/source/writemodfile.cxx
index 4ce07cb..09b1d01 100644
--- a/configmgr/source/writemodfile.cxx
+++ b/configmgr/source/writemodfile.cxx
@@ -568,7 +568,7 @@ void writeModFile(
     {
         writeModifications(
             components, tmp.handle, "", rtl::Reference< Node >(), j->first,
-            Data::findNode(Data::NO_LAYER, data.getComponents(), j->first),
+            data.getComponents().findNode(Data::NO_LAYER, j->first),
             j->second);
     }
     writeData_(tmp.handle, RTL_CONSTASCII_STRINGPARAM("</oor:items>\n"));
diff --git a/configmgr/source/xcuparser.cxx b/configmgr/source/xcuparser.cxx
index ae3090c..abbae16 100644
--- a/configmgr/source/xcuparser.cxx
+++ b/configmgr/source/xcuparser.cxx
@@ -291,8 +291,8 @@ void XcuParser::handleComponentData(xmlreader::XmlReader & reader) {
         }
     }
     rtl::Reference< Node > node(
-        Data::findNode(
-            valueParser_.getLayer(), data_.getComponents(), componentName_));
+        data_.getComponents().findNode(valueParser_.getLayer(),
+                                       componentName_));
     if (!node.is()) {
         SAL_WARN(
             "configmgr",
@@ -788,7 +788,7 @@ void XcuParser::handleGroupNode(
         }
     }
     rtl::Reference< Node > child(
-        Data::findNode(valueParser_.getLayer(), group->getMembers(), name));
+        group->getMembers().findNode(valueParser_.getLayer(), name));
     if (!child.is()) {
         SAL_WARN(
             "configmgr",
commit ff1d2ba5010821bb4f526dc7a51a99b9e6c4dd25
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Jun 26 14:24:20 2014 +0100

    configmgr: hide NodeMap implementation.
    
    Change-Id: I57c81b5ec7a6541a825e42f9b68e7c5fa98f316f

diff --git a/configmgr/source/node.hxx b/configmgr/source/node.hxx
index 6537973..8bd000c 100644
--- a/configmgr/source/node.hxx
+++ b/configmgr/source/node.hxx
@@ -25,11 +25,10 @@
 #include <rtl/ref.hxx>
 #include <salhelper/simplereferenceobject.hxx>
 
-#include "nodemap.hxx"
-
-
 namespace configmgr {
 
+class NodeMap;
+
 class Node: public salhelper::SimpleReferenceObject {
 public:
     enum Kind {
diff --git a/configmgr/source/nodemap.hxx b/configmgr/source/nodemap.hxx
index a304cc2..7b8d126 100644
--- a/configmgr/source/nodemap.hxx
+++ b/configmgr/source/nodemap.hxx
@@ -23,13 +23,36 @@
 #include <sal/config.h>
 #include <map>
 #include <rtl/ref.hxx>
-
+#include <node.hxx>
 
 namespace configmgr {
 
-class Node;
-
-typedef std::map< OUString, rtl::Reference< Node > > NodeMap;
+typedef std::map< OUString, rtl::Reference< Node > > NodeMapImpl;
+class NodeMap
+{
+    NodeMapImpl aImpl;
+  public:
+    typedef NodeMapImpl::iterator iterator;
+    typedef NodeMapImpl::const_iterator const_iterator;
+    typedef NodeMapImpl::value_type value_type;
+
+     NodeMap() {}
+    ~NodeMap() {}
+    void clear() { aImpl.clear(); }
+    bool empty() { return aImpl.empty(); }
+    void erase(const iterator &it) { aImpl.erase(it); }
+    void erase(const OUString &aStr) { aImpl.erase(aStr); }
+    iterator find(const OUString &aStr) { return aImpl.find( aStr ); }
+
+    const_iterator find(const OUString &aStr) const { return aImpl.find( aStr ); }
+    rtl::Reference<Node> &operator[](const OUString &aStr) { return aImpl[aStr]; }
+    iterator begin() { return aImpl.begin(); }
+    const_iterator begin() const { return aImpl.begin(); }
+
+    iterator end() { return aImpl.end(); }
+    const_iterator end() const { return aImpl.end(); }
+    std::pair<iterator,bool> insert(const value_type &vt) { return aImpl.insert(vt); }
+};
 
 void cloneNodeMap(NodeMap const & source, NodeMap * target);
 
diff --git a/configmgr/source/valueparser.cxx b/configmgr/source/valueparser.cxx
index a12d072..183b510 100644
--- a/configmgr/source/valueparser.cxx
+++ b/configmgr/source/valueparser.cxx
@@ -359,7 +359,7 @@ bool ValueParser::endElement() {
                     if (i == members.end()) {
                         pLVNode = new LocalizedValueNode(layer_);
                         members.insert(
-                            NodeMap::value_type(localizedName_, pLVNode));
+                            NodeMap::value_type(localizedName_, pLVNode ));
                     } else {
                         pLVNode = static_cast< LocalizedValueNode * >(i->second.get());
                     }
commit f692c61ab26b425cd8e6a36b8e229bbf7caff335
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Jun 26 13:47:54 2014 +0100

    configmgr: avoid constructing duplicating and freeing Any's
    
    Accelerates headless startup by 6.5m cycles or so, 0.6% or
    so but something.
    
    Change-Id: I9edca3d0c1c81d865e8369fee5cf193da7adb97c

diff --git a/configmgr/source/localizedvaluenode.cxx b/configmgr/source/localizedvaluenode.cxx
index 27b977d..3c7bbdc 100644
--- a/configmgr/source/localizedvaluenode.cxx
+++ b/configmgr/source/localizedvaluenode.cxx
@@ -33,6 +33,10 @@ LocalizedValueNode::LocalizedValueNode(int layer, css::uno::Any const & value):
     Node(layer), value_(value)
 {}
 
+LocalizedValueNode::LocalizedValueNode(int layer):
+    Node(layer)
+{}
+
 rtl::Reference< Node > LocalizedValueNode::clone(bool) const {
     return new LocalizedValueNode(*this);
 }
@@ -42,9 +46,11 @@ OUString LocalizedValueNode::getTemplateName() const {
 }
 
 
-void LocalizedValueNode::setValue(int layer, css::uno::Any const & value) {
+void LocalizedValueNode::setValue(int layer, css::uno::Any const & value)
+{
     setLayer(layer);
-    value_ = value;
+    if (&value != &value_)
+        value_ = value;
 }
 
 LocalizedValueNode::LocalizedValueNode(LocalizedValueNode const & other):
diff --git a/configmgr/source/localizedvaluenode.hxx b/configmgr/source/localizedvaluenode.hxx
index 08635f8..98b012a 100644
--- a/configmgr/source/localizedvaluenode.hxx
+++ b/configmgr/source/localizedvaluenode.hxx
@@ -32,13 +32,19 @@ namespace configmgr {
 
 class LocalizedValueNode: public Node {
 public:
+    LocalizedValueNode(int layer);
     LocalizedValueNode(int layer, com::sun::star::uno::Any const & value);
 
     virtual rtl::Reference< Node > clone(bool keepTemplateName) const SAL_OVERRIDE;
 
     virtual OUString getTemplateName() const SAL_OVERRIDE;
 
-    com::sun::star::uno::Any getValue() const { return value_;}
+    com::sun::star::uno::Any  getValue() const { return value_;}
+    com::sun::star::uno::Any *getValuePtr(int layer)
+    {
+        setLayer(layer);
+        return &value_;
+    }
 
     void setValue(int layer, com::sun::star::uno::Any const & value);
 
diff --git a/configmgr/source/propertynode.cxx b/configmgr/source/propertynode.cxx
index 4560913..102423a 100644
--- a/configmgr/source/propertynode.cxx
+++ b/configmgr/source/propertynode.cxx
@@ -69,6 +69,13 @@ void PropertyNode::setValue(int layer, css::uno::Any const & value) {
     externalDescriptor_ = "";
 }
 
+com::sun::star::uno::Any *PropertyNode::getValuePtr(int layer)
+{
+    setLayer(layer);
+    externalDescriptor_ = "";
+    return &value_;
+}
+
 void PropertyNode::setExternal(int layer, OUString const & descriptor) {
     assert(!descriptor.isEmpty());
     setLayer(layer);
diff --git a/configmgr/source/propertynode.hxx b/configmgr/source/propertynode.hxx
index 60108e7..805efa1 100644
--- a/configmgr/source/propertynode.hxx
+++ b/configmgr/source/propertynode.hxx
@@ -48,6 +48,7 @@ public:
     com::sun::star::uno::Any getValue(Components & components);
 
     void setValue(int layer, com::sun::star::uno::Any const & value);
+    com::sun::star::uno::Any *getValuePtr(int layer);
 
     void setExternal(int layer, OUString const & descriptor);
 
diff --git a/configmgr/source/valueparser.cxx b/configmgr/source/valueparser.cxx
index 5c140f6..a12d072 100644
--- a/configmgr/source/valueparser.cxx
+++ b/configmgr/source/valueparser.cxx
@@ -345,32 +345,57 @@ bool ValueParser::endElement() {
     switch (state_) {
     case STATE_TEXT:
         {
-            css::uno::Any value;
+            css::uno::Any *pValue = NULL;
+
+            switch (node_->kind()) {
+            case Node::KIND_PROPERTY:
+                pValue = static_cast< PropertyNode * >(node_.get())->getValuePtr(layer_);
+                break;
+            case Node::KIND_LOCALIZED_PROPERTY:
+                {
+                    NodeMap & members = node_->getMembers();
+                    NodeMap::iterator i(members.find(localizedName_));
+                    LocalizedValueNode *pLVNode;
+                    if (i == members.end()) {
+                        pLVNode = new LocalizedValueNode(layer_);
+                        members.insert(
+                            NodeMap::value_type(localizedName_, pLVNode));
+                    } else {
+                        pLVNode = static_cast< LocalizedValueNode * >(i->second.get());
+                    }
+                    pValue = pLVNode->getValuePtr(layer_);
+                }
+                break;
+            default:
+                assert(false); // this cannot happen
+                return false;
+            }
+
             if (items_.empty()) {
-                value = parseValue(separator_, pad_.get(), type_);
+                *pValue = parseValue(separator_, pad_.get(), type_);
                 pad_.clear();
             } else {
                 switch (type_) {
                 case TYPE_BOOLEAN_LIST:
-                    value = convertItems< sal_Bool >();
+                    *pValue = convertItems< sal_Bool >();
                     break;
                 case TYPE_SHORT_LIST:
-                    value = convertItems< sal_Int16 >();
+                    *pValue = convertItems< sal_Int16 >();
                     break;
                 case TYPE_INT_LIST:
-                    value = convertItems< sal_Int32 >();
+                    *pValue = convertItems< sal_Int32 >();
                     break;
                 case TYPE_LONG_LIST:
-                    value = convertItems< sal_Int64 >();
+                    *pValue = convertItems< sal_Int64 >();
                     break;
                 case TYPE_DOUBLE_LIST:
-                    value = convertItems< double >();
+                    *pValue = convertItems< double >();
                     break;
                 case TYPE_STRING_LIST:
-                    value = convertItems< OUString >();
+                    *pValue = convertItems< OUString >();
                     break;
                 case TYPE_HEXBINARY_LIST:
-                    value = convertItems< css::uno::Sequence< sal_Int8 > >();
+                    *pValue = convertItems< css::uno::Sequence< sal_Int8 > >();
                     break;
                 default:
                     assert(false); // this cannot happen
@@ -378,30 +403,6 @@ bool ValueParser::endElement() {
                 }
                 items_.clear();
             }
-            switch (node_->kind()) {
-            case Node::KIND_PROPERTY:
-                static_cast< PropertyNode * >(node_.get())->setValue(
-                    layer_, value);
-                break;
-            case Node::KIND_LOCALIZED_PROPERTY:
-                {
-                    NodeMap & members = node_->getMembers();
-                    NodeMap::iterator i(members.find(localizedName_));
-                    if (i == members.end()) {
-                        members.insert(
-                            NodeMap::value_type(
-                                localizedName_,
-                                new LocalizedValueNode(layer_, value)));
-                    } else {
-                        static_cast< LocalizedValueNode * >(i->second.get())->
-                            setValue(layer_, value);
-                    }
-                }
-                break;
-            default:
-                assert(false); // this cannot happen
-                break;
-            }
             separator_ = OString();
             node_.clear();
         }
commit 115fd951e92a725ee6fca41e96d6b791ac66bd34
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu Jun 26 12:06:52 2014 +0100

    Avoid loading persona images in headless mode.
    
    Change-Id: Ie3bb69d93b97deab0830c2b45ba3428a8931a949

diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx
index 4174d5a..1e6050c 100644
--- a/vcl/source/app/settings.cxx
+++ b/vcl/source/app/settings.cxx
@@ -2108,6 +2108,10 @@ static void setupPersonaHeaderFooter( WhichPersona eWhich, OUString& rHeaderFoot
     if ( !xContext.is() )
         return;
 
+    // don't burn time loading images we don't need.
+    if ( Application::IsHeadlessModeEnabled() )
+        return;
+
     // read from the configuration
     OUString aPersona( officecfg::Office::Common::Misc::Persona::get( xContext ) );
     OUString aPersonaSettings( officecfg::Office::Common::Misc::PersonaSettings::get( xContext ) );


More information about the Libreoffice-commits mailing list