Bug 955366 - Use Maps and Sets in IRC code, convert buddies object. r=aleth.
authorPatrick Cloke <clokep@gmail.com>
Tue, 06 May 2014 20:28:51 -0400
changeset 16179 c6b03e55cb0ffe097bb33e8452ca9b32fe9f7767
parent 16178 fe1feb4737361f3e6b13543959d0a8073a66d7a3
child 16180 fe529f9dd6975c6ba574e0a083363c8aa5292efa
push id10115
push userclokep@gmail.com
push dateThu, 08 May 2014 14:05:31 +0000
treeherdercomm-central@da34b03c7e57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaleth
bugs955366
Bug 955366 - Use Maps and Sets in IRC code, convert buddies object. r=aleth.
chat/protocols/irc/irc.js
chat/protocols/irc/ircBase.jsm
chat/protocols/irc/ircWatchMonitor.jsm
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -4,16 +4,17 @@
 
 const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
 
 Cu.import("resource:///modules/imXPCOMUtils.jsm");
 Cu.import("resource:///modules/imServices.jsm");
 Cu.import("resource:///modules/ircUtils.jsm");
 Cu.import("resource:///modules/ircHandlers.jsm");
 Cu.import("resource:///modules/jsProtoHelper.jsm");
+Cu.import("resource:///modules/NormalizedMap.jsm");
 Cu.import("resource:///modules/socket.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DownloadUtils",
   "resource://gre/modules/DownloadUtils.jsm");
 
