Cache Infrastructure
HotPDF provides bounded memory caching plus persistent caches for reusable font subsets and rendered pages
Weighted memory cache
THPDFWeightedCache in HPDFCache owns TObject values, indexes them by AnsiString, and evicts the least recently used values until their combined weight fits MaxBytes
GetandTryGetpromote a hit to most recently used and update request statisticsPeekandContainsKeyinspect entries without changing recency or request statisticsPuttakes ownership, replaces an existing key in place, and safely accepts the same object again when only its weight changesRemovefrees an entry, whileExtracttransfers ownership to the caller- Reducing
MaxBytesevicts entries immediately, andTrimToBudgetexposes the same convergence operation explicitly Hits,Misses,HitRate,Evictions,Rejections, andReplacementsexpose cache behavior, whileResetStatisticsstarts a new measurement interval- Slot capacity grows geometrically and live entries remain linked in constant-time recency order
Content keys
function HPDFCacheKeyOfBytes(const Bytes: TBytes): AnsiString;
function HPDFCacheKeyOfStream(Stream: TStream): AnsiString;
Both functions return the same lowercase SHA-256 hexadecimal key for the same content
HPDFCacheKeyOfStream hashes without allocating a second full-size byte array, reads seekable streams from position zero, and restores their original position
Loaded-font decoder cache
Each THotPDF instance retains successfully parsed loaded-font decoders in a document-scoped weighted LRU cache
- The default budget is 32 MiB with a hard limit of 128 entries, and a zero-byte budget disables retention
- Shared indirect font dictionaries reuse one parsed core across pages even when pages use different resource names
- Text extraction, SVG export, loaded text replacement, and explicit decoder requests share the same cache
GetLoadedFontDecoderdeep-copies managed arrays so callers cannot mutate cached mappings or widths- Document reload, graph mutation, page invalidation, JSON Patch, and every
CMapResourcePathassignment clear retained decoders - Decoder acquisition is serialized per document to avoid duplicate parsing of one font, but the lock does not make concurrent document mutation safe
GetLoadedFontDecoderCacheInfoexposes entries, estimated bytes, budget, hits, misses, parses, evictions, and invalidations
Sharded loaded-image decode cache
Each THotPDF instance coordinates loaded-image decode reuse through 16 independently locked metadata shards
- Cache lookup and admission hold only the selected shard while expensive filter and image decoding runs outside cache locks
- An exact per-key singleflight elects one owner decode and makes duplicate callers wait for the same completed result
- The configured
ImageCacheMaxBytes, entry-count limit, and per-entry limit remain global across all shards - Decoded-image entries hold immutable reference-counted handles that survive eviction and let renderers draw warm hits without materializing a
TBitmapcopy - Completed images are copied into caller-owned
TBitmapinstances so callers cannot mutate retained cache pixels - Document reload and image-cache invalidation clear completed entries while active flight objects retain their own reference-counted lifetime
GetImageDecodeConcurrencyInforeports active flights, active and peak owner decodes, waits, completions, and failures
ICC transform cache
HPDFICC shares complete source-to-sRGB transforms through a thread-safe 64 MiB weighted LRU cache, including proof and output profiles when configured
- The SHA-256 key covers the complete source, proof and output profile contents, effective rendering intent and black-point compensation setting
HPDFGetICCTransformCacheInforeports hits, misses, evictions, rejections, entry count, current bytes and maximum bytesHPDFSetICCTransformCacheMaxBytesapplies a new process-wide budget immediately and evicts least recently used transforms as neededHPDFClearICCTransformCachereleases retained transforms and resets request statistics without invalidating transform interfaces already held by callers
Persistent font-subset cache
Set THotPDF.FontSubsetCacheFolder to enable reusable TrueType and OpenType subset results while EnableFontSubsetting is active
- The key covers the original font bytes, exact used-glyph bitmap, compact or sparse mode, and cache schema version
- Both the normal GDI font-store path and the registered Unicode-font finalizer reuse the same cache
- Compact PDF/A entries preserve the old-to-new GID map and new glyph count needed by
CIDToGIDMap - Entries are validated before use, corrupt entries are removed, and replacement uses an atomic same-directory move
FontSubsetCacheMaxBytesapplies immediately and evicts the least recently accessed exact cache files without traversing unrelated foldersGetFontSubsetCacheInforeports hits, misses, writes, evictions, corruption, rejections, write failures, bytes, and filesClearFontSubsetCacheremoves only font-subset entries and abandoned temporary entries from the configured folder
PDF.EnableFontSubsetting := True;
PDF.FontSubsetCacheFolder := 'C:\ProgramData\MyApp\HotPDF\FontSubsets';
PDF.FontSubsetCacheMaxBytes := 256 * 1024 * 1024;
Persistent rendered-page cache
Set THotPDF.RenderCacheFolder to enable the disk tier used after the in-memory rendered-page cache
- Page files are keyed by document content, zero-based page index, DPI, effective optional-content visibility, color intent, and fallback policy
- Layer and color-intent changes select reusable state variants instead of discarding every cached bitmap
- PNG and index updates are atomic, and abandoned temporary files are removed during recovery
- Page reads refresh page-level recency, while document count, page count, and byte limits evict least recently used data
- Reducing a configured limit converges immediately instead of waiting for a later write
- Corrupt PNG files, stale or duplicate index rows, missing folders, and unindexed cache folders are repaired automatically
- Invalid document keys and coordinates are rejected before filesystem access
- Linked document folders are skipped during recovery, reads, writes, invalidation, and eviction; links and their external target files are preserved
Ownership
THPDFWeightedCacheowns values passed toPutunless a value is returned byExtractTHPDFDiskPageCache.Lookupreturns a newly allocated bitmap owned by the caller- Bitmap values passed to
THPDFDiskPageCache.Storeremain owned by the caller
Related APIs
- Persistent Font-Subset Cache
- THotPDF.LoadedFontDecoderCacheMaxBytes
- THotPDF.GetLoadedFontDecoderCacheInfo
- Sharded Loaded-Image Decode Cache
- THotPDF.GetImageDecodeConcurrencyInfo
- THotPDF.RenderCacheFolder
- THotPDF.RenderCacheMaxDocuments
- THotPDF.RenderCacheMaxBytes
- THotPDF.RenderLoadedPageToBitmapCached
- Rendering Diagnostics and Operation Telemetry