Merge branch 's7evink/roomstate' of github.com:matrix-org/sliding-sync into s7evink/roomstate

This commit is contained in:
Till Faelligen 2023-09-07 17:38:40 +02:00
commit 68279e998f
No known key found for this signature in database
GPG Key ID: ACCDC9606D472758

View File

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"strings"
"time"
"github.com/getsentry/sentry-go"
"github.com/lib/pq"
@ -520,39 +521,51 @@ func (s *Storage) RoomStateAfterEventPosition(ctx context.Context, roomIDs []str
}
}
args = append(args, pq.StringArray(userIDs))
cols := "state_key = ANY (?) AND"
if len(userIDs) == 0 {
cols = ""
} else {
args = append(args, pq.StringArray(userIDs))
}
args = append(args, typeArgs...)
// figure out which state events to look at - if there is no m.room.member filter we can be super fast
needUnion := false
if hasMembershipFilter {
needUnion = true
// If there are no where clauses, we need to add a "dummy" where, so we don't get
// anything back. This is mostly the case if we only care about membership events,
// which aren't added in the above loop.
if len(wheres) == 0 {
if hasOtherFilter {
wheres = append(wheres, "TRUE")
} else {
wheres = append(wheres, "FALSE")
}
}
// Similar to CurrentStateEventsInAllRooms
// We're using a CTE here, since unnestting the nids is quite expensive. Using the array as is
// and using ANY() instead performs quite well (e.g. 86k membership events and 130ms execution time, vs
// the previous query with unnest took 2.5s)
if len(wheres) == 0 {
wheres = append(wheres, "1=1")
}
qry := `WITH nids AS (
SELECT snapshot_id, events, membership_events FROM syncv3_snapshots WHERE snapshot_id = ANY(?)
), memberships AS (
SELECT syncv3_memberships.event_nid
FROM syncv3_memberships, nids
WHERE WHERE state_key = ANY (?) AND nids.snapshot_id = ANY(syncv3_memberships.snapshot_id)
)
SELECT syncv3_events.event_nid, syncv3_events.room_id, syncv3_events.event_type, syncv3_events.state_key, syncv3_events.event
FROM syncv3_events, nids
WHERE (syncv3_events.event_nid = ANY(nids.events) AND (` + strings.Join(wheres, " OR ") + `))`
qry := `
WITH nids AS (
SELECT snapshot_id, events, membership_events FROM syncv3_snapshots WHERE snapshot_id = ANY(?)
), memberships AS (
SELECT syncv3_memberships.event_nid
FROM syncv3_memberships, nids
WHERE ` + cols + ` nids.snapshot_id = ANY(syncv3_memberships.snapshot_ids)
)
SELECT syncv3_events.event_nid, syncv3_events.room_id, syncv3_events.event_type, syncv3_events.state_key, syncv3_events.event
FROM syncv3_events, nids
WHERE (syncv3_events.event_nid = ANY(nids.events) AND (` + strings.Join(wheres, " OR ") + `))`
if needUnion {
qry += ` UNION
SELECT syncv3_events.event_nid, syncv3_events.room_id, syncv3_events.event_type, syncv3_events.state_key, syncv3_events.event
FROM syncv3_events, memberships
WHERE syncv3_events.event_nid IN (memberships.event_nid)
ORDER BY event_nid ASC`
// If we're getting membership events, add the UNION select as well.
// This causes the CTE "memberships" to be executed.
if hasMembershipFilter {
qry += `
UNION
SELECT syncv3_events.event_nid, syncv3_events.room_id, syncv3_events.event_type, syncv3_events.state_key, syncv3_events.event
FROM syncv3_events, memberships
WHERE syncv3_events.event_nid IN (memberships.event_nid)
ORDER BY event_nid ASC`
} else {
qry += ` ORDER BY event_nid ASC`
}
@ -581,7 +594,7 @@ ORDER BY event_nid ASC`
}
roomToEvents[ev.RoomID] = append(roomToEvents[ev.RoomID], ev)
}
logger.Trace().Msgf("Query: %s\nArgs: %#v", qry, args)
logger.Trace().Msgf("[%s] Query: %s\nArgs: %#v", time.Since(qryStart), qry, args)
// handle the most recent events which won't be in the snapshot but may need to be.
// we handle the replace case but don't handle brand new state events
for i := range latestEvents {