https://github.com/pavel-kirienko/wild_key_value
Fast single-header key-value container in C with pattern matching and routing, suitable for embedded systems.
https://github.com/pavel-kirienko/wild_key_value
c c99 container embedded embedded-c key-value pattern-matching single-header wildcard
Last synced: 11 months ago
JSON representation
Fast single-header key-value container in C with pattern matching and routing, suitable for embedded systems.
- Host: GitHub
- URL: https://github.com/pavel-kirienko/wild_key_value
- Owner: pavel-kirienko
- License: mit
- Created: 2025-05-27T19:33:21.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-06-18T19:54:07.000Z (about 1 year ago)
- Last Synced: 2025-07-03T05:36:58.068Z (about 1 year ago)
- Topics: c, c99, container, embedded, embedded-c, key-value, pattern-matching, single-header, wildcard
- Language: C
- Homepage: https://opencyphal.org/
- Size: 320 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Wild Key-Value
[](https://github.com/pavel-kirienko/wild_key_value/actions/workflows/main.yml)
Fast and simple single-header key-value container with pattern matching for embedded systems.
Keys are strings, and values are void pointers.
Keys are stored in the heap in fragments; common prefixes are deduplicated so the memory usage is extremely low.
Patterns can be used to look up keys in the container, and also to look up patterns that match a given key;
the latter is called "routing".
## Usage
Copy `wkv.h` into your project and include it:
```c++
#define WKV_NO_ASSERT 1 ///< Speeds things up by removing runtime invariant checking.
#include
```
Define the realloc function. If you're using the standard heap, it would look as follows:
```c++
static void* my_realloc(wkv_t* const self, void* const ptr, const size_t new_size)
{
if (new_size > 0) { return realloc(ptr, new_size); }
free(ptr); // Handle freeing explicitly because invoking the standard realloc() with zero size is UB.
return NULL;
}
```
Embedded systems might prefer [O1Heap](https://github.com/pavel-kirienko/o1heap), which is only slightly different.
Basic operations -- init, get/set, delete, enumerate:
```c++
wkv_t kv;
wkv_init(&kv, my_realloc);
// Insert/update keys in logarithmic time using wkv_set().
wkv_node_t* node = wkv_set(&kv, wkv_key("foo/bar/baz"));
if (node != NULL) {
if (node->value == NULL) {
node->value = &my_value; // This is a new item, freshly created. We must assign a non-NULL value.
} else {
node->value = &my_value; // Such key already existed; we can reassign it here.
}
} else {
// Not enough memory.
}
// Access existing keys in logarithmic time using wkv_get().
node = wkv_get(&kv, wkv_key("foo/bar/baz"));
if (node != NULL) {
do_something(node->value); // The value of an existing key is never NULL.
} else {
// The key does not exist.
}
// Delete a key using wkv_del(). Passing NULL node is safe here.
wkv_del(&kv, node); // Using a specific node.
wkv_del(&kv, wkv_get(&kv, wkv_key("foo/bar/baz"))); // If the node needs to be found first (safe if not found).
// Index-based access. The ordering is unspecified and invalidated on insertion.
node = wkv_at(&kv, 123);
if (node != NULL) {
do_something(node->value);
} else {
// The index points past the last element.
}
// Get the key of a previosuly found node.
// WKV does not store full keys; instead, a key is reconstructed ad-hoc like so:
char key_buf[node->key_len + 1]; // you can replace the VLA with an application-specific capacity.
wkv_get_key(&kv, node, key_buf);
printf("Key: %s\n", key_buf);
```
WKV supports pattern matching and routing:
- Matching refers to finding keys in a container that match a given pattern. This is done via `wkv_match()`.
- Routing refers to finding patterns in a container that match a given key. This is done via `wkv_route()`.
## Development
Build and run tests using CMake.
Set CMake cache variable `COVERAGE=ON` to make a coverage build; then build the `lcov` target to generate the report.
To release a new version, simply tag it.