@@ -606,17 +607,17 @@ function ircConversation(aAccount, aName
 
   // Fetch correctly capitalized name.
   // Always request the info as it may be out of date.
   this._waitingForNick = true;
   this.requestBuddyInfo(aName);
 }
 ircConversation.prototype = {
   __proto__: GenericConvIMPrototype,
-  get buddy() this._account.getBuddy(this.name),
+  get buddy() this._account.buddies.get(this.name),
 
   // Overwrite the writeMessage function to apply CTCP formatting before
   // display.
   writeMessage: function(aWho, aText, aProperties) {
     GenericConvIMPrototype.writeMessage.call(this, aWho,
                                              ctcpFormatToHTML(aText),
                                              aProperties);
   },
@@ -779,18 +780,18 @@ ircAccountBuddy.prototype = {
 
   remove: function() {
     this._account.removeBuddy(this);
     GenericAccountBuddyPrototype.remove.call(this);
   }
 };
 
 function ircAccount(aProtocol, aImAccount) {
-  this._buddies = {};
   this._init(aProtocol, aImAccount);
+  this.buddies = new NormalizedMap(this.normalizeNick.bind(this));
   this._conversations = {};
 
   // Split the account name into usable parts.
   let splitter = this.name.lastIndexOf("@");
   this._accountNickname = this.name.slice(0, splitter);
   this._server = this.name.slice(splitter + 1);
 
   this._nickname = this._accountNickname;
@@ -1125,48 +1126,34 @@ ircAccount.prototype = {
     if (index < 0) {
       this.ERROR("Trying to untrack a nick that was not being tracked: "+ aNick);
       return;
     }
     this.trackQueue.splice(index, 1);
   },
   addBuddy: function(aTag, aName) {
     let buddy = new ircAccountBuddy(this, null, aTag, aName);
-    this._buddies[buddy.normalizedName] = buddy;
+    this.buddies.set(buddy.normalizedName, buddy);
     this.trackBuddy(buddy.userName);
 
     Services.contacts.accountBuddyAdded(buddy);
   },
   removeBuddy: function(aBuddy) {
-    delete this._buddies[aBuddy.normalizedName];
+    this.buddies.delete(aBuddy.normalizedName);
     this.untrackBuddy(aBuddy.userName);
   },
   // Loads a buddy from the local storage. Called for each buddy locally stored
   // before connecting to the server.
   loadBuddy: function(aBuddy, aTag) {
     let buddy = new ircAccountBuddy(this, aBuddy, aTag);
-    this._buddies[buddy.normalizedName] = buddy;
+    this.buddies.set(buddy.normalizedName, buddy);
     this.trackBuddy(buddy.userName);
 
     return buddy;
   },
-  hasBuddy: function(aName)
-    hasOwnProperty(this._buddies, this.normalizeNick(aName)),
-  // Return an array of buddy names.
-  getBuddyNames: function() {
-    let buddies = [];
-    for each (let buddyName in Object.keys(this._buddies))
-      buddies.push(this._buddies[buddyName].userName);
-    return buddies;
-  },
-  getBuddy: function(aName) {
-    if (this.hasBuddy(aName))
-      return this._buddies[this.normalizeNick(aName)];
-    return null;
-  },
   changeBuddyNick: function(aOldNick, aNewNick) {
     let msg;
     if (this.normalizeNick(aOldNick) == this.normalizeNick(this._nickname)) {
       // Your nickname changed!
       this._nickname = aNewNick;
       msg = _("message.nick.you", aNewNick);
       for each (let conversation in this._conversations) {
         // Update the nick for chats, and inform the user in every conversation.
@@ -1662,18 +1649,18 @@ ircAccount.prototype = {
     this.sendMessage("USER", [username, this._mode.toString(), "*",
                               this._realname || this._requestedNickname]);
   },
 
   _reportDisconnecting: function(aErrorReason, aErrorMessage) {
     this.reportDisconnecting(aErrorReason, aErrorMessage);
 
     // Mark all contacts on the account as having an unknown status.
-    for each (let buddy in this._buddies)
-      buddy.setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, "");
+    this.buddies.forEach(function(aBuddy)
+      aBuddy.setStatus(Ci.imIStatusInfo.STATUS_UNKNOWN, ""));
   },
 
   gotDisconnected: function(aError, aErrorMessage) {
     if (!this.imAccount || this.disconnected)
        return;
 
     if (aError === undefined)
       aError = Ci.prplIAccount.NO_ERROR;
@@ -1711,19 +1698,18 @@ ircAccount.prototype = {
 
     this.reportDisconnected();
   },
 
   remove: function() {
     for each (let conv in this._conversations)
       conv.close();
     delete this._conversations;
-    for each (let buddy in this._buddies)
-      buddy.remove();
-    delete this._buddies;
+    this.buddies.forEach(function(aBuddy) aBuddy.remove());
+    delete this.buddies;
   },
 
   unInit: function() {
     // Disconnect if we're online while this gets called.
     if (this._socket) {
       if (!this.disconnecting)
         this.quit();
       this._socket.disconnect();
--- a/chat/protocols/irc/ircBase.jsm
+++ b/chat/protocols/irc/ircBase.jsm
@@ -203,17 +203,17 @@ var ircBase = {
           // case.
           conversation.getParticipant(aMessage.nickname, true);
           let msg = _("message.join", aMessage.nickname, aMessage.source || "");
           conversation.writeMessage(aMessage.nickname, msg, {system: true,
                                                              noLinkification: true});
         }
       }
       // If the joiner is a buddy, mark as online.
-      let buddy = this.getBuddy(aMessage.nickname);
+      let buddy = this.buddies.get(aMessage.nickname);
       if (buddy)
         buddy.setStatus(Ci.imIStatusInfo.STATUS_AVAILABLE, "");
       return true;
     },
     "KICK": function(aMessage) {
       // KICK <channel> *( "," <channel> ) <user> *( "," <user> ) [<comment>]
       let comment = aMessage.params.length == 3 ? aMessage.params[2] : null;
       // Some servers (moznet) send the kicker as the comment.
@@ -302,17 +302,17 @@ var ircBase = {
           conversation.removeParticipant(aMessage.nickname, true);
         }
       }
 
       // Remove from the whois table.
       this.removeBuddyInfo(aMessage.nickname);
 
       // If the leaver is a buddy, mark as offline.
-      let buddy = this.getBuddy(aMessage.nickname);
+      let buddy = this.buddies.get(aMessage.nickname);
       if (buddy)
         buddy.setStatus(Ci.imIStatusInfo.STATUS_OFFLINE, "");
       return true;
     },
     "SQUIT": function(aMessage) {
       // <server> <comment>
       return true;
     },
@@ -667,17 +667,17 @@ var ircBase = {
         // If the buddy name is in the list returned from the server, they're
         // online.
         let status = (receivedBuddyNames.indexOf(buddyName) == -1) ?
                        Ci.imIStatusInfo.STATUS_OFFLINE :
                        Ci.imIStatusInfo.STATUS_AVAILABLE;
 
         // Set the status with no status message, only if the buddy actually
         // exists in the buddy list.
-        let buddy = this.getBuddy(buddyName);
+        let buddy = this.buddies.get(buddyName);
         if (buddy)
           buddy.setStatus(status, "");
       }
       return true;
     },
     "305": function(aMessage) { // RPL_UNAWAY
       // :You are no longer marked as being away
       this.isAway = false;
--- a/chat/protocols/irc/ircWatchMonitor.jsm
+++ b/chat/protocols/irc/ircWatchMonitor.jsm
@@ -29,17 +29,17 @@ function setStatus(aAccount, aNick, aSta
     // We need to request the away message.
     aAccount.requestBuddyInfo(aNick);
   }
   else {
     // Clear the WHOIS information.
     aAccount.removeBuddyInfo(aNick);
   }
 
-  let buddy = aAccount.getBuddy(aNick);
+  let buddy = aAccount.buddies.get(aNick);
   if (!buddy)
     return false;
   buddy.setStatus(Ci.imIStatusInfo["STATUS_" + aStatus], "");
   return true;
 }
 
 function trackBuddyWatch(aNicks) {
   let nicks = (Array.isArray(aNicks) ? aNicks : [aNicks])
@@ -152,17 +152,17 @@ var ircWATCH = {
       // Fall through to other handlers since we're only using this as an entry
       // point and not actually handling the message.
       return false;
     },
 
     "301": function(aMessage) { // RPL_AWAY
       // <nick> :<away message>
       // Set the received away message.
-      let buddy = this.getBuddy(aMessage.params[1]);
+      let buddy = this.buddies.get(aMessage.params[1]);
       if (buddy)
         buddy.setStatus(Ci.imIStatusInfo.STATUS_AWAY, aMessage.params[2]);
 
       // Fall through to the other implementations after setting the status
       // message.
       return false;
     },