MCPcopy Create free account
hub / github.com/daodst/chat / loadStateAfterEventsForNumericTuples

Method loadStateAfterEventsForNumericTuples

roomserver/state/state.go:418–489  ·  view source on GitHub ↗
(
	ctx context.Context,
	prevStates []types.StateAtEvent,
	stateKeyTuples []types.StateKeyTuple,
)

Source from the content-addressed store, hash-verified

416}
417
418func (v *StateResolution) loadStateAfterEventsForNumericTuples(
419 ctx context.Context,
420 prevStates []types.StateAtEvent,
421 stateKeyTuples []types.StateKeyTuple,
422) ([]types.StateEntry, error) {
423 span, ctx := opentracing.StartSpanFromContext(ctx, "StateResolution.loadStateAfterEventsForNumericTuples")
424 defer span.Finish()
425
426 if len(prevStates) == 1 {
427 // Fast path for a single event.
428 prevState := prevStates[0]
429 result, err := v.loadStateAtSnapshotForNumericTuples(
430 ctx, prevState.BeforeStateSnapshotNID, stateKeyTuples,
431 )
432 if err != nil {
433 return nil, err
434 }
435 if prevState.IsStateEvent() {
436 // The result is current the state before the requested event.
437 // We want the state after the requested event.
438 // If the requested event was a state event then we need to
439 // update that key in the result.
440 // If the requested event wasn't a state event then the state after
441 // it is the same as the state before it.
442 set := false
443 for i := range result {
444 if result[i].StateKeyTuple == prevState.StateKeyTuple {
445 result[i] = prevState.StateEntry
446 set = true
447 }
448 }
449 if !set { // no previous state exists for this event: add new state
450 result = append(result, prevState.StateEntry)
451 }
452 }
453 return result, nil
454 }
455
456 // Slow path for more that one event.
457 // Load the entire state so that we can do conflict resolution if we need to.
458 // TODO: The are some optimistations we could do here:
459 // 1) We only need to do conflict resolution if there is a conflict in the
460 // requested tuples so we might try loading just those tuples and then
461 // checking for conflicts.
462 // 2) When there is a conflict we still only need to load the state
463 // needed to do conflict resolution which would save us having to load
464 // the full state.
465
466 // TODO: Add metrics for this as it could take a long time for big rooms
467 // with large conflicts.
468 fullState, _, _, err := v.calculateStateAfterManyEvents(ctx, v.roomInfo.RoomVersion, prevStates)
469 if err != nil {
470 return nil, err
471 }
472
473 // Sort the full state so we can use it as a map.
474 sort.Sort(stateEntrySorter(fullState))
475

Calls 6

stateEntrySorterTypeAlias · 0.85
IsStateEventMethod · 0.80
stateEntryMapTypeAlias · 0.70
lookupMethod · 0.45

Tested by

no test coverage detected