THPDFCoalescingRandomAccessSource Class
Wraps any THPDFRandomAccessSource with bounded range caching and cancellation-aware asynchronous prefetch
Declaration
constructor Create(
ASource: THPDFRandomAccessSource;
OwnsSource: Boolean = False;
BlockSize: Integer = 262144;
MaxCacheBytes: Int64 = 2097152;
MaxEntryBytes: Int64 = 0;
MaxCacheEntries: Integer = 0;
AdaptiveAdmission: Boolean = True);
procedure PrefetchRange(Offset, Count: Int64);
procedure ObserveReadPattern(Offset: Int64; Count: Integer);
function TransferAt(Offset, Count: Int64;
Destination: TStream): Int64;
procedure CancelPrefetch;
function IsPrefetchActive: Boolean;
procedure ClearCache;
procedure ConfigureCacheAdmission(MaxCacheBytes,
MaxEntryBytes: Int64; MaxCacheEntries: Integer;
AdaptiveAdmission: Boolean = True);
procedure GetStatistics(out Statistics: THPDFRangeCacheStatistics);
property BlockSize: Integer;
property MaxCacheBytes: Int64;
property MaxEntryBytes: Int64;
property MaxCacheEntries: Integer;
property AdaptiveAdmissionEnabled: Boolean;
property AsyncPrefetchEnabled: Boolean;
property AdaptiveReadAheadEnabled: Boolean;
property MaxReadAheadBlocks: Integer;
property SequentialReadToleranceBytes: Integer;
Range coalescing
- A cache miss expands to an aligned block that covers the requested bytes, so adjacent parser reads share one backing-store request
- The cache enforces independent total-byte, per-entry, and optional entry-count limits, and an oversized range bypasses retention
- Adaptive admission combines least-recently-used order with a bounded aging frequency sketch, so cold scans read directly without replacing hotter retained ranges
- When a sparse source cannot provide an expanded block, the wrapper falls back to the exact available requested range
- Source access is serialised so existing subclasses do not need to become thread safe
Asynchronous prefetch and cancellation
PrefetchRange schedules one background range and replaces an unrelated earlier request
A foreground cache miss outside the active range cancels the worker before acquiring the source lock, allowing a cooperative transport to yield promptly to the visible operation
Override THPDFRandomAccessSource.ReadAtCancellable to inspect the supplied THPDFCancellationToken during network or storage I/O; the inherited implementation checks cancellation immediately before and after ReadAt
Set AsyncPrefetchEnabled to False when transport policy forbids background access
Adaptive read-ahead
The parser stream calls ObserveReadPattern after each successful read; sustained forward reads grow the read-ahead window through 1, 2, 4, and 8 blocks, while a seek or backward access immediately suppresses speculative transport
SequentialReadToleranceBytes accepts small forward gaps as sequential access and defaults to 4096 bytes; MaxReadAheadBlocks limits the adaptive window from 1 through 32 blocks and defaults to 8
The effective window is also limited by MaxCacheBytes, so read-ahead cannot intentionally exceed the configured cache capacity; sequential confidence recovers gradually after a random jump
Set AdaptiveReadAheadEnabled to False for fixed one-block prefetch while retaining asynchronous transport
Statistics
TransferAt acquires retained cache-block references and writes them to the destination without allocating or filling an intermediate read buffer
THPDFRangeCacheStatistics reports backing-source read count and bytes, cache hits and misses, cache admissions, rejections and evictions, frequency admissions, rejections and aging, prefetch requests, completions and cancellations, sequential and random reads, suppressed prefetches, current and peak read-ahead blocks, direct transfer calls and bytes, plus current cached range count and bytes
Ownership
When OwnsSource is True, destroying the wrapper cancels and joins its worker, releases cached ranges, and frees the wrapped source