comphelper/source/misc/accessibleeventnotifier.cxx | 24 +++++++++------------ include/comphelper/interfacecontainer4.hxx | 4 +++ 2 files changed, 15 insertions(+), 13 deletions(-)
New commits: commit e3c6c36e6fffeafa235e9230901e81b08866e6b2 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue May 2 13:53:02 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue May 2 18:57:33 2023 +0200 tdf#137544 reduce cost of AccessibleEventNotifier the ListenerContainer can be a moveable type, which means we can store it in a node and avoid an indirection and an extra allocation. Also use unordered_map to speed up lookups. Change-Id: I888f0418b035e459cce3facd956ba51db97335a4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151265 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/comphelper/source/misc/accessibleeventnotifier.cxx b/comphelper/source/misc/accessibleeventnotifier.cxx index f8bd5a1170e8..ad9edf574a9f 100644 --- a/comphelper/source/misc/accessibleeventnotifier.cxx +++ b/comphelper/source/misc/accessibleeventnotifier.cxx @@ -21,9 +21,10 @@ #include <com/sun/star/accessibility/XAccessibleEventListener.hpp> #include <comphelper/interfacecontainer4.hxx> +#include <limits> #include <map> #include <memory> -#include <limits> +#include <unordered_map> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -36,7 +37,7 @@ typedef std::pair< AccessibleEventNotifier::TClientId, AccessibleEventObject > ClientEvent; typedef ::comphelper::OInterfaceContainerHelper4<XAccessibleEventListener> ListenerContainer; -typedef std::map< AccessibleEventNotifier::TClientId, ListenerContainer* > ClientMap; +typedef std::unordered_map< AccessibleEventNotifier::TClientId, ListenerContainer > ClientMap; /// key is the end of the interval, value is the start of the interval typedef std::map<AccessibleEventNotifier::TClientId, @@ -154,10 +155,8 @@ AccessibleEventNotifier::TClientId AccessibleEventNotifier::registerClient() // generate a new client id TClientId nNewClientId = generateId( ); - // the event listeners for the new client - ListenerContainer * pNewListeners = new ListenerContainer(); // add the client - gaClients.emplace( nNewClientId, pNewListeners ); + gaClients.emplace( nNewClientId, ListenerContainer{} ); // outta here return nNewClientId; @@ -173,7 +172,6 @@ void AccessibleEventNotifier::revokeClient( const TClientId _nClient ) return; // remove it from the clients map - delete aClientPos->second; gaClients.erase( aClientPos ); releaseId(_nClient); } @@ -189,7 +187,7 @@ void AccessibleEventNotifier::revokeClientNotifyDisposing( return; // notify the listeners - std::unique_ptr<ListenerContainer> pListeners(aClientPos->second); + ListenerContainer aListeners(std::move(aClientPos->second)); // we do not need the entry in the clients map anymore // (do this before actually notifying, because some client @@ -203,7 +201,7 @@ void AccessibleEventNotifier::revokeClientNotifyDisposing( aDisposalEvent.Source = _rxEventSource; // now really do the notification - pListeners->disposeAndClear( aGuard, aDisposalEvent ); + aListeners.disposeAndClear( aGuard, aDisposalEvent ); } sal_Int32 AccessibleEventNotifier::addEventListener( @@ -217,9 +215,9 @@ sal_Int32 AccessibleEventNotifier::addEventListener( return 0; if ( _rxListener.is() ) - aClientPos->second->addInterface( aGuard, _rxListener ); + aClientPos->second.addInterface( aGuard, _rxListener ); - return aClientPos->second->getLength(aGuard); + return aClientPos->second.getLength(aGuard); } sal_Int32 AccessibleEventNotifier::removeEventListener( @@ -233,9 +231,9 @@ sal_Int32 AccessibleEventNotifier::removeEventListener( return 0; if ( _rxListener.is() ) - aClientPos->second->removeInterface( aGuard, _rxListener ); + aClientPos->second.removeInterface( aGuard, _rxListener ); - return aClientPos->second->getLength(aGuard); + return aClientPos->second.getLength(aGuard); } void AccessibleEventNotifier::addEvent( const TClientId _nClient, const AccessibleEventObject& _rEvent ) @@ -251,7 +249,7 @@ void AccessibleEventNotifier::addEvent( const TClientId _nClient, const Accessib return; // since we're synchronous, again, we want to notify immediately - aListeners = aClientPos->second->getElements(aGuard); + aListeners = aClientPos->second.getElements(aGuard); } // default handling: loop through all listeners, and notify them diff --git a/include/comphelper/interfacecontainer4.hxx b/include/comphelper/interfacecontainer4.hxx index bfa3a3059212..1362ee1df741 100644 --- a/include/comphelper/interfacecontainer4.hxx +++ b/include/comphelper/interfacecontainer4.hxx @@ -231,6 +231,10 @@ public: void (SAL_CALL ListenerT::*NotificationMethod)(const EventT&), const EventT& Event) const; + // this is moveable, but not copyable + OInterfaceContainerHelper4(OInterfaceContainerHelper4&&) = default; + OInterfaceContainerHelper4& operator=(OInterfaceContainerHelper4&&) = default; + private: friend class OInterfaceIteratorHelper4<ListenerT>; o3tl::cow_wrapper<std::vector<css::uno::Reference<ListenerT>>,