PdfBudgetedCache<K, V> class
One bounded, least-recently-used cache that every in-package cache is built on, so the eviction rules live (and are property-tested) in exactly one place instead of being re-derived - subtly differently, and with a fresh off-by-one each time - at six call sites.
A key map provides lookups and a linked list tracks recency, so touching an entry or evicting the oldest one takes constant time even when the cache is full. Two independent bounds cap growth, either or both of which a call site may leave off:
- a weight budget (maxWeight) measured in whatever unit the
weigherreturns - decoded image bytes, exact-raster pixels, retained command slots. Eviction under this budget skips weight-0 entries (they free nothing yet cost a re-decode to rebuild) and never drops the single most-recently-used entry, so a lone page larger than the whole budget is still available for the render that just asked for it - unlessrejectOversizeis set, in which case an entry heavier than the whole budget is never stored (the record cache's policy). - an entry count (maxEntries), which does see weight-0 entries - the bound that stops image-free / vector-first buffers piling up one per page on a long scroll (issue #283, the weight-0 unbounded-growth bug).
Values that outlive their cache slot are handled by three hooks:
cloner- when a value is handed out while a master stays cached (aui.Imageshared by clone), take and putAndClone returncloner(value)so a caller disposing its copy, or eviction dropping the master, can never pull pixels out from under a picture still painting.disposer- run on every value the cache drops (eviction, evict, clear, dispose, or a same-key overwrite), so retained engine resources are released deterministically.onEvicted- optional diagnostics invoked only when a weight/count or coordinated process budget evicts an entry. Explicit invalidation, clearing, and same-key replacement do not count as policy evictions.
Registering with PdfCacheRegistry (via clearsUnderMemoryPressure: true)
wires the cache into the one coordinated memory-pressure path.
Constructors
- PdfBudgetedCache({int weigher(V value)?, int? maxWeight, int? maxEntries, void disposer(V value)?, V cloner(V value)?, void onEvicted(K key, V value)?, bool rejectOversize = false, bool clearsUnderMemoryPressure = false, String debugLabel = 'cache'})
-
Creates a cache bounded by
maxWeight(usingweigher) and/ormaxEntries. At least one bound should be given or the cache grows without limit.maxEntriesis floored at 1 so the cache always keeps the most-recently-used entry. WhenclearsUnderMemoryPressureis set the cache registers with PdfCacheRegistry for its lifetime (until dispose).
Properties
- debugLabel → String
-
A short name used in registry accounting and diagnostics.
final
- evictions → int
-
Entries dropped by an eviction bound (not counting evict/clear).
no setter
- hashCode → int
-
The hash code for this object.
no setterinherited
- hits → int
-
Lookups served from a retained value.
no setter
-
keys
→ Iterable<
K> -
The retained keys, least-recently used first.
no setter
- length → int
-
Number of retained entries.
no setter
- maxEntries → int?
-
The count cap, or null when the cache is unbounded by entry count.
no setter
- maxWeight ↔ int
-
The weight budget (in the
weigher's unit). Lowering it trims to the new budget at once; raising it lets later inserts fill the extra room. Only meaningful when a weigher was supplied.getter/setter pair - misses → int
-
Lookups that missed.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
-
values
→ Iterable<
V> -
The retained values, least-recently used first.
no setter
- weight → int
-
Total weight currently retained (occupancy, not a reservation).
no setter
Methods
-
clear(
) → void - Empties the cache, disposing every retained value. Counters survive - a clear is a cache operation, not a fresh measurement. Any clones already handed out are unaffected.
-
containsKey(
K key) → bool -
Whether a value is retained for
key, without touching LRU order. -
dispose(
) → void - Empties the cache and detaches it from the memory-pressure registry. Further puts are dropped (returning the value uncached).
-
evict(
K key) → void -
Drops (and disposes) the retained value for
key. A no-op on a miss. -
evictWhere(
bool test(K key)) → void -
Drops (and disposes) every retained entry whose key satisfies
test. Used for targeted, per-page invalidation - a render worker evicting just the pages an incremental revision changed instead of clearing the whole cache. Counters and every non-matching entry are untouched. -
getOrAdd(
K key, V ifAbsent()) → V -
The value for
key, computing and storing it withifAbsenton a miss. The compute-once counterpart of take/put used by caches whose values are built lazily (text layouts, per-page derived objects). The stored value is returned directly (no clone) - the master is shared, not handed out. A hit marks the entry most-recently used and never runsifAbsent. -
lookup(
K key) → V? -
The stored value for
key, counted as a hit or miss like take but without touching LRU order or running thecloner; null on a miss. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
peek(
K key) → V? -
The retained value for
keywithout touching LRU order or the hit/miss counters, or null on a miss. Returns the master itself, never a clone - for read-only inspection (staleness checks, rebinding), not handing out. -
put(
K key, V value) → V -
Stores
valueunderkey(the cache takes ownership, disposing any previous value for that key) and evicts down to the bounds. Returnsvalueitself - the caller has handed it off. Use putAndClone when the caller needs its own independent copy of a shared value. -
putAndClone(
K key, V value) → V -
Stores
valueas the retained master (like put) and returns an independentclonercopy for the caller to use and dispose, so a caller that both populates and paints in one step never shares the exact object the cache may later evict. Requires acloner. -
remapKeys(
K keyFor(K key)) → void - Re-keys retained entries without disposing their values or changing LRU order.
-
resetCounters(
) → void - Zeroes the hit/miss/eviction counters (they survive clear, which is a cache operation, not a fresh measurement). Used by benchmarks that reuse a warm cache across measurement passes.
-
take(
K key) → V? -
The value for
key- a clone when aclonerwas supplied, else the stored value - moved to most-recently-used, or null on a miss. -
toString(
) → String -
A string representation of this object.
inherited
-
trimToWeight(
int target) → void -
Evicts least-recently-used weight-bearing entries until retained weight
is at or under
target(floored at 0). Like the budget eviction in_trim, the most-recently-used entry is protected and weight-0 entries are skipped (evicting them frees nothing). A no-op without aweigher. -
weightOf(
K key) → int? -
The weight of the retained entry for
key, or null on a miss. Does not touch LRU order - a pure peek.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited