LoadCombinedStateAfterEvents loads a snapshot of the state after each of the events and combines those snapshots together into a single list. At this point it is possible to run into duplicate (type, state key) tuples.
( ctx context.Context, prevStates []types.StateAtEvent, )
| 151 | // and combines those snapshots together into a single list. At this point it is |
| 152 | // possible to run into duplicate (type, state key) tuples. |
| 153 | func (v *StateResolution) LoadCombinedStateAfterEvents( |
| 154 | ctx context.Context, prevStates []types.StateAtEvent, |
| 155 | ) ([]types.StateEntry, error) { |
| 156 | span, ctx := opentracing.StartSpanFromContext(ctx, "StateResolution.LoadCombinedStateAfterEvents") |
| 157 | defer span.Finish() |
| 158 | |
| 159 | stateNIDs := make([]types.StateSnapshotNID, len(prevStates)) |
| 160 | for i, state := range prevStates { |
| 161 | stateNIDs[i] = state.BeforeStateSnapshotNID |
| 162 | } |
| 163 | // Fetch the state snapshots for the state before the each prev event from the database. |
| 164 | // Deduplicate the IDs before passing them to the database. |
| 165 | // There could be duplicates because the events could be state events where |
| 166 | // the snapshot of the room state before them was the same. |
| 167 | stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, UniqueStateSnapshotNIDs(stateNIDs)) |
| 168 | if err != nil { |
| 169 | return nil, fmt.Errorf("v.db.StateBlockNIDs: %w", err) |
| 170 | } |
| 171 | |
| 172 | var stateBlockNIDs []types.StateBlockNID |
| 173 | for _, list := range stateBlockNIDLists { |
| 174 | stateBlockNIDs = append(stateBlockNIDs, list.StateBlockNIDs...) |
| 175 | } |
| 176 | // Fetch the state entries that will be combined to create the snapshots. |
| 177 | // Deduplicate the IDs before passing them to the database. |
| 178 | // There could be duplicates because a block of state entries could be reused by |
| 179 | // multiple snapshots. |
| 180 | stateEntryLists, err := v.db.StateEntries(ctx, uniqueStateBlockNIDs(stateBlockNIDs)) |
| 181 | if err != nil { |
| 182 | return nil, fmt.Errorf("v.db.StateEntries: %w", err) |
| 183 | } |
| 184 | stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists) |
| 185 | stateEntriesMap := stateEntryListMap(stateEntryLists) |
| 186 | |
| 187 | // Combine the entries from all the snapshots of state after each prev event into a single list. |
| 188 | var combined []types.StateEntry |
| 189 | for _, prevState := range prevStates { |
| 190 | // Grab the list of state data NIDs for this snapshot. |
| 191 | stateBlockNIDs, ok := stateBlockNIDsMap.lookup(prevState.BeforeStateSnapshotNID) |
| 192 | if !ok { |
| 193 | // This should only get hit if the database is corrupt. |
| 194 | // It should be impossible for an event to reference a NID that doesn't exist |
| 195 | panic(fmt.Errorf("corrupt DB: Missing state snapshot numeric ID %d", prevState.BeforeStateSnapshotNID)) |
| 196 | } |
| 197 | |
| 198 | // Combine all the state entries for this snapshot. |
| 199 | // The order of state block NIDs in the list tells us the order to combine them in. |
| 200 | var fullState []types.StateEntry |
| 201 | for _, stateBlockNID := range stateBlockNIDs { |
| 202 | entries, ok := stateEntriesMap.lookup(stateBlockNID) |
| 203 | if !ok { |
| 204 | // This should only get hit if the database is corrupt. |
| 205 | // It should be impossible for an event to reference a NID that doesn't exist |
| 206 | panic(fmt.Errorf("corrupt DB: Missing state block numeric ID %d", stateBlockNID)) |
| 207 | } |
| 208 | fullState = append(fullState, entries...) |
| 209 | } |
| 210 | if prevState.IsStateEvent() && !prevState.IsRejected { |
no test coverage detected