mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-02-25 05:53:09 -06:00
Move the event loading code into a separate function.
This commit is contained in:
parent
93b7a26e05
commit
2aec67d39e
|
|
@ -72,7 +72,44 @@ const maxStateBlockNIDs = 64
|
||||||
// Stores the resulting state and returns a numeric ID for the snapshot.
|
// Stores the resulting state and returns a numeric ID for the snapshot.
|
||||||
func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, prevStates []types.StateAtEvent) (types.StateSnapshotNID, error) {
|
func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, prevStates []types.StateAtEvent) (types.StateSnapshotNID, error) {
|
||||||
// Conflict resolution.
|
// Conflict resolution.
|
||||||
// First stage: load the state datablocks for the prev events.
|
// First stage: load the state after each of the prev events.
|
||||||
|
combined, err := loadCombinedStateAfterEvents(db, prevStates)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect all the entries with the same type and key together.
|
||||||
|
// We don't care about the order here because the conflict resolution
|
||||||
|
// algorithm doesn't depend on the order of the prev events.
|
||||||
|
sort.Sort(stateEntrySorter(combined))
|
||||||
|
// Remove duplicate entires.
|
||||||
|
combined = combined[:unique(stateEntrySorter(combined))]
|
||||||
|
|
||||||
|
// Find the conflicts
|
||||||
|
conflicts := findDuplicateStateKeys(combined)
|
||||||
|
|
||||||
|
var state []types.StateEntry
|
||||||
|
if len(conflicts) > 0 {
|
||||||
|
// 5) There are conflicting state events, for each conflict workout
|
||||||
|
// what the appropriate state event is.
|
||||||
|
resolved, err := resolveConflicts(db, combined, conflicts)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
state = resolved
|
||||||
|
} else {
|
||||||
|
// 6) There weren't any conflicts
|
||||||
|
state = combined
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if we can encode the new state as a delta against the
|
||||||
|
// previous state.
|
||||||
|
return db.AddState(roomNID, nil, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadCombinedStateAfterEvents loads a snapshot of the state after each of the events
|
||||||
|
// and combines those snapshots together into a single list.
|
||||||
|
func loadCombinedStateAfterEvents(db RoomEventDatabase, prevStates []types.StateAtEvent) ([]types.StateEntry, error) {
|
||||||
stateNIDs := make([]types.StateSnapshotNID, len(prevStates))
|
stateNIDs := make([]types.StateSnapshotNID, len(prevStates))
|
||||||
for i, state := range prevStates {
|
for i, state := range prevStates {
|
||||||
stateNIDs[i] = state.BeforeStateSnapshotNID
|
stateNIDs[i] = state.BeforeStateSnapshotNID
|
||||||
|
|
@ -83,7 +120,7 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
|
||||||
// the snapshot of the room state before them was the same.
|
// the snapshot of the room state before them was the same.
|
||||||
stateBlockNIDLists, err := db.StateBlockNIDs(uniqueStateSnapshotNIDs(stateNIDs))
|
stateBlockNIDLists, err := db.StateBlockNIDs(uniqueStateSnapshotNIDs(stateNIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var stateBlockNIDs []types.StateBlockNID
|
var stateBlockNIDs []types.StateBlockNID
|
||||||
|
|
@ -96,7 +133,7 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
|
||||||
// multiple snapshots.
|
// multiple snapshots.
|
||||||
stateEntryLists, err := db.StateEntries(uniqueStateBlockNIDs(stateBlockNIDs))
|
stateEntryLists, err := db.StateEntries(uniqueStateBlockNIDs(stateBlockNIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return nil, err
|
||||||
}
|
}
|
||||||
stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists)
|
stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists)
|
||||||
stateEntriesMap := stateEntryListMap(stateEntryLists)
|
stateEntriesMap := stateEntryListMap(stateEntryLists)
|
||||||
|
|
@ -138,34 +175,7 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
|
||||||
// Add the full state for this StateSnapshotNID.
|
// Add the full state for this StateSnapshotNID.
|
||||||
combined = append(combined, fullState...)
|
combined = append(combined, fullState...)
|
||||||
}
|
}
|
||||||
|
return combined, nil
|
||||||
// Collect all the entries with the same type and key together.
|
|
||||||
// We don't care about the order here because the conflict resolution
|
|
||||||
// algorithm doesn't depend on the order of the prev events.
|
|
||||||
sort.Sort(stateEntrySorter(combined))
|
|
||||||
// Remove duplicate entires.
|
|
||||||
combined = combined[:unique(stateEntrySorter(combined))]
|
|
||||||
|
|
||||||
// Find the conflicts
|
|
||||||
conflicts := findDuplicateStateKeys(combined)
|
|
||||||
|
|
||||||
var state []types.StateEntry
|
|
||||||
if len(conflicts) > 0 {
|
|
||||||
// 5) There are conflicting state events, for each conflict workout
|
|
||||||
// what the appropriate state event is.
|
|
||||||
resolved, err := resolveConflicts(db, combined, conflicts)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
state = resolved
|
|
||||||
} else {
|
|
||||||
// 6) There weren't any conflicts
|
|
||||||
state = combined
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Check if we can encode the new state as a delta against the
|
|
||||||
// previous state.
|
|
||||||
return db.AddState(roomNID, nil, state)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveConflicts(db RoomEventDatabase, combined, conflicted []types.StateEntry) ([]types.StateEntry, error) {
|
func resolveConflicts(db RoomEventDatabase, combined, conflicted []types.StateEntry) ([]types.StateEntry, error) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue