Skip to content

Commit b220373

Browse files
Format memory grants as KB/MB/GB instead of raw KB (#76)
Add FormatMemoryGrantKB helper to TextFormatter that picks the most readable unit: KB under 1024, MB with 1 decimal up to 1 GB, GB with 2 decimals above. Applied in both the text output and the runtime summary pane. Closes #68 Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9fe3f33 commit b220373

2 files changed

Lines changed: 23 additions & 5 deletions

File tree

src/PlanViewer.App/Controls/PlanViewerControl.axaml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using PlanViewer.App.Helpers;
1919
using PlanViewer.App.Mcp;
2020
using PlanViewer.Core.Models;
21+
using PlanViewer.Core.Output;
2122
using PlanViewer.Core.Services;
2223

2324
using AvaloniaPath = Avalonia.Controls.Shapes.Path;
@@ -2622,7 +2623,7 @@ static string EfficiencyColor(double pct) => pct >= 80 ? "#E4E6EB"
26222623
? (double)mg.MaxUsedMemoryKB / mg.GrantedMemoryKB * 100 : 100;
26232624
var grantColor = EfficiencyColor(grantPct);
26242625
AddRow("Memory grant",
2625-
$"{mg.GrantedMemoryKB:N0} KB granted, {mg.MaxUsedMemoryKB:N0} KB used ({grantPct:N0}%)",
2626+
$"{TextFormatter.FormatMemoryGrantKB(mg.GrantedMemoryKB)} granted, {TextFormatter.FormatMemoryGrantKB(mg.MaxUsedMemoryKB)} used ({grantPct:N0}%)",
26262627
grantColor);
26272628
if (mg.GrantWaitTimeMs > 0)
26282629
AddRow("Grant wait", $"{mg.GrantWaitTimeMs:N0}ms", "#E57373");

src/PlanViewer.Core/Output/TextFormatter.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ public static void WriteText(AnalysisResult result, TextWriter writer)
6262
writer.WriteLine($"Runtime: {stmt.QueryTime.ElapsedTimeMs:N0}ms elapsed, {stmt.QueryTime.CpuTimeMs:N0}ms CPU");
6363
if (stmt.MemoryGrant != null && stmt.MemoryGrant.GrantedKB > 0)
6464
{
65-
var grantedMB = stmt.MemoryGrant.GrantedKB / 1024.0;
66-
var usedMB = stmt.MemoryGrant.MaxUsedKB / 1024.0;
67-
var pctUsed = grantedMB > 0 ? usedMB / grantedMB * 100 : 0;
65+
var pctUsed = stmt.MemoryGrant.GrantedKB > 0
66+
? (double)stmt.MemoryGrant.MaxUsedKB / stmt.MemoryGrant.GrantedKB * 100 : 0;
6867
var pctContext = "";
6968
if (result.ServerContext?.MaxServerMemoryMB > 0)
69+
{
70+
var grantedMB = stmt.MemoryGrant.GrantedKB / 1024.0;
7071
pctContext = $", {grantedMB / result.ServerContext.MaxServerMemoryMB * 100:N1}% of max server memory";
71-
writer.WriteLine($"Memory grant: {grantedMB:N1} MB granted, {usedMB:N1} MB used ({pctUsed:N0}% utilized{pctContext})");
72+
}
73+
writer.WriteLine($"Memory grant: {FormatMemoryGrantKB(stmt.MemoryGrant.GrantedKB)} granted, {FormatMemoryGrantKB(stmt.MemoryGrant.MaxUsedKB)} used ({pctUsed:N0}% utilized{pctContext})");
7274
}
7375

7476
// Expensive operators — promoted to right after memory grant.
@@ -323,6 +325,21 @@ private static void WriteGroupedOperatorWarnings(List<WarningResult> warnings, T
323325
}
324326
}
325327

328+
/// <summary>
329+
/// Formats a memory value given in KB to a human-readable string.
330+
/// Under 1,024 KB: show KB (e.g., "512 KB").
331+
/// 1,024 KB to 1,048,576 KB: show MB with 1 decimal (e.g., "533.3 MB").
332+
/// Over 1,048,576 KB: show GB with 2 decimals (e.g., "2.14 GB").
333+
/// </summary>
334+
public static string FormatMemoryGrantKB(long kb)
335+
{
336+
if (kb < 1024)
337+
return $"{kb:N0} KB";
338+
if (kb < 1024 * 1024)
339+
return $"{kb / 1024.0:N1} MB";
340+
return $"{kb / (1024.0 * 1024.0):N2} GB";
341+
}
342+
326343
/// <summary>
327344
/// Replaces newlines with unit separator (U+001F) so multi-line warning messages
328345
/// survive the top-level line split in AdviceContentBuilder.Build().

0 commit comments

Comments
 (0)