Registry¶
Header: libxs_reg.h
Thread-safe key-value store backed by a hash table with per-thread caching.
Configuration Macros¶
| Macro | Default | Description |
|---|---|---|
LIBXS_REGKEY_MAXSIZE |
64 | Maximum key size in bytes |
LIBXS_REGISTRY_NBUCKETS |
64 | Initial hash-table buckets (power of two); registries grow dynamically |
LIBXS_REGCACHE_NENTRIES |
16 | Thread-local cache entries per thread (power of two; 0 disables caching) |
Types¶
Lifetime¶
Create a new registry. Returns NULL in case of an error.
Destroy a registry and release all entries.
Return a pointer to the registry's internal lock. The returned lock can be passed as the lock argument to other registry functions (e.g., to hold the lock across multiple operations).
Iteration¶
void* libxs_registry_begin(libxs_registry_t* registry,
const void** key, size_t* cursor);
void* libxs_registry_next(libxs_registry_t* registry,
const void** key, size_t* cursor);
Enumerate entries. Initialize *cursor to 0 before the first begin call. Each call returns the value pointer and writes the key pointer to *key, or returns NULL when iteration is complete.
Access¶
void* libxs_registry_set(libxs_registry_t* registry,
const void* key, size_t key_size,
const void* value_init, size_t value_size,
libxs_lock_t* lock /* = NULL */);
Insert or update a key-value pair. The key must be binary-reproducible (zero-initialize padding). value_init may be NULL to defer initialization. Re-registering an existing key reallocates if the new value is larger. When lock is NULL the registry's internal lock is used. Returns a pointer to the stored value.
void* libxs_registry_get(const libxs_registry_t* registry,
const void* key, size_t key_size,
libxs_lock_t* lock /* = NULL */);
Look up a value by key. Returns NULL if not found.
int libxs_registry_get_copy(const libxs_registry_t* registry,
const void* key, size_t key_size,
void* value_out, size_t value_size,
libxs_lock_t* lock /* = NULL */);
Thread-safe query: copies up to value_size bytes of the stored value into value_out under the lock. Unlike libxs_registry_get, the caller never receives a raw pointer into the registry's internal storage, making this safe under concurrent modifications. Returns non-zero if the key was found, zero otherwise.
int libxs_registry_has(libxs_registry_t* registry,
const void* key, size_t key_size,
libxs_lock_t* lock /* = NULL */);
Check whether a key exists. Non-zero if found.
size_t libxs_registry_value_size(libxs_registry_t* registry,
const void* key, size_t key_size,
libxs_lock_t* lock /* = NULL */);
Query the stored value size in bytes. Returns 0 if not found.
void libxs_registry_remove(libxs_registry_t* registry,
const void* key, size_t key_size,
libxs_lock_t* lock /* = NULL */);
Remove a key-value pair and release its memory.
int libxs_registry_extract(libxs_registry_t* registry,
const void* key, size_t key_size,
void* value_out, size_t value_size,
libxs_lock_t* lock /* = NULL */);
Atomically retrieve and remove a key-value pair. Copies up to value_size bytes of the stored value into value_out (may be NULL to discard the value), then removes the entry and releases its memory. The lookup, copy, and removal are performed under a single lock hold, eliminating the race that exists when calling libxs_registry_get followed by libxs_registry_remove separately. Returns non-zero if the key was found, zero otherwise.
Status¶
Query registry capacity, number of entries, and total bytes stored.