LoadStateAtSnapshot loads the full state of a room at a particular snapshot. This is typically the state before an event or the current state of a room. Returns a sorted list of state entries or an error if there was a problem talking to the database.
( ctx context.Context, stateNID types.StateSnapshotNID, )
| 62 | // This is typically the state before an event or the current state of a room. |
| 63 | // Returns a sorted list of state entries or an error if there was a problem talking to the database. |
| 64 | func (v *StateResolution) LoadStateAtSnapshot( |
| 65 | ctx context.Context, stateNID types.StateSnapshotNID, |
| 66 | ) ([]types.StateEntry, error) { |
| 67 | span, ctx := opentracing.StartSpanFromContext(ctx, "StateResolution.LoadStateAtSnapshot") |
| 68 | defer span.Finish() |
| 69 | |
| 70 | stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, []types.StateSnapshotNID{stateNID}) |
| 71 | if err != nil { |
| 72 | return nil, err |
| 73 | } |
| 74 | // We've asked for exactly one snapshot from the db so we should have exactly one entry in the result. |
| 75 | stateBlockNIDList := stateBlockNIDLists[0] |
| 76 | |
| 77 | stateEntryLists, err := v.db.StateEntries(ctx, stateBlockNIDList.StateBlockNIDs) |
| 78 | if err != nil { |
| 79 | return nil, err |
| 80 | } |
| 81 | stateEntriesMap := stateEntryListMap(stateEntryLists) |
| 82 | |
| 83 | // Combine all the state entries for this snapshot. |
| 84 | // The order of state block NIDs in the list tells us the order to combine them in. |
| 85 | var fullState []types.StateEntry |
| 86 | for _, stateBlockNID := range stateBlockNIDList.StateBlockNIDs { |
| 87 | entries, ok := stateEntriesMap.lookup(stateBlockNID) |
| 88 | if !ok { |
| 89 | // This should only get hit if the database is corrupt. |
| 90 | // It should be impossible for an event to reference a NID that doesn't exist |
| 91 | panic(fmt.Errorf("corrupt DB: Missing state block numeric ID %d", stateBlockNID)) |
| 92 | } |
| 93 | fullState = append(fullState, entries...) |
| 94 | } |
| 95 | |
| 96 | // Stable sort so that the most recent entry for each state key stays |
| 97 | // remains later in the list than the older entries for the same state key. |
| 98 | sort.Stable(stateEntryByStateKeySorter(fullState)) |
| 99 | // Unique returns the last entry and hence the most recent entry for each state key. |
| 100 | fullState = fullState[:util.Unique(stateEntryByStateKeySorter(fullState))] |
| 101 | return fullState, nil |
| 102 | } |
| 103 | |
| 104 | // LoadStateAtEvent loads the full state of a room before a particular event. |
| 105 | func (v *StateResolution) LoadStateAtEvent( |
no test coverage detected