From 427f6b307aa35fc921aa8d8538b8c653219bb065 Mon Sep 17 00:00:00 2001 From: Kevin Smith 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 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::iterator it = children_.begin(); while (it != children_.end()) { ContactRosterItem* contact = dynamic_cast(*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 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 +#include #include #include @@ -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)> onUserAction; void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();} void removeFilter(RosterFilter *filter); @@ -49,6 +52,7 @@ class Roster { std::vector children_; std::vector items_; std::vector filters_; + std::map > 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, JID::CompareType compareType = JID::WithoutResource) : presence_(presence), compareType_(compareType) { + SetPresence(boost::shared_ptr 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