2021-11-02 11:09:26 +00:00
|
|
|
package sync3
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sort"
|
2021-11-04 18:02:58 +00:00
|
|
|
|
2022-12-15 11:08:50 +00:00
|
|
|
"github.com/matrix-org/sliding-sync/internal"
|
2021-11-02 11:09:26 +00:00
|
|
|
)
|
|
|
|
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
type RoomFinder interface {
|
2023-02-02 11:26:08 +00:00
|
|
|
ReadOnlyRoom(roomID string) *RoomConnMetadata
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
}
|
|
|
|
|
2021-11-05 15:45:04 +00:00
|
|
|
// SortableRooms represents a list of rooms which can be sorted and updated. Maintains mappings of
|
|
|
|
// room IDs to current index positions after sorting.
|
2021-11-04 18:02:58 +00:00
|
|
|
type SortableRooms struct {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
finder RoomFinder
|
2023-05-24 15:20:49 +01:00
|
|
|
listKey string
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
roomIDs []string
|
2021-11-04 18:02:58 +00:00
|
|
|
roomIDToIndex map[string]int // room_id -> index in rooms
|
|
|
|
}
|
|
|
|
|
2023-05-24 15:20:49 +01:00
|
|
|
func NewSortableRooms(finder RoomFinder, listKey string, rooms []string) *SortableRooms {
|
2021-11-04 18:02:58 +00:00
|
|
|
return &SortableRooms{
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
roomIDs: rooms,
|
|
|
|
finder: finder,
|
2023-05-24 15:20:49 +01:00
|
|
|
listKey: listKey,
|
2021-11-04 18:02:58 +00:00
|
|
|
roomIDToIndex: make(map[string]int),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *SortableRooms) IndexOf(roomID string) (int, bool) {
|
|
|
|
index, ok := s.roomIDToIndex[roomID]
|
|
|
|
return index, ok
|
|
|
|
}
|
2021-11-02 11:09:26 +00:00
|
|
|
|
2021-11-05 15:45:04 +00:00
|
|
|
func (s *SortableRooms) RoomIDs() []string {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
roomIDs := make([]string, len(s.roomIDs))
|
|
|
|
for i := range s.roomIDs {
|
|
|
|
roomIDs[i] = s.roomIDs[i]
|
2021-11-05 15:45:04 +00:00
|
|
|
}
|
|
|
|
return roomIDs
|
|
|
|
}
|
|
|
|
|
2021-11-08 16:21:02 +00:00
|
|
|
// Add a room to the list. Returns true if the room was added.
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
func (s *SortableRooms) Add(roomID string) bool {
|
|
|
|
_, exists := s.roomIDToIndex[roomID]
|
2021-11-08 16:21:02 +00:00
|
|
|
if exists {
|
|
|
|
return false
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
s.roomIDs = append(s.roomIDs, roomID)
|
|
|
|
s.roomIDToIndex[roomID] = len(s.roomIDs) - 1
|
2021-11-08 16:21:02 +00:00
|
|
|
return true
|
2021-11-05 15:45:04 +00:00
|
|
|
}
|
|
|
|
|
2023-04-05 15:36:05 +01:00
|
|
|
func (s *SortableRooms) Get(index int) string {
|
2023-04-05 18:31:03 +01:00
|
|
|
// TODO: find a way to plumb a context into this assert
|
2023-04-05 15:36:05 +01:00
|
|
|
internal.Assert(fmt.Sprintf("index is within len(rooms) %v < %v", index, len(s.roomIDs)), index < len(s.roomIDs))
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
return s.roomIDs[index]
|
2021-11-05 15:45:04 +00:00
|
|
|
}
|
|
|
|
|
2021-11-08 16:49:21 +00:00
|
|
|
func (s *SortableRooms) Remove(roomID string) int {
|
2021-11-08 16:21:02 +00:00
|
|
|
index, ok := s.roomIDToIndex[roomID]
|
|
|
|
if !ok {
|
2021-11-08 16:49:21 +00:00
|
|
|
return -1
|
2021-11-08 16:21:02 +00:00
|
|
|
}
|
|
|
|
delete(s.roomIDToIndex, roomID)
|
|
|
|
// splice out index
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
s.roomIDs = append(s.roomIDs[:index], s.roomIDs[index+1:]...)
|
2022-08-16 15:56:16 +01:00
|
|
|
// re-update the map
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
for i := index; i < len(s.roomIDs); i++ {
|
|
|
|
s.roomIDToIndex[s.roomIDs[i]] = i
|
2022-08-16 15:56:16 +01:00
|
|
|
}
|
2021-11-08 16:49:21 +00:00
|
|
|
return index
|
2021-11-08 16:21:02 +00:00
|
|
|
}
|
|
|
|
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) Len() int64 {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
return int64(len(s.roomIDs))
|
2021-11-02 11:09:26 +00:00
|
|
|
}
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) Subslice(i, j int64) Subslicer {
|
2023-04-05 18:31:03 +01:00
|
|
|
// TODO: find a way to plumb a context.Context through to this assert
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
internal.Assert("i < j and are within len(rooms)", i < j && i < int64(len(s.roomIDs)) && j <= int64(len(s.roomIDs)))
|
2021-11-04 18:02:58 +00:00
|
|
|
return &SortableRooms{
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
roomIDs: s.roomIDs[i:j],
|
2021-11-04 18:02:58 +00:00
|
|
|
roomIDToIndex: s.roomIDToIndex,
|
|
|
|
}
|
2021-11-02 11:09:26 +00:00
|
|
|
}
|
|
|
|
|
2023-04-05 15:36:05 +01:00
|
|
|
func (s *SortableRooms) Sort(sortBy []string) error {
|
2023-04-05 18:31:03 +01:00
|
|
|
// TODO: find a way to plumb a context into this assert
|
2023-04-05 15:36:05 +01:00
|
|
|
internal.Assert("sortBy is not empty", len(sortBy) != 0)
|
2021-11-02 11:09:26 +00:00
|
|
|
comparators := []func(i, j int) int{}
|
|
|
|
for _, sort := range sortBy {
|
|
|
|
switch sort {
|
|
|
|
case SortByHighlightCount:
|
|
|
|
comparators = append(comparators, s.comparatorSortByHighlightCount)
|
|
|
|
case SortByNotificationCount:
|
|
|
|
comparators = append(comparators, s.comparatorSortByNotificationCount)
|
|
|
|
case SortByName:
|
|
|
|
comparators = append(comparators, s.comparatorSortByName)
|
|
|
|
case SortByRecency:
|
|
|
|
comparators = append(comparators, s.comparatorSortByRecency)
|
2022-12-14 18:53:55 +00:00
|
|
|
case SortByNotificationLevel:
|
|
|
|
comparators = append(comparators, s.comparatorSortByNotificationLevel)
|
2021-11-02 11:09:26 +00:00
|
|
|
default:
|
|
|
|
return fmt.Errorf("unknown sort order: %s", sort)
|
|
|
|
}
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
sort.SliceStable(s.roomIDs, func(i, j int) bool {
|
2021-11-02 11:09:26 +00:00
|
|
|
for _, fn := range comparators {
|
|
|
|
val := fn(i, j)
|
|
|
|
if val == 1 {
|
|
|
|
return true
|
|
|
|
} else if val == -1 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
// continue to next comparator as these are equal
|
|
|
|
}
|
|
|
|
// the two items are identical
|
|
|
|
return false
|
|
|
|
})
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
for i := range s.roomIDs {
|
|
|
|
s.roomIDToIndex[s.roomIDs[i]] = i
|
2021-11-04 18:02:58 +00:00
|
|
|
}
|
|
|
|
|
2021-11-02 11:09:26 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Comparator functions: -1 = false, +1 = true, 0 = match
|
|
|
|
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
func (s *SortableRooms) resolveRooms(i, j int) (ri, rj *RoomConnMetadata) {
|
2023-02-02 11:26:08 +00:00
|
|
|
ri = s.finder.ReadOnlyRoom(s.roomIDs[i])
|
|
|
|
rj = s.finder.ReadOnlyRoom(s.roomIDs[j])
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) comparatorSortByName(i, j int) int {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
ri, rj := s.resolveRooms(i, j)
|
|
|
|
if ri.CanonicalisedName == rj.CanonicalisedName {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 0
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
if ri.CanonicalisedName < rj.CanonicalisedName {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) comparatorSortByRecency(i, j int) int {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
ri, rj := s.resolveRooms(i, j)
|
2023-05-25 11:30:42 +01:00
|
|
|
tsRi := ri.GetLastInterestedEventTimestamp(s.listKey)
|
|
|
|
tsRj := rj.GetLastInterestedEventTimestamp(s.listKey)
|
|
|
|
if tsRi == tsRj {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 0
|
|
|
|
}
|
2023-05-25 11:30:42 +01:00
|
|
|
if tsRi > tsRj {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) comparatorSortByHighlightCount(i, j int) int {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
ri, rj := s.resolveRooms(i, j)
|
|
|
|
if ri.HighlightCount == rj.HighlightCount {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 0
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
if ri.HighlightCount > rj.HighlightCount {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2022-12-14 18:53:55 +00:00
|
|
|
func (s *SortableRooms) comparatorSortByNotificationLevel(i, j int) int {
|
|
|
|
ri, rj := s.resolveRooms(i, j)
|
|
|
|
// highlight rooms come first
|
|
|
|
if ri.HighlightCount > 0 && rj.HighlightCount > 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if ri.HighlightCount > 0 {
|
|
|
|
return 1
|
|
|
|
} else if rj.HighlightCount > 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
// then notification count
|
|
|
|
if ri.NotificationCount > 0 && rj.NotificationCount > 0 {
|
|
|
|
// when we are comparing rooms with notif counts, sort encrypted rooms above unencrypted rooms
|
|
|
|
// as the client needs to calculate highlight counts (so it's possible that notif counts are
|
|
|
|
// actually highlight counts!) - this is the "Lite" description in MSC3575
|
|
|
|
if ri.Encrypted && !rj.Encrypted {
|
|
|
|
return 1
|
|
|
|
} else if rj.Encrypted && !ri.Encrypted {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if ri.NotificationCount > 0 {
|
|
|
|
return 1
|
|
|
|
} else if rj.NotificationCount > 0 {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
// no highlight or notifs get grouped together
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2021-11-04 18:02:58 +00:00
|
|
|
func (s *SortableRooms) comparatorSortByNotificationCount(i, j int) int {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
ri, rj := s.resolveRooms(i, j)
|
|
|
|
if ri.NotificationCount == rj.NotificationCount {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 0
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
if ri.NotificationCount > rj.NotificationCount {
|
2021-11-02 11:09:26 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return -1
|
|
|
|
}
|
2021-11-08 16:21:02 +00:00
|
|
|
|
2022-03-23 14:13:59 +00:00
|
|
|
// FilteredSortableRooms is SortableRooms but where rooms are filtered before being added to the list.
|
|
|
|
// Updates to room metadata may result in rooms being added/removed.
|
2021-11-08 16:21:02 +00:00
|
|
|
type FilteredSortableRooms struct {
|
|
|
|
*SortableRooms
|
|
|
|
filter *RequestFilters
|
|
|
|
}
|
|
|
|
|
2023-05-24 15:20:49 +01:00
|
|
|
func NewFilteredSortableRooms(finder RoomFinder, listKey string, roomIDs []string, filter *RequestFilters) *FilteredSortableRooms {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
var filteredRooms []string
|
2021-11-08 16:21:02 +00:00
|
|
|
if filter == nil {
|
|
|
|
filter = &RequestFilters{}
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
for _, roomID := range roomIDs {
|
2023-02-02 11:26:08 +00:00
|
|
|
r := finder.ReadOnlyRoom(roomID)
|
2022-12-14 18:53:55 +00:00
|
|
|
if filter.Include(r, finder) {
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
filteredRooms = append(filteredRooms, roomID)
|
2021-11-08 16:21:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return &FilteredSortableRooms{
|
2023-05-24 15:20:49 +01:00
|
|
|
SortableRooms: NewSortableRooms(finder, listKey, filteredRooms),
|
2021-11-08 16:21:02 +00:00
|
|
|
filter: filter,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
func (f *FilteredSortableRooms) Add(roomID string) bool {
|
2023-02-02 11:26:08 +00:00
|
|
|
r := f.finder.ReadOnlyRoom(roomID)
|
2022-12-14 18:53:55 +00:00
|
|
|
if !f.filter.Include(r, f.finder) {
|
2021-11-08 16:21:02 +00:00
|
|
|
return false
|
|
|
|
}
|
refactor: add RoomFinder and use it in InternalRequestLists
This is part of a series of refactors aimed to improve the performance
and complexity of calculating list deltas, which up until now exists in
its current form due to organic growth of the codebase.
This specific refactor introduces a new interface `RoomFinder` which
can map room IDs to `*RoomConnMetadata` which is used by `ConnState`.
All the sliding sync lists now use the `RoomFinder` instead of keeping
their own copies of `RoomConnMetadata`, meaning per-connection, rooms
just have 1 copy in-memory. This cuts down on memory usage as well as
cuts down on GC churn as we would constantly be replacing N rooms for
each update, where N is the total number of lists on that connection.
For Element-Web, N=7 currently to handle Favourites, Low Priority, DMs,
Rooms, Spaces, Invites, Search. This also has the benefit of creating
a single source of truth in `InternalRequestLists.allRooms` which can
be updated once and then a list of list deltas can be calculated off
the back of that. Previously, `allRooms` was _only_ used to seed new
lists, which created a weird imbalance as we would need to update both
`allRooms` _and_ each `FilteredSortableRooms` to keep things in-sync.
This refactor is incomplete in its present form, as we need to make
use of the new `RoomDelta` struct to efficiently package list updates.
2022-08-26 10:09:41 +01:00
|
|
|
return f.SortableRooms.Add(roomID)
|
2021-11-08 16:21:02 +00:00
|
|
|
}
|