1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//! Block-level render memoization for the parse → render pipeline.
//!
//! `ParsedDoc::build` re-renders every top-level block on every reparse,
//! even though a typical edit changes exactly one block. [`RenderCache`]
//! memoizes each block's rendered lines keyed by the block's AST value, so
//! an unchanged block costs a clone of its cached lines instead of a full
//! re-render (inline styling, word measurement, table column layout).
//! See docs/perf-benchmark-plan.md — rendering dominated the pipeline for
//! table-heavy and mixed documents before memoization.
//!
//! Keying by the `Block` value (not the source byte slice) is what makes
//! the cache safe against everything that changes rendering without
//! changing source text: live table-width drag overrides, post-pass
//! promotions, and list splitting all mutate the AST, so a mutated block
//! simply misses the cache and re-renders.
//!
//! `Block::ImageBlock` is never cached: its rendered row count depends on
//! the image decode cache (via the renderer's row override), which changes
//! out-of-band as decodes complete. Image blocks are cheap placeholder
//! fills, so re-rendering them is free anyway.
use HashMap;
use Line;
use Block;
/// Fingerprint of every `Renderer` input that affects a block's rendered
/// lines besides the block itself. When any of these change between
/// builds the whole cache is cleared. The theme is identified by address
/// — themes are `&'static` and the editor already treats pointer identity
/// as theme identity (`EditorState::set_theme` short-circuits on
/// `ptr::eq`).
pub
/// Memoized rendered lines per top-level block, owned by `EditorState`
/// and threaded into `ParsedDoc::build_with_overrides` on every reparse.
///
/// Eviction is by document membership: each build moves the entries it
/// hits into a fresh map and drops the old map afterwards, so blocks no
/// longer present in the document are released immediately — the same
/// keep-what's-live policy as the image cache GC.