Skip to content

Commit

Permalink
Stop doing O(n^2) work to find event's home (#3227)
Browse files Browse the repository at this point in the history
* Stop doing O(n^2) work to find event's home

In certain rooms (e.g. with many state changes hidden via user preferences), the
events array presented to `eventShouldLiveIn` may contain 100s of events. As
part of its various checks, `eventShouldLiveIn` would get an event's associated
ID (reply / relation / redaction parent). It would then use `events.find` to
search the entire (possibly large) `events` array to look for the parent. (This
by itself seems sub-optimal and should probably change to use a map.)

For many events in a room, there is no associated ID. Unfortunately,
`eventShouldLiveIn` did not check whether the associated ID actually exists
before running off to search all of `events`, resulting in O(n^2) work.

This changes `eventShouldLiveIn` to first check that there is an associated ID
before proceeding with its (slow) search. For some rooms, this change
drastically improves performance from ~100% CPU usage to nearly idle.

Signed-off-by: J. Ryan Stinnett <jryans@gmail.com>

* Add type to `parentEvent`

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: J. Ryan Stinnett <jryans@gmail.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
  • Loading branch information
jryans and t3chguy authored Mar 23, 2023
1 parent fc55c4c commit 5f3e115
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/models/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2028,8 +2028,11 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
};
}

const parentEventId = event.getAssociatedId()!;
const parentEvent = this.findEventById(parentEventId) ?? events?.find((e) => e.getId() === parentEventId);
const parentEventId = event.getAssociatedId();
let parentEvent: MatrixEvent | undefined;
if (parentEventId) {
parentEvent = this.findEventById(parentEventId) ?? events?.find((e) => e.getId() === parentEventId);
}

// Treat relations and redactions as extensions of their parents so evaluate parentEvent instead
if (parentEvent && (event.isRelation() || event.isRedaction())) {
Expand Down

0 comments on commit 5f3e115

Please sign in to comment.