message: Speed up PublicitySyncer._solveVisibility by keeping reverse lookups
  Reduces time taken on Freenode's database from 6.3s to 430ms.
diff: @@ -22,6 +22,9 @@ function PublicitySyncer(ircBridge) {
  mappings: {
  //room_id: ['funNetwork #channel1', 'funNetwork channel2',...]
  },
  + networkToRooms: {
  + //'funNetwork #channel1': [room_id, room_id, ...]
  + },
  channelIsSecret: {
  // '$networkId $channel': true | false
  },
  @@ -141,7 +144,12 @@ PublicitySyncer.prototype._solveVisibility = Promise.coroutine(function*() {
  roomIds.forEach((roomId) => {
  this._visibilityMap.mappings[roomId] = mappings[roomId].map((mapping) => {
  - return this.getIRCVisMapKey(mapping.networkId, mapping.channel);
  + let key = this.getIRCVisMapKey(mapping.networkId, mapping.channel);
  + // also assign reverse mapping for lookup speed later
  + if (!this._visibilityMap.networkToRooms[key]) {
  + this._visibilityMap.networkToRooms[key] = [];
  + }
  + this._visibilityMap.networkToRooms[key].push(roomId);
  });
  });
  @@ -180,9 +188,7 @@ PublicitySyncer.prototype._solveVisibility = Promise.coroutine(function*() {
  // So get all the roomIds that this channel is mapped to and return whether any
  // are mapped to channels that are secret
  return channels.map((channel) => {
  - return Object.keys(this._visibilityMap.mappings).filter((roomId2) => {
  - return this._visibilityMap.mappings[roomId2].indexOf(channel) !== -1;
  - });
  + return this._visibilityMap.networkToRooms[channel];
  }).some((roomIds2) => {
  return roomIds2.some((roomId2) => {
  return shouldBePrivate(roomId2, checkedChannels.concat(channels));
  