# bion-kv đŸ—ƒïž Magasin clĂ©-valeur durable, **std-only, zĂ©ro dĂ©pendance**, style [Bitcask](https://riak.com/assets/bitcask-intro.pdf) : un log append-only sur disque + un index en mĂ©moire + une compaction atomique. La brique *build-your-own-database* du xerboxion — construite une fois, plus jamais rebĂątie, seulement optimisĂ©e (principe RS-7). ## Quoi - `Kv::open(dir)` — ouvre/crĂ©e le magasin, reconstruit l'index en scannant le log - `put(k, v)` — un append sĂ©quentiel, O(1) - `get(k) -> Option>` — un lookup mĂ©moire + au plus un seek/read - `delete(k)` — appose un **tombstone** (on n'efface jamais le passĂ©) - `compact()` — réécrit uniquement les donnĂ©es vivantes, bascule **atomique par `rename`** - `sync()` — fsync explicite quand on veut la garantie coupure-de-courant - CRC32 (IEEE) **implĂ©mentĂ© maison** (`bion_kv::crc32`, table `const` calculĂ©e Ă  la compilation) ## Pourquoi Bitcask 1. **Rapide en Ă©criture** : tout est un append sĂ©quentiel — le motif d'E/S le plus rapide sur disque comme sur SSD. Pas d'arbre Ă  rééquilibrer, pas de page Ă  réécrire. 2. **Robuste** : le passĂ© est immuable ; un crash ne peut abĂźmer que la *queue* du log. À la rĂ©ouverture, chaque record est vĂ©rifiĂ© par CRC32 et la queue malade est tronquĂ©e — les donnĂ©es saines survivent toujours. 3. **Simple** : le format tient en une ligne (`crc32 | klen | vlen | clĂ© | valeur`, tombstone = `vlen == 0xFFFFFFFF`), la rĂ©cupĂ©ration = relire le log. Tout le moteur tient dans un fichier source lisible en une soirĂ©e : c'est aussi un cours. Le compromis assumĂ© : la RAM porte l'index (proportionnel au **nombre de clĂ©s**, pas au volume des valeurs), et le log grossit avec les versions mortes — d'oĂč `compact()`. ## Lien avec le boxion store Le boxion store (`jOSBoxion`) expose dĂ©jĂ  un KV par-utilisateur aux ploxions. `bion-kv` en est le moteur cĂŽtĂ© **core Rust** : mĂȘme contrat (put/get/delete durable et rĂ©ouvrable), mais embarquable partout — dans `xerboxion-rt`, dans l'OS bare-metal, dans un bion WASM. On ne rĂ©invente pas le KV Ă  chaque Ă©tage : on branche ce bloc. ## Exemple ```rust let mut kv = bion_kv::Kv::open("/tmp/mon-magasin")?; kv.put(b"xer", b"renderer")?; assert_eq!(kv.get(b"xer")?.as_deref(), Some(&b"renderer"[..])); kv.delete(b"xer")?; // tombstone dans le log assert_eq!(kv.get(b"xer")?, None); kv.compact()?; // le log ne garde que le vivant # Ok::<(), std::io::Error>(()) ``` ## Build-your-own-x MĂȘme famille que ces guides du dĂ©pĂŽt [codecrafters-io/build-your-own-x](https://github.com/codecrafters-io/build-your-own-x) (section *Build your own Database*) : - *Build Your Own Fast, Persistent KV Store in Rust* — exactement ce crate - l'article fondateur : **Bitcask — A Log-Structured Hash Table for Fast Key/Value Data** (Riak) - cousins de design : les WAL de SQLite/Postgres, les SSTables de LevelDB/RocksDB (Bitcask = le cas dĂ©gĂ©nĂ©rĂ© Ă  un seul niveau) ## Comment l'optimiser (l'invitation au fork) L'API est **stable pour toujours** ; tout ce qui suit se fait dessous, sans casser un seul appelant : - **Fichiers multiples + hint files** (le vrai Bitcask) : fermer le segment actif Ă  N Mo, compacter segment par segment, et Ă©crire un *hint file* (clĂ© → offset) pour rouvrir sans relire les valeurs. - **Compaction incrĂ©mentale** : aujourd'hui `compact()` copie tout le vivant d'un coup ; en segments, on ne compacte que les segments les plus « morts ». - **Batching/`put_many`** : grouper plusieurs records dans un seul `write_all` + un seul fsync. - **CRC matĂ©riel** : remplacer la table par l'instruction `crc32c` (SSE4.2) ou du SIMD — le format ne change pas si on garde le polynĂŽme IEEE. - **Index plus dense** : `HashMap, _>` → arĂšne de clĂ©s + table Ă  adressage ouvert, ou un ART pour les scans par prĂ©fixe. - **`get` sans `&mut`** : `pread`/`read_at` (FileExt) pour des lectures concurrentes sans dĂ©placer le curseur. ## Tests `cargo test -p bion-kv` — 17 tests unitaires + 2 doc-tests : put/get/delete, Ă©crasements, clĂ©s/valeurs binaires et vides, persistance aprĂšs rĂ©ouverture, tombstones rejouĂ©s, compaction (taille rĂ©duite, donnĂ©es intactes, rĂ©ouverture), queue corrompue (bruit, record tronquĂ©, bit-flip dĂ©tectĂ© par CRC), fichier Ă©tranger refusĂ©, brouillon de compaction orphelin ignorĂ©, 500 clĂ©s.