From 48c2f0b4b157e133605c99549893521775ede4da Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Mon, 23 Aug 2021 14:10:34 +0200 Subject: cache access in ConfigurationWrapper (tdf#105575) If we repeatedly hit a config item like this: officecfg::Office::Common::Drawinglayer::MaximumPaperWidth::get() the stuff in configmgr because quite a bottleneck. So cache the access objects in ConfigurationWrapper. This change only affects the auto-generated code we use for the C++ officecfg:: configuration API Change-Id: Ie2adefc2319dfb362f1ef814690120e13abae6fd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120866 Tested-by: Jenkins Reviewed-by: Noel Grandin --- comphelper/source/misc/configuration.cxx | 35 +++++++++++++++++++++++++++++--- include/comphelper/configuration.hxx | 5 +++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/comphelper/source/misc/configuration.cxx b/comphelper/source/misc/configuration.cxx index a03855b41c4b..3e8bb31ebb8a 100644 --- a/comphelper/source/misc/configuration.cxx +++ b/comphelper/source/misc/configuration.cxx @@ -10,9 +10,12 @@ #include #include +#include #include +#include #include +#include #include #include #include @@ -128,10 +131,36 @@ bool comphelper::detail::ConfigurationWrapper::isReadOnly(OUString const & path) != 0; } -css::uno::Any comphelper::detail::ConfigurationWrapper::getPropertyValue( - OUString const & path) const +css::uno::Any comphelper::detail::ConfigurationWrapper::getPropertyValue(css::uno::Reference< css::uno::XComponentContext > const & context, + OUString const & path) { - return access_->getByHierarchicalName(path); + // Cache the configuration access, since some of the keys are used in hot code. + // Note that this cache is only used by the officecfg:: auto-generated code, using it for anything + // else would be unwise because the cache could end up containing stale entries. + static std::mutex gMutex; + static std::map> gAccessMap; + + sal_Int32 idx = path.lastIndexOf("/"); + assert(idx!=-1); + OUString parentPath = path.copy(0, idx); + OUString childName = path.copy(idx+1); + + std::scoped_lock aGuard(gMutex); + + // check cache + auto it = gAccessMap.find(parentPath); + if (it != gAccessMap.end()) + return it->second->getByName(childName); + + // not in the cache, look it up + css::uno::Reference< css::lang::XMultiServiceFactory > provider = css::configuration::theDefaultProvider::get( + context ); + css::uno::Any arg(css::beans::NamedValue("nodepath", css::uno::Any(parentPath))); + css::uno::Reference< css::container::XNameAccess > access(provider->createInstanceWithArguments( + "com.sun.star.configuration.ConfigurationAccess", + { arg }), css::uno::UNO_QUERY_THROW); + gAccessMap.emplace(parentPath, access); + return access->getByName(childName); } void comphelper::detail::ConfigurationWrapper::setPropertyValue( diff --git a/include/comphelper/configuration.hxx b/include/comphelper/configuration.hxx index 1ed37dcd45c3..27344e7a3672 100644 --- a/include/comphelper/configuration.hxx +++ b/include/comphelper/configuration.hxx @@ -97,7 +97,8 @@ public: bool isReadOnly(OUString const & path) const; - css::uno::Any getPropertyValue(OUString const & path) const; + static css::uno::Any getPropertyValue(css::uno::Reference< css::uno::XComponentContext > const & context, + OUString const & path); static void setPropertyValue( std::shared_ptr< ConfigurationChanges > const & batch, @@ -210,7 +211,7 @@ template< typename T, typename U > struct ConfigurationProperty // Folding this into one statement causes a bogus error at least with // Red Hat GCC 4.6.2-1: css::uno::Any a( - detail::ConfigurationWrapper::get(context).getPropertyValue( + detail::ConfigurationWrapper::getPropertyValue(context, T::path())); return detail::Convert< U >::fromAny(a); } -- cgit