From 7e1cea1ef6d442d70763a8c890be53fc71a413f7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 26 Feb 2018 16:43:26 +0000 Subject: [PATCH] Cache the joined member count for a room state Pushrule evaluation needs the count of joined room members and filtering the list for joined members takes a nontrivial amount of time, but caching it is trivial, both code and memory wise. --- src/models/room-state.js | 16 ++++++++++++++++ src/pushprocessor.js | 4 +--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/models/room-state.js b/src/models/room-state.js index e7965fad4..0f3cfc8ec 100644 --- a/src/models/room-state.js +++ b/src/models/room-state.js @@ -69,9 +69,24 @@ function RoomState(roomId) { this._displayNameToUserIds = {}; this._userIdsToDisplayNames = {}; this._tokenToInvite = {}; // 3pid invite state_key to m.room.member invite + this._joinedMemberCount = null; // cache of the number of joined members } utils.inherits(RoomState, EventEmitter); +/** + * Returns the number of joined members in this room + * This method caches the result. + * @return {integer} The number of members in this room whose membership is 'join' + */ +RoomState.prototype.getJoinedMemberCount = function() { + if (this._joinedMemberCount === null) { + this._joinedMemberCount = this.getMembers().filter((m) => { + return m.membership === 'join'; + }).length; + } + return this._joinedMemberCount; +}; + /** * Get all RoomMembers in this room. * @return {Array} A list of RoomMembers. @@ -218,6 +233,7 @@ RoomState.prototype.setStateEvents = function(stateEvents) { delete self._sentinels[userId]; self.members[userId] = member; + self._joinedMemberCount = null; self.emit("RoomState.members", event, self, member); } else if (event.getType() === "m.room.power_levels") { const members = utils.values(self.members); diff --git a/src/pushprocessor.js b/src/pushprocessor.js index 6ab7d1c87..1fdbdfe84 100644 --- a/src/pushprocessor.js +++ b/src/pushprocessor.js @@ -156,9 +156,7 @@ function PushProcessor(client) { return false; } - const memberCount = Object.keys(room.currentState.members).filter(function(m) { - return room.currentState.members[m].membership == 'join'; - }).length; + const memberCount = room.currentState.getJoinedMemberCount(); const m = cond.is.match(/^([=<>]*)([0-9]*)$/); if (!m) {