Skip to content

Calling MarkAsSaved repeatedly with no edits in between appends a duplicate save boundary each time, so SaveBoundaries and the saved state grow without bound #121

Description

@matt-edmondson

What's wrong

SaveBoundaryManager.CreateSaveBoundary always appends a new SaveBoundary, even when one already exists at the same position. docs/getting-started.md shows a Save button that calls MarkAsSaved on every click, and autosave timers do the same. Each save without an edit in between adds another identical boundary. Nothing removes them until the stack branches or is trimmed past that position.

Repro

var s = new UndoRedoService(new StackManager(), new SaveBoundaryManager(), new CommandMerger());
s.SetSerializer(new JsonUndoRedoSerializer());
s.Execute(new DelegateCommand("Type", () => { }, () => { }));
Console.WriteLine($"before saving: {s.SaveBoundaries.Count} boundaries, {(await s.SaveStateAsync()).Length} bytes");
for (int i = 0; i < 1000; i++) s.MarkAsSaved("Saved");
Console.WriteLine($"after 1000 saves: {s.SaveBoundaries.Count} boundaries at position(s) " +
    $"{string.Join(",", s.SaveBoundaries.Select(b => b.Position).Distinct())}, state {(await s.SaveStateAsync()).Length} bytes");

Observed:

before saving: 0 boundaries, 368 bytes
after 1000 saves: 1000 boundaries at position(s) 0, state 85250 bytes

Why it matters

  • The serialized history grows by about 85 bytes for every save that changes nothing.
  • HasUnsavedChanges, GetChangeVisualizations and IsAtSaveBoundary run on every Execute, and each one scans the boundary list.
  • A history UI that lists SaveBoundaries shows the same save point hundreds of times.

Suggested fix / acceptance criteria

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions