Skip to content
Merged
Show file tree
Hide file tree
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ Open cycle — bug-fix / housekeeping. Entries land here as they merge.
large table this removes the dominant per-cell layout allocation. No public API
or behaviour change.

- **Process-wide line-metrics cache stops inserting instead of flushing when full.**
The static line-metrics cache `clear()`-ed every entry once it passed 50,000
distinct styles — a full flush whose non-atomic check-then-clear is a
thundering-herd recompute under concurrent rendering. It now stops inserting at
the cap and keeps the existing entries (distinct styles are few in real use, so
this is only a pathological-explosion guard; it runs on a cache miss, never on
the per-measurement path). **Measured line metrics are unchanged.** No public API
or behaviour change.

### Tests / tooling

- **Benchmark regression gate and measurement probe (benchmarks module, not part
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,16 @@ private GlobalPdfStyleKey globalPdfStyleKey(PdfFont font, TextStyle style) {
}

private static void cacheGlobalLineMetrics(GlobalPdfStyleKey key, LineMetrics metrics) {
if (GLOBAL_PDF_LINE_METRICS_CACHE.size() > GLOBAL_LINE_METRICS_CACHE_LIMIT) {
GLOBAL_PDF_LINE_METRICS_CACHE.clear();
// Safety cap on the process-wide line-metrics cache. Distinct styles are
// few in real use (a handful of font/size/decoration combos); this only
// guards a pathological style explosion. Stop inserting once full instead
// of clear()-ing: the old full flush wiped every hot entry under
// concurrent rendering (a thundering-herd recompute), so keeping the
// existing entries is strictly better. This runs on a cache miss only,
// never on the per-measurement get() path.
if (GLOBAL_PDF_LINE_METRICS_CACHE.size() < GLOBAL_LINE_METRICS_CACHE_LIMIT) {
GLOBAL_PDF_LINE_METRICS_CACHE.putIfAbsent(key, metrics);
}
GLOBAL_PDF_LINE_METRICS_CACHE.putIfAbsent(key, metrics);
}

@Override
Expand Down