Skip to content

Waterfill column-width distribution - #3

Merged
dnouri merged 1 commit into
mainfrom
feat/waterfill-widths
Mar 18, 2026
Merged

Waterfill column-width distribution#3
dnouri merged 1 commit into
mainfrom
feat/waterfill-widths

Conversation

@dnouri

@dnouri dnouri commented Mar 18, 2026

Copy link
Copy Markdown
Owner

Replace the ad-hoc proportional allocator with an analytical waterfill: find the unique level L where sum(min(nat, L·√nat)) = budget, then round via Webster/Sainte-Laguë.

The old algorithm had binary thresholds for small-column protection and tight-budget fallback that caused columns to shrink when the terminal got wider. The waterfill is monotonic by construction — no column ever loses width when more space becomes available.

The cliff

A table with columns | ID | Name | Category | Description | (natural widths 2, 12, 11, 93) hits a catastrophic discontinuity at width 39. The old algorithm suddenly protects Name and Category at full width, starving Description to 1 character — one letter per line:

Before (w=38 → w=39):

w=38: ID=1  Name=4   Category=4   Description=16
w=39: ID=2  Name=12  Category=11  Description=1   ← one letter per line
w=40: ID=2  Name=12  Category=11  Description=2

After — smooth progression, no column ever shrinks:

w=38: ID=2  Name=5  Category=4  Description=14
w=39: ID=2  Name=5  Category=5  Description=14
w=40: ID=2  Name=5  Category=5  Description=15

Benchmark

resize-all improves ~15% (fewer GC cycles from dropping the per-cell longest-word scan):

            main        waterfill
resize-all  ~1435ms     ~1210ms
GCs         268         220

Changes

  • Replace four-phase distribute-widths with analytical waterfill + Webster rounding
  • Remove min-word-widths from compute-table-metrics (no longer used)
  • Remove --longest-word-width helper and --small-column-threshold constant
  • Net −31 lines of production code

Replace the ad-hoc proportional allocator with an analytical
waterfill: find the unique level L where sum(min(nat, L·√nat))
equals the budget, then round via Webster/Sainte-Laguë.

The old algorithm had binary thresholds for small-column protection
and tight-budget fallback that caused columns to shrink when the
terminal got wider.  The waterfill is monotonic by construction —
no column ever loses width when more space becomes available.

The min-word-width metric is no longer needed and is removed from
compute-table-metrics, which also drops the per-cell longest-word
scan.  resize-all bench improves ~15% (fewer GC cycles).
@dnouri
dnouri merged commit 6410be7 into main Mar 18, 2026
7 checks passed
@dnouri
dnouri deleted the feat/waterfill-widths branch March 18, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant