Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion research/ui/analyze_output_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,26 @@ def heartbeat_summary(trace: list[dict]) -> list[str]:
gaps[:3], states[:3]))
return lines

def resize_summary(trace: list[dict]) -> list[str]:
"""Pair geometry switches with repaint batches, which is what decides whether
a repaint was generated for the previous grid but consumed with the new one."""
resizes = [row for row in trace if row.get("schema") == "termforge-resize-trace-v1"]
repaints = [row for row in trace if row.get("schema") == "termforge-output-trace-v1" and row.get("repaint")]
if not resizes:
return []
lines: list[str] = []
for row in resizes:
terminal = row.get("terminal")
at = row.get("t_ms") or 0
after = [r for r in repaints if r.get("terminal") == terminal and (r.get("t_ms") or 0) >= at][:2]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use trace order to exclude repaints preceding the resize

When a repaint and a subsequent resize have the same t_ms, this filter incorrectly pairs the earlier repaint with the later resize. Both producers in experiments/shell/shell.cpp use GetTickCount64(), so equal timestamps do not establish event order; the JSONL record order distinguishes them. A synthetic trace containing an 80-column repaint, then an 80→112 resize at the same timestamp, produces resize ... -> 112x24 ... | repaint +0ms 80x24, falsely suggesting an old-grid repaint followed the geometry switch. Select repaint records occurring after the resize record, using timestamps only to calculate the elapsed time.

Useful? React with 👍 / 👎.

detail = ", ".join(
"repaint +%dms %sx%s" % ((r.get("t_ms") or 0) - at, r.get("columns"), r.get("rows"))
for r in after)
lines.append(" resize term%s %sx%s -> %sx%s at %s%s" % (
terminal, row.get("old_columns"), row.get("old_rows"), row.get("columns"), row.get("rows"), at,
(" | " + detail) if detail else ""))
return lines

def main():
import argparse
parser = argparse.ArgumentParser(description=__doc__)
Expand All @@ -120,7 +140,10 @@ def main():
for stage in stages:
for line in describe(stage):
print(line)
for line in heartbeat_summary(read_jsonl(stage / "output-trace.jsonl")):
trace_rows = read_jsonl(stage / "output-trace.jsonl")
for line in heartbeat_summary(trace_rows):
print(line)
for line in resize_summary(trace_rows):
print(line)


Expand Down