aboutsummaryrefslogtreecommitdiff
path: root/roomserver/storage/postgres/state_snapshot_table.go
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2022-08-01 14:11:00 +0100
committerGitHub <noreply@github.com>2022-08-01 14:11:00 +0100
commit05c83923e3bf24fa7def55a14ac096cdff3a3882 (patch)
tree3ee6bca7393990e75b83971a23611f6982998d59 /roomserver/storage/postgres/state_snapshot_table.go
parentc7f7aec4d07d59120d37d5b16a900f6d608a75c4 (diff)
Optimise checking other servers allowed to see events (#2596)
* Try optimising checking if server is allowed to see event * Fix error * Handle case where snapshot NID is 0 * Fix query * Update SQL * Clean up `CheckServerAllowedToSeeEvent` * Not supported on SQLite * Maybe placate the unit tests * Review comments
Diffstat (limited to 'roomserver/storage/postgres/state_snapshot_table.go')
-rw-r--r--roomserver/storage/postgres/state_snapshot_table.go51
1 files changed, 49 insertions, 2 deletions
diff --git a/roomserver/storage/postgres/state_snapshot_table.go b/roomserver/storage/postgres/state_snapshot_table.go
index a24b7f3f..99c76bef 100644
--- a/roomserver/storage/postgres/state_snapshot_table.go
+++ b/roomserver/storage/postgres/state_snapshot_table.go
@@ -72,9 +72,35 @@ const bulkSelectStateBlockNIDsSQL = "" +
"SELECT state_snapshot_nid, state_block_nids FROM roomserver_state_snapshots" +
" WHERE state_snapshot_nid = ANY($1) ORDER BY state_snapshot_nid ASC"
+// Looks up both the history visibility event and relevant membership events from
+// a given domain name from a given state snapshot. This is used to optimise the
+// helpers.CheckServerAllowedToSeeEvent function.
+// TODO: There's a sequence scan here because of the hash join strategy, which is
+// probably O(n) on state key entries, so there must be a way to avoid that somehow.
+// Event type NIDs are:
+// - 5: m.room.member as per https://github.com/matrix-org/dendrite/blob/c7f7aec4d07d59120d37d5b16a900f6d608a75c4/roomserver/storage/postgres/event_types_table.go#L40
+// - 7: m.room.history_visibility as per https://github.com/matrix-org/dendrite/blob/c7f7aec4d07d59120d37d5b16a900f6d608a75c4/roomserver/storage/postgres/event_types_table.go#L42
+const bulkSelectStateForHistoryVisibilitySQL = `
+ SELECT event_nid FROM (
+ SELECT event_nid, event_type_nid, event_state_key_nid FROM roomserver_events
+ WHERE (event_type_nid = 5 OR event_type_nid = 7)
+ AND event_nid = ANY(
+ SELECT UNNEST(event_nids) FROM roomserver_state_block
+ WHERE state_block_nid = ANY(
+ SELECT UNNEST(state_block_nids) FROM roomserver_state_snapshots
+ WHERE state_snapshot_nid = $1
+ )
+ )
+ ) AS roomserver_events
+ INNER JOIN roomserver_event_state_keys
+ ON roomserver_events.event_state_key_nid = roomserver_event_state_keys.event_state_key_nid
+ AND (event_type_nid = 7 OR event_state_key LIKE '%:' || $2);
+`
+
type stateSnapshotStatements struct {
- insertStateStmt *sql.Stmt
- bulkSelectStateBlockNIDsStmt *sql.Stmt
+ insertStateStmt *sql.Stmt
+ bulkSelectStateBlockNIDsStmt *sql.Stmt
+ bulkSelectStateForHistoryVisibilityStmt *sql.Stmt
}
func CreateStateSnapshotTable(db *sql.DB) error {
@@ -88,6 +114,7 @@ func PrepareStateSnapshotTable(db *sql.DB) (tables.StateSnapshot, error) {
return s, sqlutil.StatementList{
{&s.insertStateStmt, insertStateSQL},
{&s.bulkSelectStateBlockNIDsStmt, bulkSelectStateBlockNIDsSQL},
+ {&s.bulkSelectStateForHistoryVisibilityStmt, bulkSelectStateForHistoryVisibilitySQL},
}.Prepare(db)
}
@@ -136,3 +163,23 @@ func (s *stateSnapshotStatements) BulkSelectStateBlockNIDs(
}
return results, nil
}
+
+func (s *stateSnapshotStatements) BulkSelectStateForHistoryVisibility(
+ ctx context.Context, txn *sql.Tx, stateSnapshotNID types.StateSnapshotNID, domain string,
+) ([]types.EventNID, error) {
+ stmt := sqlutil.TxStmt(txn, s.bulkSelectStateForHistoryVisibilityStmt)
+ rows, err := stmt.QueryContext(ctx, stateSnapshotNID, domain)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close() // nolint: errcheck
+ results := make([]types.EventNID, 0, 16)
+ for rows.Next() {
+ var eventNID types.EventNID
+ if err = rows.Scan(&eventNID); err != nil {
+ return nil, err
+ }
+ results = append(results, eventNID)
+ }
+ return results, rows.Err()
+}