summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2013-11-14 09:49:15 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2013-11-14 23:53:51 -0500
commitae79b40f725ac28f8940bc9d97fd137088c20a22 (patch)
tree0ad551d0f576ba0c2e5bfb9622d32af9d3ee135a
parentf076c62d5cce5425d903b861827c83c16a040b86 (diff)
Optimize SvtBroadcaster for insertion.
This helps file load performance at the slight overhead during editing. That said, the overhead during editing is only in theory (not measured) and shouldn't be that much even in theory. Change-Id: If22ea34acb0cda311575ac3ed8ce1a8eb69ae33a
-rw-r--r--include/svl/broadcast.hxx14
-rw-r--r--svl/source/notify/broadcast.cxx30
2 files changed, 35 insertions, 9 deletions
diff --git a/include/svl/broadcast.hxx b/include/svl/broadcast.hxx
index 80d9568b6392..6a6bc03c6fd6 100644
--- a/include/svl/broadcast.hxx
+++ b/include/svl/broadcast.hxx
@@ -21,7 +21,7 @@
#include <svl/svldllapi.h>
-#include <boost/unordered_set.hpp>
+#include <vector>
class SvtListener;
class SfxHint;
@@ -31,11 +31,18 @@ class SVL_DLLPUBLIC SvtBroadcaster
public:
friend class SvtListener;
- typedef boost::unordered_set<SvtListener*> ListenersType;
+ typedef std::vector<SvtListener*> ListenersType;
private:
const SvtBroadcaster& operator=(const SvtBroadcaster &); // verboten
+ /**
+ * Ensure that the container doesn't contain any duplicated listener
+ * entries. As a side effect, the listeners get sorted by pointer values
+ * after this call.
+ */
+ void Normalize();
+
void Add( SvtListener* p );
void Remove( SvtListener* p );
@@ -55,7 +62,8 @@ public:
private:
ListenersType maListeners;
- bool mbDying;
+ bool mbDisposing:1;
+ bool mbNormalized:1;
};
diff --git a/svl/source/notify/broadcast.cxx b/svl/source/notify/broadcast.cxx
index 7e59e36e2ec7..96d34a7f6ced 100644
--- a/svl/source/notify/broadcast.cxx
+++ b/svl/source/notify/broadcast.cxx
@@ -62,32 +62,49 @@ public:
}
+void SvtBroadcaster::Normalize()
+{
+ if (mbNormalized)
+ return;
+
+ std::sort(maListeners.begin(), maListeners.end());
+ ListenersType::iterator itUniqueEnd = std::unique(maListeners.begin(), maListeners.end());
+ maListeners.erase(itUniqueEnd, maListeners.end());
+ mbNormalized = true;
+}
+
void SvtBroadcaster::Add( SvtListener* p )
{
- maListeners.insert(p);
+ maListeners.push_back(p);
+ mbNormalized = false;
}
void SvtBroadcaster::Remove( SvtListener* p )
{
- if (mbDying)
+ if (mbDisposing)
return;
- maListeners.erase(p);
+ Normalize();
+ std::pair<ListenersType::iterator,ListenersType::iterator> r =
+ std::equal_range(maListeners.begin(), maListeners.end(), p);
+
+ if (r.first != r.second)
+ maListeners.erase(r.first, r.second);
if (maListeners.empty())
ListenersGone();
}
-SvtBroadcaster::SvtBroadcaster() : mbDying(false) {}
+SvtBroadcaster::SvtBroadcaster() : mbDisposing(false), mbNormalized(false) {}
SvtBroadcaster::SvtBroadcaster( const SvtBroadcaster &rBC ) :
- maListeners(rBC.maListeners), mbDying(false)
+ maListeners(rBC.maListeners), mbDisposing(false), mbNormalized(rBC.mbNormalized)
{
std::for_each(maListeners.begin(), maListeners.end(), StartListeningHandler(*this));
}
SvtBroadcaster::~SvtBroadcaster()
{
- mbDying = true;
+ mbDisposing = true;
Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
// unregister all listeners.
@@ -96,6 +113,7 @@ SvtBroadcaster::~SvtBroadcaster()
void SvtBroadcaster::Broadcast( const SfxHint &rHint )
{
+ Normalize();
std::for_each(maListeners.begin(), maListeners.end(), NotifyHandler(*this, rHint));
}