![]() |
Nilorea Library
C utilities for networking, threading, graphics
|
A bounded cache of files in one directory, keyed by content. More...
Go to the source code of this file.
Macros | |
| #define | N_DISK_CACHE_NAME_LEN 32 |
| length of an entry's name before its extension: 128 bits in hexadecimal | |
Functions | |
| void | n_disk_cache_close (N_DISK_CACHE **cache) |
| Forget a cache. | |
| const char * | n_disk_cache_dir (const N_DISK_CACHE *cache) |
| The cache's directory, as it was opened. | |
| int | n_disk_cache_expire (const N_DISK_CACHE *cache, int64_t max_age_seconds) |
| Remove every entry unused for longer than an age. | |
| 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. | |
| N_DISK_CACHE * | n_disk_cache_open (const char *dir) |
| Use a directory as a cache. | |
| 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. | |
| 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_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_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_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_size (const N_DISK_CACHE *cache, uint64_t *total) |
| How many bytes the cache's entries take. | |
A bounded cache of files in one directory, keyed by content.
A program that derives something expensive from a source, a thumbnail from a photograph, a transcoded file, a downloaded page, keeps the result on disk under a key that names everything it was derived from: change any of it and the key changes, so a stale entry is a miss rather than a wrong answer.
A key is any bytes. It is hashed (MurmurHash3, 128 bits) into a file name of 32 hexadecimal digits, followed by the caller's extension, in the cache's directory. Nothing else is stored: no index file to corrupt or keep in step.
Entries go in with n_disk_cache_put() (written atomically, so a crash leaves the old entry or the new one) and come out with n_disk_cache_get(). A caller whose data is written and read by another library, an image codec saving straight to a path, asks for the path with n_disk_cache_path() instead.
The cache is bounded by n_disk_cache_prune(), which removes least recently used entries until the directory is under a size, and n_disk_cache_expire(), which removes entries unused for longer than an age. "Used" is the access time where the filesystem keeps one, else the write time.
Both only ever remove files whose names this module could have made: 32 lowercase hexadecimal digits, then nothing or a '.'. A cache pointed at a directory that holds other files leaves them alone.
Nothing is kept in memory but the directory name, so any number of threads may use one cache; two writing the same key at once leave one of the two.
Definition in file n_disk_cache.h.