5 Module N_DISK_CACHE
gullradriel edited this page 2026-10-09 00:55:18 +02:00

DISK CACHE: a bounded cache of files keyed by content

Functions

Name
int n_disk_cache_size(const N_DISK_CACHE * cache, uint64_t * total)
How many bytes the cache's entries take.
int n_disk_cache_remove(const N_DISK_CACHE * cache, const void * key, size_t key_len, const char * ext)
Remove one entry, for a caller that found it unreadable.
int n_disk_cache_put(const N_DISK_CACHE * cache, const void * key, size_t key_len, const char * ext, const void * data, size_t len)
Store an entry, replacing any under the same key and extension.
int n_disk_cache_prune_group(const N_DISK_CACHE *const * caches, int count, uint64_t max_bytes)
n_disk_cache_prune() over several caches that share one budget.
int n_disk_cache_prune(const N_DISK_CACHE * cache, uint64_t max_bytes)
Remove least recently used entries until the rest fit a budget.
int n_disk_cache_path(const N_DISK_CACHE * cache, const void * key, size_t key_len, const char * ext, char * out, size_t out_len)
The file an entry lives in, whether or not it exists.
N_DISK_CACHE * n_disk_cache_open(const char * dir)
Use a directory as a cache.
int n_disk_cache_get(const N_DISK_CACHE * cache, const void * key, size_t key_len, const char * ext, size_t max_len, unsigned char ** data, size_t * len)
Read an entry.
int n_disk_cache_expire(const N_DISK_CACHE * cache, int64_t max_age_seconds)
Remove every entry unused for longer than an age.
const char * n_disk_cache_dir(const N_DISK_CACHE * cache)
The cache's directory, as it was opened.
void n_disk_cache_close(N_DISK_CACHE ** cache)
Forget a cache.

Defines

Name
N_DISK_CACHE_NAME_LEN
length of an entry's name before its extension: 128 bits in hexadecimal

Functions Documentation

function n_disk_cache_size

int n_disk_cache_size(
    const N_DISK_CACHE * cache,
    uint64_t * total
)

How many bytes the cache's entries take.

Parameters:

  • cache the cache. Must not be NULL.
  • total receives the sum of the entries' sizes. Must not be NULL.

Return: how many entries there are, or -1 when the directory cannot be read.

function n_disk_cache_remove

int n_disk_cache_remove(
    const N_DISK_CACHE * cache,
    const void * key,
    size_t key_len,
    const char * ext
)

Remove one entry, for a caller that found it unreadable.

Parameters:

  • cache the cache. Must not be NULL.
  • key the key's bytes. Must not be NULL.
  • key_len how many bytes of key.
  • ext the extension, as for n_disk_cache_path().

Return: TRUE when it is gone or was never there, FALSE when it could not be removed.

function n_disk_cache_put

int n_disk_cache_put(
    const N_DISK_CACHE * cache,
    const void * key,
    size_t key_len,
    const char * ext,
    const void * data,
    size_t len
)

Store an entry, replacing any under the same key and extension.

Parameters:

  • cache the cache. Must not be NULL.
  • key the key's bytes. Must not be NULL.
  • key_len how many bytes of key.
  • ext the extension, as for n_disk_cache_path().
  • data the entry. May be NULL when len is 0.
  • len its length in bytes.

Return: TRUE, or FALSE when it could not be written.

Written through n_file_write_atomic(): a reader never sees half an entry.

function n_disk_cache_prune_group

int n_disk_cache_prune_group(
    const N_DISK_CACHE *const * caches,
    int count,
    uint64_t max_bytes
)

n_disk_cache_prune() over several caches that share one budget.

Parameters:

  • caches the caches. Must not be NULL; a NULL entry is skipped.
  • count how many, 1 or more.
  • max_bytes the budget for all of them together. 0 removes every entry.

Return: how many entries were removed, or -1 when a directory cannot be read, in which case nothing was removed.

Every entry of every cache in one list, sorted by the time each was last used, oldest first, and removed in that order until the total of all of them fits: one least recently used order across the directories, so a program that keeps two kinds of derived file apart still has one bound on the disk it takes, and neither kind is emptied first to spare the other.

function n_disk_cache_prune

int n_disk_cache_prune(
    const N_DISK_CACHE * cache,
    uint64_t max_bytes
)

Remove least recently used entries until the rest fit a budget.

Parameters:

  • cache the cache. Must not be NULL.
  • max_bytes the budget. 0 removes every entry.

Return: how many entries were removed, or -1 when the directory cannot be read.

Sorted by the time each was last used, oldest first, and removed in that order: an exact LRU, not an approximation.

function n_disk_cache_path

int n_disk_cache_path(
    const N_DISK_CACHE * cache,
    const void * key,
    size_t key_len,
    const char * ext,
    char * out,
    size_t out_len
)

The file an entry lives in, whether or not it exists.

Parameters:

  • cache the cache. Must not be NULL.
  • key the key's bytes. Must not be NULL.
  • key_len how many bytes of key.
  • ext appended to the name, with its dot, such as ".png". NULL or "" for none. Must not contain a path separator.
  • out receives the path. Must not be NULL.
  • out_len room in out.

Return: TRUE, or FALSE on a bad argument or a path that does not fit.

function n_disk_cache_open

N_DISK_CACHE * n_disk_cache_open(
    const char * dir
)

Use a directory as a cache.

Parameters:

  • dir the directory. Must not be NULL or empty.

Return: a new cache owned by the caller, to release with n_disk_cache_close(), or NULL when dir is not a directory.

The directory must exist: making a nested one is the caller's (Allegro's al_make_directory(), or mkdir -p). Nothing in it is read or changed here.

function n_disk_cache_get

int n_disk_cache_get(
    const N_DISK_CACHE * cache,
    const void * key,
    size_t key_len,
    const char * ext,
    size_t max_len,
    unsigned char ** data,
    size_t * len
)

Read an entry.

Parameters:

  • cache the cache. Must not be NULL.
  • key the key's bytes. Must not be NULL.
  • key_len how many bytes of key.
  • ext the extension, as for n_disk_cache_path().
  • max_len the largest entry accepted; a larger one is a miss.
  • data receives a new buffer the caller frees with free(), one byte longer than the entry and NUL-terminated. Must not be NULL.
  • len receives the entry's length. Must not be NULL.

Return: TRUE on a hit, FALSE on a miss or an unreadable entry (then *data is NULL).

function n_disk_cache_expire

int n_disk_cache_expire(
    const N_DISK_CACHE * cache,
    int64_t max_age_seconds
)

Remove every entry unused for longer than an age.

Parameters:

  • cache the cache. Must not be NULL.
  • max_age_seconds how long an entry may go unused. 0 or less removes nothing.

Return: how many entries were removed, or -1 when the directory cannot be read.

function n_disk_cache_dir

const char * n_disk_cache_dir(
    const N_DISK_CACHE * cache
)

The cache's directory, as it was opened.

Parameters:

  • cache the cache.

Return: a string owned by the cache, or "" for a NULL cache.

function n_disk_cache_close

void n_disk_cache_close(
    N_DISK_CACHE ** cache
)

Forget a cache.

Parameters:

  • cache address of the handle; set to NULL. NULL, or a pointer to NULL, is a no-op.

Its files stay on disk.

Macros Documentation

define N_DISK_CACHE_NAME_LEN

#define N_DISK_CACHE_NAME_LEN 32

length of an entry's name before its extension: 128 bits in hexadecimal