You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2026-01-03 23:22:30 +03:00
Change calculating display names from O(n^2) to O(n)
Reduces initial sync times from ~30s to ~1s on accounts with heavily populated rooms. The problem was that f.e. RoomMember it would try to calculate the display name, which involved looping each RoomMember to get their display name to check for disambiguation. We now cache display names to user IDs so we don't need to loop every member when disambiguating.
This commit is contained in:
@@ -208,18 +208,13 @@ function calculateDisplayName(member, event, roomState) {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
var stateEvents = utils.filter(
|
||||
roomState.getStateEvents("m.room.member"),
|
||||
function(e) {
|
||||
return e.getContent().displayname === displayName &&
|
||||
e.getSender() !== selfUserId;
|
||||
}
|
||||
);
|
||||
if (stateEvents.length > 0) {
|
||||
// need to disambiguate
|
||||
var userIds = roomState.getUserIdsWithDisplayName(displayName);
|
||||
var otherUsers = userIds.filter(function(u) {
|
||||
return u !== selfUserId;
|
||||
});
|
||||
if (otherUsers.length > 0) {
|
||||
return displayName + " (" + selfUserId + ")";
|
||||
}
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ function RoomState(roomId) {
|
||||
// userId: RoomMember
|
||||
};
|
||||
this._updateModifiedTime();
|
||||
this._displayNameToUserIds = {};
|
||||
this._userIdsToDisplayNames = {};
|
||||
}
|
||||
utils.inherits(RoomState, EventEmitter);
|
||||
|
||||
@@ -108,6 +110,11 @@ RoomState.prototype.setStateEvents = function(stateEvents) {
|
||||
self.events[event.getType()] = {};
|
||||
}
|
||||
self.events[event.getType()][event.getStateKey()] = event;
|
||||
if (event.getType() === "m.room.member") {
|
||||
_updateDisplayNameCache(
|
||||
self, event.getStateKey(), event.getContent().displayname
|
||||
);
|
||||
}
|
||||
self.emit("RoomState.events", event, self);
|
||||
});
|
||||
|
||||
@@ -180,11 +187,37 @@ RoomState.prototype.getLastModifiedTime = function() {
|
||||
return this._modified;
|
||||
};
|
||||
|
||||
RoomState.prototype.getUserIdsWithDisplayName = function(displayName) {
|
||||
return this._displayNameToUserIds[displayName] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* The RoomState class.
|
||||
*/
|
||||
module.exports = RoomState;
|
||||
|
||||
|
||||
function _updateDisplayNameCache(roomState, userId, displayName) {
|
||||
var oldName = roomState._userIdsToDisplayNames[userId];
|
||||
delete roomState._userIdsToDisplayNames[userId];
|
||||
if (oldName) {
|
||||
var existing = roomState._displayNameToUserIds[oldName] || [];
|
||||
for (var i = 0; i < existing.length; i++) {
|
||||
if (existing[i] === userId) {
|
||||
existing.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
roomState._displayNameToUserIds[oldName] = existing;
|
||||
}
|
||||
|
||||
roomState._userIdsToDisplayNames[userId] = displayName;
|
||||
if (!roomState._displayNameToUserIds[displayName]) {
|
||||
roomState._displayNameToUserIds[displayName] = [];
|
||||
}
|
||||
roomState._displayNameToUserIds[displayName].push(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires whenever the event dictionary in room state is updated.
|
||||
* @event module:client~MatrixClient#"RoomState.events"
|
||||
|
||||
@@ -201,6 +201,9 @@ describe("RoomMember", function() {
|
||||
}),
|
||||
joinEvent
|
||||
];
|
||||
},
|
||||
getUserIdsWithDisplayName: function(displayName) {
|
||||
return [userA, userC];
|
||||
}
|
||||
};
|
||||
expect(member.name).toEqual(userA); // default = user_id
|
||||
|
||||
Reference in New Issue
Block a user