Don't create so many state snapshots when updating forward extremities (#1718)
* Light-weight checking of state changes when updating forward extremities * Only do this for non-state events, since state events will always result in state change at extremitiesmain
parent
dd1e31bee7
commit
244ff0dccb
|
@ -100,7 +100,8 @@ type latestEventsUpdater struct {
|
||||||
// The eventID of the event that was processed before this one.
|
// The eventID of the event that was processed before this one.
|
||||||
lastEventIDSent string
|
lastEventIDSent string
|
||||||
// The latest events in the room after processing this event.
|
// The latest events in the room after processing this event.
|
||||||
latest []types.StateAtEventAndReference
|
oldLatest []types.StateAtEventAndReference
|
||||||
|
latest []types.StateAtEventAndReference
|
||||||
// The state entries removed from and added to the current state of the
|
// The state entries removed from and added to the current state of the
|
||||||
// room as a result of processing this event. They are sorted lists.
|
// room as a result of processing this event. They are sorted lists.
|
||||||
removed []types.StateEntry
|
removed []types.StateEntry
|
||||||
|
@ -123,10 +124,10 @@ func (u *latestEventsUpdater) doUpdateLatestEvents() error {
|
||||||
// state snapshot from somewhere else, e.g. a federated room join,
|
// state snapshot from somewhere else, e.g. a federated room join,
|
||||||
// then start with an empty set - none of the forward extremities
|
// then start with an empty set - none of the forward extremities
|
||||||
// that we knew about before matter anymore.
|
// that we knew about before matter anymore.
|
||||||
oldLatest := []types.StateAtEventAndReference{}
|
u.oldLatest = []types.StateAtEventAndReference{}
|
||||||
if !u.rewritesState {
|
if !u.rewritesState {
|
||||||
u.oldStateNID = u.updater.CurrentStateSnapshotNID()
|
u.oldStateNID = u.updater.CurrentStateSnapshotNID()
|
||||||
oldLatest = u.updater.LatestEvents()
|
u.oldLatest = u.updater.LatestEvents()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the event has already been written to the output log then we
|
// If the event has already been written to the output log then we
|
||||||
|
@ -140,7 +141,7 @@ func (u *latestEventsUpdater) doUpdateLatestEvents() error {
|
||||||
// Work out what the latest events are. This will include the new
|
// Work out what the latest events are. This will include the new
|
||||||
// event if it is not already referenced.
|
// event if it is not already referenced.
|
||||||
extremitiesChanged, err := u.calculateLatest(
|
extremitiesChanged, err := u.calculateLatest(
|
||||||
oldLatest, u.event,
|
u.oldLatest, u.event,
|
||||||
types.StateAtEventAndReference{
|
types.StateAtEventAndReference{
|
||||||
EventReference: u.event.EventReference(),
|
EventReference: u.event.EventReference(),
|
||||||
StateAtEvent: u.stateAtEvent,
|
StateAtEvent: u.stateAtEvent,
|
||||||
|
@ -200,6 +201,37 @@ func (u *latestEventsUpdater) latestState() error {
|
||||||
var err error
|
var err error
|
||||||
roomState := state.NewStateResolution(u.api.DB, *u.roomInfo)
|
roomState := state.NewStateResolution(u.api.DB, *u.roomInfo)
|
||||||
|
|
||||||
|
// Work out if the state at the extremities has actually changed
|
||||||
|
// or not. If they haven't then we won't bother doing all of the
|
||||||
|
// hard work.
|
||||||
|
if u.event.StateKey() == nil {
|
||||||
|
stateChanged := false
|
||||||
|
oldStateNIDs := make([]types.StateSnapshotNID, 0, len(u.oldLatest))
|
||||||
|
newStateNIDs := make([]types.StateSnapshotNID, 0, len(u.latest))
|
||||||
|
for _, old := range u.oldLatest {
|
||||||
|
oldStateNIDs = append(oldStateNIDs, old.BeforeStateSnapshotNID)
|
||||||
|
}
|
||||||
|
for _, new := range u.latest {
|
||||||
|
newStateNIDs = append(newStateNIDs, new.BeforeStateSnapshotNID)
|
||||||
|
}
|
||||||
|
oldStateNIDs = state.UniqueStateSnapshotNIDs(oldStateNIDs)
|
||||||
|
newStateNIDs = state.UniqueStateSnapshotNIDs(newStateNIDs)
|
||||||
|
if len(oldStateNIDs) != len(newStateNIDs) {
|
||||||
|
stateChanged = true
|
||||||
|
} else {
|
||||||
|
for i := range oldStateNIDs {
|
||||||
|
if oldStateNIDs[i] != newStateNIDs[i] {
|
||||||
|
stateChanged = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stateChanged {
|
||||||
|
u.newStateNID = u.oldStateNID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get a list of the current latest events. This may or may not
|
// Get a list of the current latest events. This may or may not
|
||||||
// include the new event from the input path, depending on whether
|
// include the new event from the input path, depending on whether
|
||||||
// it is a forward extremity or not.
|
// it is a forward extremity or not.
|
||||||
|
|
|
@ -116,7 +116,7 @@ func (v StateResolution) LoadCombinedStateAfterEvents(
|
||||||
// Deduplicate the IDs before passing them to the database.
|
// Deduplicate the IDs before passing them to the database.
|
||||||
// There could be duplicates because the events could be state events where
|
// There could be duplicates because the events could be state events where
|
||||||
// the snapshot of the room state before them was the same.
|
// the snapshot of the room state before them was the same.
|
||||||
stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, uniqueStateSnapshotNIDs(stateNIDs))
|
stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, UniqueStateSnapshotNIDs(stateNIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("v.db.StateBlockNIDs: %w", err)
|
return nil, fmt.Errorf("v.db.StateBlockNIDs: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1103,7 @@ func (s stateNIDSorter) Len() int { return len(s) }
|
||||||
func (s stateNIDSorter) Less(i, j int) bool { return s[i] < s[j] }
|
func (s stateNIDSorter) Less(i, j int) bool { return s[i] < s[j] }
|
||||||
func (s stateNIDSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
func (s stateNIDSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
|
||||||
func uniqueStateSnapshotNIDs(nids []types.StateSnapshotNID) []types.StateSnapshotNID {
|
func UniqueStateSnapshotNIDs(nids []types.StateSnapshotNID) []types.StateSnapshotNID {
|
||||||
return nids[:util.SortAndUnique(stateNIDSorter(nids))]
|
return nids[:util.SortAndUnique(stateNIDSorter(nids))]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue