|
solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
|
Cache management utilities for performance optimization. More...
#include <stdbool.h>#include <stddef.h>#include <stdint.h>Go to the source code of this file.
Typedefs | |
| typedef struct cache_s | cache_t |
Functions | |
| cache_t * | cache_create (size_t capacity, uint32_t default_ttl) |
| void | cache_destroy (cache_t *cache) |
| const void * | cache_get (cache_t *cache, const char *key, size_t key_len, size_t *out_len) |
| void | cache_release (const void *ptr) |
| bool | cache_set (cache_t *cache, const char *key, size_t key_len, const void *value, size_t value_len, uint32_t ttl_override) |
| void | cache_invalidate (cache_t *cache, const char *key) |
| void | cache_clear (cache_t *cache) |
| size_t | get_total_cache_size (cache_t *cache) |
| size_t | get_total_capacity (cache_t *cache) |
| bool | cache_save (cache_t *cache_ptr, const char *filename) |
| bool | cache_load (cache_t *cache_ptr, const char *filename) |
Cache management utilities for performance optimization.
Definition in file cache.h.
| typedef struct cache_s cache_t |
| void cache_clear | ( | cache_t * | cache_ptr | ) |
| cache_t * cache_create | ( | size_t | capacity, |
| uint32_t | default_ttl | ||
| ) |
| void cache_destroy | ( | cache_t * | cache_ptr | ) |
| const void * cache_get | ( | cache_t * | cache_ptr, |
| const char * | key, | ||
| size_t | klen, | ||
| size_t * | out_len | ||
| ) |
Zero-Copy Retrieval.
| cache | The cache handle. |
| key | The lookup key. |
| key_len | The length of the key. |
| out_len | Pointer to store the size of the retrieved value. |
Retrieves a value from the cache by key.
On a hit the caller receives a pointer into the entry's data block. The entry's reference count is incremented before the lock is released, ensuring the memory remains valid even if another thread evicts the entry concurrently. The caller MUST call cache_release() when done with the pointer.
On expiry the function upgrades to a write lock to remove the stale entry. A double-check is performed after the upgrade because another thread may have refreshed or removed the entry between the read-unlock and write-lock. Compaction is intentionally NOT triggered here; that is deferred to the write path (cache_set, cache_invalidate) to avoid O(n) work on the read fast path.
| void cache_invalidate | ( | cache_t * | cache_ptr, |
| const char * | key | ||
| ) |
| bool cache_load | ( | cache_t * | cache_ptr, |
| const char * | filename | ||
| ) |
Loads cache entries from a binary file.
Entries that are already expired in the file are skipped. Entries loaded will be subject to the current cache's eviction policy (if the file contains more items than the cache capacity).
| cache_ptr | The cache to load into. |
| filename | The input file path. |
Loads entries from a file previously written by cache_save().
Entries whose expiry timestamp has already passed at load time are silently skipped. The TTL passed to cache_set is computed as the remaining lifetime (expiry - now), preserving the original expiration wall-clock time.
Key buffer strategy: a stack buffer (512 bytes) handles the common case. Oversized keys fall back to a heap buffer that is reused across iterations via realloc to avoid per-entry allocation.
Definition at line 828 of file cache.c.
References cache_set().
| void cache_release | ( | const void * | ptr | ) |
| bool cache_save | ( | cache_t * | cache_ptr, |
| const char * | filename | ||
| ) |
Serializes the current cache state to a binary file.
The operation locks shards one by one, allowing concurrent reads/writes to other shards while saving. The snapshot is not atomic across shards.
| cache_ptr | The cache to save. |
| filename | The output file path. |
Serialises all non-expired entries to a binary file.
File format: [magic:u32][version:u32][entry_count:u64] For each entry: [key_len:u32][value_len:u64][expires_at:i64][key_bytes:key_len][value_bytes:value_len]
entry_count is written as a placeholder (zero) in the header and patched to the actual count at the end via fseek, because expired entries are skipped during iteration and the true count is not known upfront.
| bool cache_set | ( | cache_t * | cache_ptr, |
| const char * | key, | ||
| size_t | klen, | ||
| const void * | value, | ||
| size_t | value_len, | ||
| uint32_t | ttl | ||
| ) |
Stores a value in the cache.
| cache | The cache handle. |
| key | The key. |
| value | The data to store. |
| value_len | The length of the data. |
| ttl_override | Optional TTL in seconds (0 uses default). |
Inserts or updates a key-value pair in the cache.
The new entry is fully constructed outside the lock to minimize critical section duration. If the key already exists the old entry is replaced in-place (size unchanged). On a new insertion, eviction is triggered if the shard is at capacity.
Optimization vs. original: find_slot is called only ONCE per insert. The original code called find_slot a second time after clock_evict() returned, reasoning that the evicted slot might have invalidated idx. This was unnecessary:
Definition at line 550 of file cache.c.
Referenced by cache_load().
| size_t get_total_cache_size | ( | cache_t * | cache_ptr | ) |
Returns the total number of entries currently in the cache across all shards. Thread-safe: acquires read locks on all shards.
| cache | The cache instance. |
Returns the total number of live entries across all shards. Each shard is read-locked independently; the returned value is a consistent per-shard snapshot but not an atomic snapshot of the entire cache.
| size_t get_total_capacity | ( | cache_t * | cache_ptr | ) |
Returns the total capacity of the cache across all shards. Thread-safe: acquires read locks on all shards. Note: Capacity is set at creation and never changes, but we lock for consistency.
| cache | The cache instance. |
Returns the total capacity across all shards. Capacity is set at creation time and does not change, so locking here is defensive rather than strictly necessary.