From 427f6b307aa35fc921aa8d8538b8c653219bb065 Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Sun, 18 Apr 2010 19:03:21 +0100 Subject: Improve roster performance through map lookups on operations diff --git a/Swiften/Roster/Roster.cpp b/Swiften/Roster/Roster.cpp index e6640e2..8c2aa0e 100644 --- a/Swiften/Roster/Roster.cpp +++ b/Swiften/Roster/Roster.cpp @@ -56,12 +56,14 @@ void Roster::handleUserAction(boost::shared_ptr<UserRosterAction> action) { void Roster::addContact(const JID& jid, const String& name, const String& group) { ContactRosterItem *item = new ContactRosterItem(jid, name, getGroup(group), widgetFactory_); items_.push_back(item); + itemMap_[jid.toBare()].push_back(item); item->onUserAction.connect(boost::bind(&Roster::handleUserAction, this, _1)); filterItem(item); } void Roster::removeContact(const JID& jid) { + itemMap_.erase(jid.toBare()); std::vector<RosterItem*>::iterator it = children_.begin(); while (it != children_.end()) { ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); @@ -91,6 +93,21 @@ void Roster::removeContactFromGroup(const JID& jid, const String& groupName) { void Roster::applyOnItems(const RosterItemOperation& operation) { + if (operation.requiresLookup()) { + applyOnItem(operation, operation.lookupJID()); + } else { + applyOnAllItems(operation); + } +} + +void Roster::applyOnItem(const RosterItemOperation& operation, const JID& jid) { + foreach (RosterItem* item, itemMap_[jid]) { + operation(item); + filterItem(item); + } +} + +void Roster::applyOnAllItems(const RosterItemOperation& operation) { std::deque<RosterItem*> queue(children_.begin(), children_.end()); while (!queue.empty()) { RosterItem* item = *queue.begin(); diff --git a/Swiften/Roster/Roster.h b/Swiften/Roster/Roster.h index 2e88c5d..5fc3cfb 100644 --- a/Swiften/Roster/Roster.h +++ b/Swiften/Roster/Roster.h @@ -14,6 +14,7 @@ #include "Swiften/Roster/RosterFilter.h" #include <vector> +#include <map> #include <boost/signal.hpp> #include <boost/shared_ptr.hpp> @@ -35,6 +36,8 @@ class Roster { void removeContact(const JID& jid); void removeContactFromGroup(const JID& jid, const String& group); void applyOnItems(const RosterItemOperation& operation); + void applyOnAllItems(const RosterItemOperation& operation); + void applyOnItem(const RosterItemOperation& operation, const JID& jid); boost::signal<void (boost::shared_ptr<UserRosterAction>)> onUserAction; void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();} void removeFilter(RosterFilter *filter); @@ -49,6 +52,7 @@ class Roster { std::vector<RosterItem*> children_; std::vector<RosterItem*> items_; std::vector<RosterFilter*> filters_; + std::map<JID, std::vector<RosterItem*> > itemMap_; }; } diff --git a/Swiften/Roster/RosterItemOperation.h b/Swiften/Roster/RosterItemOperation.h index a41ed6e..a901fb4 100644 --- a/Swiften/Roster/RosterItemOperation.h +++ b/Swiften/Roster/RosterItemOperation.h @@ -13,8 +13,14 @@ namespace Swift { class RosterItemOperation { public: - virtual ~RosterItemOperation() {} + RosterItemOperation(bool requiresLookup = false, const JID& lookupJID = JID()) : requiresLookup_(requiresLookup), lookupJID_(lookupJID) {}; + virtual ~RosterItemOperation() {}; + bool requiresLookup() const {return requiresLookup_;}; + const JID& lookupJID() const {return lookupJID_;}; virtual void operator() (RosterItem*) const = 0; + private: + bool requiresLookup_; + JID lookupJID_; }; } diff --git a/Swiften/Roster/SetAvatar.h b/Swiften/Roster/SetAvatar.h index 3274d10..2b22188 100644 --- a/Swiften/Roster/SetAvatar.h +++ b/Swiften/Roster/SetAvatar.h @@ -18,7 +18,7 @@ class RosterItem; class SetAvatar : public RosterItemOperation { public: - SetAvatar(const JID& jid, const String& path, JID::CompareType compareType = JID::WithoutResource) : jid_(jid), path_(path), compareType_(compareType) { + SetAvatar(const JID& jid, const String& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) { } virtual void operator() (RosterItem* item) const { diff --git a/Swiften/Roster/SetName.h b/Swiften/Roster/SetName.h index 17bc2ea..33dd521 100644 --- a/Swiften/Roster/SetName.h +++ b/Swiften/Roster/SetName.h @@ -16,7 +16,7 @@ class RosterItem; class SetName : public RosterItemOperation { public: - SetName(const String& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : name_(name), jid_(jid), compareType_(compareType) { + SetName(const String& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), name_(name), jid_(jid), compareType_(compareType) { } virtual void operator() (RosterItem* item) const { diff --git a/Swiften/Roster/SetPresence.h b/Swiften/Roster/SetPresence.h index c4151bc..9cc3ba9 100644 --- a/Swiften/Roster/SetPresence.h +++ b/Swiften/Roster/SetPresence.h @@ -18,7 +18,7 @@ class RosterItem; class SetPresence : public RosterItemOperation { public: - SetPresence(boost::shared_ptr<Presence> presence, JID::CompareType compareType = JID::WithoutResource) : presence_(presence), compareType_(compareType) { + SetPresence(boost::shared_ptr<Presence> presence, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, presence->getFrom().toBare()), presence_(presence), compareType_(compareType) { } virtual void operator() (RosterItem* item) const { -- cgit v0.10.2-6-g49f6