AxlPageCache — LRU Page Cache
See AxlData — Data Structures for an overview of all data modules.
A fixed-capacity LRU cache of equal-sized pages backed by a caller-supplied fill function. Lookups return a borrowed, zero-copy pointer into the resident frame; on a miss the least-recently-used frame is evicted and refilled. It is the mechanism behind AxlFileView but knows nothing about files — the fill function decides where bytes come from, so it windows any large, randomly-addressed backing store where only the hot pages should stay resident.
Header: <axl/axl-page-cache.h>
API Reference
Typedefs
-
typedef struct AxlPageCache AxlPageCache
axl-page-cache.h:
A fixed-capacity LRU cache of equal-sized pages, backed by a caller-supplied fill function. The cache owns a pool of page frames; on a miss it evicts the least-recently-used frame and calls the fill function to populate it. Lookups return a borrowed pointer into the resident frame — zero-copy, no per-access value copy.
It is the mechanism behind AxlFileView (pages faulted in from a file via positional reads), but knows nothing about files: the fill function decides where bytes come from, so the same cache windows any large, randomly-addressed backing store (block device, decompressed stream, generated data) where only the hot pages should stay resident.
Distinct from AxlCache: that is a TTL, string-keyed, copy-in/copy-out value cache; this is a capacity-only, integer-indexed, zero-copy page cache whose frames are recycled in place on eviction.
Two usage modes share one frame pool and LRU:
Single-tenant — axl_page_cache_new(… fill …) binds one fill function; axl_page_cache_get keys frames by page index alone.
Multi-tenant — axl_page_cache_new_shared() makes a fill-less cache that several owners share; axl_page_cache_fetch keys frames by (owner, page index) and takes the fill per call, so one budget of resident frames serves many backing stores (e.g. every open file in an editor). axl_page_cache_drop_owner reclaims a closing owner’s frames. (Single-tenant get is the multi-tenant fetch with the cache itself as the owner.)
Single-threaded (UEFI). Borrowed page pointers are valid only until the next axl_page_cache_get / _fetch / _clear that may evict.
-
typedef int64_t (*AxlPageFillFunc)(void *user, size_t page_index, void *dst, size_t cap)
AxlPageFillFunc:
Populate the frame for page_index. dst has cap bytes (the cache’s page size); write up to cap bytes of that page’s content and return how many were written. A short count (< cap) marks a partial trailing page — the cache records it as the page’s valid length. Return -1 on error; the cache then leaves the frame empty and axl_page_cache_get returns NULL.
- Return:
bytes written (0..cap), or -1 on error.
Functions
-
AxlPageCache *axl_page_cache_new(size_t page_size, size_t max_frames, AxlPageFillFunc fill, void *user)
Create a page cache.
Allocates max_frames frames of page_size bytes up front.
- Parameters:
page_size – bytes per page (frame capacity)
max_frames – resident frame count (LRU capacity)
fill – page-fill callback (required)
user – opaque cookie passed to
fill
- Returns:
new cache, or NULL on OOM / invalid args (page_size or max_frames zero, or fill NULL). Free with axl_page_cache_free().
Create a shared (multi-tenant) page cache.
Like axl_page_cache_new but with no bound fill function: several owners share the one frame pool and LRU via axl_page_cache_fetch, each supplying its own fill per call and its own owner token. Use it to cap the total resident pages across many backing stores (e.g. all open files in an editor). axl_page_cache_get is not available on a shared cache (it has no default fill) — use fetch.
- Parameters:
page_size – bytes per page (frame capacity)
max_frames – resident frame count shared across all owners
- Returns:
new cache, or NULL on OOM / invalid args (
page_sizeormax_frameszero). Free with axl_page_cache_free().
-
void axl_page_cache_free(AxlPageCache *pc)
Free a page cache and its frame pool. NULL-safe.
- Parameters:
pc – cache (NULL-safe)
-
const void *axl_page_cache_get(AxlPageCache *pc, size_t page_index, size_t *valid_len)
Get a borrowed pointer to a resident page.
Returns a pointer to the start of page_index’s frame, faulting it in via the fill function on a miss (evicting the LRU frame first).
*valid_lenreceives the page’s valid byte count (what the fill function returned).The pointer is valid only until the next axl_page_cache_get / _fetch / _clear call, which may evict this frame. Do not free it.
- Parameters:
pc – cache
page_index – page to fetch
valid_len – [out, optional] valid bytes in the page
- Returns:
frame pointer, or NULL if the fill function reported an error (or the cache has no bound fill — i.e. a shared cache; use _fetch).
-
const void *axl_page_cache_fetch(AxlPageCache *pc, const void *owner, size_t page_index, AxlPageFillFunc fill, void *user, size_t *valid_len)
Get a borrowed page for a specific owner (multi-tenant).
Like axl_page_cache_get but keys the frame by (
owner,page_index) and takes thefill/userfrom the call rather than the cache’s constructor, so distinct owners never collide on the same page index and one cache serves many backing stores.owneris any stable, unique pointer identifying the tenant (typically the owning object). Eviction is global LRU across all owners.Works on both shared and single-tenant caches. The borrowed pointer is valid only until the next get / fetch / clear that may evict.
- Parameters:
pc – cache
owner – tenant identity (stable, unique pointer)
page_index – page to fetch within the owner
fill – fill callback for a miss (required)
user – opaque cookie passed to
fillvalid_len – [out, optional] valid bytes in the page
- Returns:
frame pointer, or NULL if
fillis NULL or reported an error.
-
void axl_page_cache_drop_owner(AxlPageCache *pc, const void *owner)
Evict every resident frame belonging to
owner.A closing tenant (e.g. an AxlFileView sharing the cache) calls this to return its frames to the pool. Frames of other owners are untouched.
- Parameters:
pc – cache
owner – tenant whose frames to drop
-
size_t axl_page_cache_page_size(const AxlPageCache *pc)
Page size (frame capacity) in bytes.
- Parameters:
pc – cache
-
void axl_page_cache_clear(AxlPageCache *pc)
Drop all resident pages (e.g. the backing store changed).
Frames become empty; the next get of any page is a miss. Stats are reset to zero.
- Parameters:
pc – cache
-
void axl_page_cache_stats(const AxlPageCache *pc, AxlPageCacheStats *out)
Snapshot the cache counters.
- Parameters:
pc – cache
out – [out] counters (zeroed if
pcis NULL)
-
struct AxlPageCacheStats
- #include <axl-page-cache.h>
Cache counters (monotonic; reset by axl_page_cache_clear).