# ekv
Key-value database for embedded systems, for raw NOR flash, using an LSM-Tree.
## crates.io - Docs - Docs for git - Chat
## Features
- Keys and values are arbitrary-length byte arrays. The database is essentially an on-disk `Map, Vec>`.
- `O(log n)` reads. Amortized `O(log n)` writes. No linear scans!
- Power-fail safe. Powering off in the middle of writes never corrupts the database.
- Transaction support:
- Atomic writes: Start a write transaction, write multiple keys, commit. If power fails midway, either all or no writes are committed.
- Consistent reads: Read transactions see a consistent snapshot of the database, unaffected by concurrent writes.
- Unlimited read transactions and one write transaction are allowed concurrently.
- Read transactions are only blocked by a write transaction commit, not by the whole write transaction. Commit is fast, `O(1)`.
- Iterating reading keys with a cursor, either all or within a range. Multiple concurrent cursors are supported.
- Wear leveling: erase cycles are spread out evenly between all flash pages. Pages are allocated cyclically. At boot, a random seed is required to decide which is the first.
- Corruption-resistant: A corrupted or deliberately manipulated flash image cannot cause crashes, panics or infinite loops, only `Err(Corrupted)` errors.
- Optional CRC32 protection of headers and data on flash.
- Extensively tested, using unit tests and fuzzing.
- Tunable chunk size. Smaller chunks reduce RAM requirements at the expense of doing more and smaller writes and spending a bit more flash space in chunk headers with CRCs.
## Current status
The project is in **production ready** stage. The author is using it in production, it is fully functional and has no known bugs. This does not mean it's feature-complete, see the limitations below.
The on-disk format is **not stable** yet.
- Major releases can do fully breaking changes to the on-disk format. New code won't be able to read old databases and vice-versa. No code to upgrade in-place will be provided. You'll have to either format and lose all data, or read out the data and write it back in the newer format.
- Minor releases can do backwards-compatible changes: they'll always be able to read databases written by older versions, but they might write databases using new features that older versions can't read.
- Patch releases will maintain full backwards and forwards on-disk compatibility.
## Future work
- Optimize tiny write transactions: append to the last file if possible, instead of starting a new one. Currently each write transaction opens a new file, which will have to erase at least one full page, even if the transaction writes just one small key. It is recommended to batch multiple writes in a single transaction for performance.
- Support access align higher than 4. Currently reads/writes are (optionally) aligned up to 4 bytes. Some flash out there can only be written in 8-byte words or higher.
- Allow writes within a transaction to be unsorted.
- Allow reads within a write transaction. They should see the the not yet committed writes in the current transaction.
- Add optional encryption + authentication support (which disables CRCs)
- Integrate with `embedded-storage`.
## Alternatives
`ekv` works best for datasets with large amounts of keys (>1000), where its `O(log n)` complexity outperforms linear search. For datasets with less keys, other key-value databases based on linear search (such as `sequential-storage`) will be faster.
- If the dataset fits in RAM, you could read/write it all at once. Either making it `repr(C)` and transmuting, or serializing it with some compact `serde` flavor such as [`postcard`](https://docs.rs/postcard)
- [sequential-storage](https://docs.rs/sequential-storage) - Rust. Linear search. No multi-key transactions. Multiple single-key transactions can be written to the same page, unlike `ekv`.
- [Tock's tickv](https://docs.rs/tickv) - Rust. Hash table. No multi-key transactions.
- [pigweed's pw_kvs](https://pigweed.dev/pw_kvs/) - C. Linear search. No multi-key transactions. Multiple single-key transactions can be written to the same page, unlike `ekv`.
## Why the name?
Embedded Key-Value! :)
## License
This work is licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or )
at your option.