TurboKV is een asynchrone, embedded key-value store ontwikkeld voor de programmeertaal Rust. De database is ontworpen voor hoge prestaties en biedt diverse geavanceerde functionaliteiten:
- Data-operaties: Ondersteunt point-reads, bulk-inserts en atomaire
WriteBatch-operaties, waarbij sleutels en waarden als byte-sequenties worden behandeld.
- Duurzaamheidsmodi: Gebruikers kunnen kiezen uit drie presets:
fast (geen WAL), durable (standaard herstel na crash) en paranoid (maximale synchronisatie).
- Efficiënte scans: Biedt geordende range scans en prefix scans via streaming iteratoren voor optimale geheugengebruik.
- Configuratie en Optimalisatie: De database maakt gebruik van hardware AES voor Bloom-filters en biedt configureerbare opties voor memtable-grootte, block cache en compressie (LZ4, Snappy, Zstd).
- Benchmarks: In vergelijkingen met fjall en redb scoort TurboKV significant hoger op doorvoer, met name bij sequentiële vullingen en batch-operaties.
TurboKV: Een snelle, embedded key-value store voor Rust
Installatie
Voeg de volgende pakketten toe via cargo:
cargo add turbokv
cargo add tokio --features full
Of voeg de afhankelijkheden direct toe aan je Cargo.toml:
[dependencies]
turbokv = "0.6"
tokio = { version = "1", features = ["full"] }
Het persistente Bloom-filter-formaat van TurboKV maakt gebruik van hardware AES. Bouw x86/x86_64 targets met RUSTFLAGS="-C target-feature=+aes,+sse2" en ARM/AArch64 targets met RUSTFLAGS="-C target-feature=+aes,+neon". Alternatief kun je -C target-cpu=native gebruiken wanneer het binary alleen op hetzelfde CPU-model of een superset van functies zal draaien.
Snelstart
use turbokv::{Db, DbOptions, WriteBatch};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Db::open_with_options("./my-database", DbOptions::durable()).await?;
db.insert(b"user:1", b"Ada").await?;
assert_eq!(db.get(b"user:1").await?, Some(b"Ada".to_vec()));
let mut batch = WriteBatch::new();
batch.put(b"user:2", b"Grace");
batch.put(b"user:3", b"Linus");
batch.delete(b"user:1");
db.write_batch(&batch).await?;
for (key, value) in db.scan_prefix(b"user:").await? {
println!(
"{} = {}",
String::from_utf8_lossy(&key),
String::from_utf8_lossy(&value)
);
}
db.close().await?;
Ok(())
}
Beschikbare voorbeelden
De volgende runnable voorbeelden zijn beschikbaar:
- basic: invoegen, ophalen, bijwerken en verwijderen.
- batch_writes: atomaire puts en deletes.
- range_queries: geordende range scans en prefix scans.
- concurrent: gedeelde toegang vanuit Tokio-taken.
- persistence: herstel van de WAL (Write-Ahead Log) in 'paranoid' modus.
- configuration: opties voor cache, memtable en compressie.
API-overzicht
Duurzaamheidsinstellingen (Durability presets)
| Preset | Bevestigingsgrens (Acknowledgement boundary) | Gebruiksgeval |
DbOptions::fast() | Zichtbaarheid in het geheugen; geen WAL | Caches en reproduceerbare data |
DbOptions::durable() | Toegevoegd aan de WAL zonder per-schrijfactie sync | Herstel na procescrash; aanbevolen standaardinstelling |
DbOptions::paranoid() | WAL groep voltooit sync_all vóór terugkeer | Sterkste modus, afhankelijk van bestandssysteem/apparaat garanties |
Let op: Eén open Db of Engine bezit exclusief zijn datamap. Gebruik close() of closewithstatus() voor een nette afsluiting; het simpelweg laten vallen (dropping) van een handle wordt niet beschouwd als een nette afsluiting.
Database-operaties
Sleutels en waarden zijn willekeurige byte-sequenties die worden aangeleverd via AsRef<[u8]>; strings moeten door de aanroeper worden gecodeerd. Mutatie-API's kopiëren hun inputs voordat ze terugkeren. Point- en collecting-reads retourneren eigendomsrechten op Vec<u8> waarden. Een lege waarde is geldige data en is verschillend van een verwijderde sleutel.
Openen en configuratie
| API | Parameters | Resultaat en gedrag |
Db::open(path) | path: AsRef<Path> | Opent of maakt de directory aan met DbOptions::durable(). De open handle bezit exclusief de directory. |
Db::openwithoptions(path, options) | Database pad en een DbOptions waarde | Opent met expliciete instellingen voor duurzaamheid, geheugen, cache en compressie. Weigert tegenstrijdige instellingen (bijv. sync_writes = true terwijl de WAL is uitgeschakeld). |
DbOptions::fast() | Geen | Retourneert de preset zonder WAL. |
DbOptions::durable() | Geen | Retourneert de preset voor herstel na procescrash (WAL). |
DbOptions::paranoid() | Geen | Retourneert de preset voor synchronisatie vóór bevestiging. |
options.with_compression(compression) | Een Compression variant | Builder-stijl update die de gewijzigde opties retourneert. |
Alle presets starten standaard met een memtable van 64 MiB, een block cache van 64 MiB en LZ4-compressie. De volgende publieke velden kunnen worden aangepast vóór het openen:
Veld van DbOptions | Betekenis |
wal_enabled: bool | Voegt mutaties toe aan de WAL. Uitschakelen kan leiden tot dataverlies bij een procescrash tot de volgende succesvolle flush of afsluiting. |
sync_writes: bool | Wacht op een WAL sync-barrier vóór bevestiging van elke mutatiegroep. Vereist wal_enabled. |
memtable_size: usize | Benaderde drempelwaarde in bytes in het geheugen die een memtable-rotatie en achtergrond-flush triggert. |
blockcachesize: usize | Budget in bytes voor de gedecomprimeerde SSTable block-cache. Zet op 0 om de cache uit te schakelen. |
compression: Compression | SSTable-compressie voor nieuw geschreven data: Lz4, Snappy, Zstd, of None. Bestaande tabellen behouden hun eigen formaat. |
Point, bulk en batch operaties
| API | Parameters | Resultaat en semantiek |
insert(key, value) | Byte-achtige sleutel en waarde | Result<()>. Voegt de sleutel toe of vervangt deze. De gekozen duurzaamheidsgrens is bereikt vóór succes. |
insert_many(entries) | Iterator van (sleutel, waarde) paren | Result<()>. Kopieert de volledige iterator en past entries sequentieel toe; de laatste duplicate sleutel wint. Dit is een bulk-API, geen atomaire overgang. |
get(key) | Byte-achtige sleutel | Result<Option<Vec<u8>>>. Retourneert None voor ontbrekende of verwijderde sleutels en Some(Vec::new()) voor een opgeslagen lege waarde. |
remove(key) | Byte-achtige sleutel | Result<()>. Schrijft een tombstone; het verwijderen van een ontbrekende sleutel is toegestaan. |
contains_key(key) | Byte-achtige sleutel | Result<bool>. Geeft dezelfde status als get en veroorzaakt momenteel dezelfde waarde-allocatie. |
write_batch(batch) | &WriteBatch | Result<()>. Publiceert alle operaties atomair; lezers zien ofwel de staat vóór de batch, of de volledige batch. De laatste operatie voor een duplicate sleutel wint. |
Wanneer de WAL is ingeschakeld, moet één record of een volledige batch passen binnen de u32 payload-lengte van de WAL. Een mislukte of geannuleerde mutatie kan mogelijk al in de WAL zijn terechtgekomen; controleer de sleutel of open de database opnieuw voordat je een niet-idempotente operatie opnieuw probeert.
WriteBatch bezit kopieën van elke sleutel en waarde:
| API | Parameters | Effect |
WriteBatch::new() | Geen | Maakt een lege batch aan. |
WriteBatch::with_capacity(capacity) | Verwacht aantal operaties | Pre-alloceert slots voor operaties, maar niet de bytes voor sleutels of waarden. |
batch.put(key, value) | Byte-achtige sleutel en waarde | Voegt een 'owned' put-operatie toe. |
batch.delete(key) | Byte-achtige sleutel | Voegt een 'owned' delete-operatie toe. |
batch.ops() | Geen | Leent de geordende &[BatchOp] operatielijst. |
batch.len() / batch.is_empty() | Geen | Rapporteert het huidige aantal operaties. |
batch.clear() | Geen | Verwijdert alle operaties terwijl de allocatie behouden blijft voor hergebruik. |
Range en prefix scans
Sleutels zijn lexicografisch geordend op basis van ruwe bytes. Elke scan legt een coherent momentopname-beeld (point-in-time view) vast. Het maken van een scan kan een actieve memtable bevriezen, waardoor frequente kleine scans het latere flush-werk kunnen verhogen.
| API | Parameters | Resultaat en allocatie |
range(start, end) | Inclusieve start-sleutel en exclusieve eind-sleutel | Result<Vec<(Vec<u8>, Vec<u8>)>>; alloceert direct elke geretourneerde sleutel en waarde. |
scan_prefix(prefix) | Byte prefix; een lege prefix matcht alles | Collecteert direct alle matching key/value paren in volgorde. |
range_iter(start, end) | Dezelfde [start, end) grenzen | Maakt een RangeIter. Items zijn Result<EntryGuard, ScanError> omdat corruptie kan worden ontdekt tijdens het itereren. |
scanprefixiter(prefix) | Byte prefix | Maakt een PrefixIter, een alias van dezelfde streaming implementatie. |
Het voortbewegen van een streaming iterator is synchroon en kan mmap-reads, checksum-validatie, decompressie en cache-locking uitvoeren. Vernietig de iterator snel: de iterator pinst snapshot-readers en het eigendom van de database-directory.
Iterator of guard API
| API | Parameters | Resultaat |
iter.count() | Geen | Consumeert de iterator en retourneert Result<usize, ScanError>. |
iter.keys() | Geen | Consumeert de iterator en collecteert eigendomsrechten op sleutels zonder memtable waarden te materialiseren. |
iter.collect_pairs() | Geen | Consumeert de iterator en collecteert eigendomsrechten op key/value paren. |
iter.paginate(offset, limit) | Aantal entries om over te slaan en maximum entries | Retourneert een lazy iterator; overgeslagen entries worden getraverseerd, maar hun memtable waarden worden niet gekopieerd. |
guard.key() | Geen | Leent de sleutel zonder de waarde te laden. |
guard.value() / guard.value_len() | Geen | Leent de waarde, of rapporteert de lengte; een memtable-waarde wordt pas gekopieerd wanneer value() voor het eerst wordt aangevraagd. |
guard.intopair() / intokey() / into_value() | Geen | Consumeert de guard en retourneert de gevraagde eigendomsrechten op bytes. |
Persistentie, onderhoud en statistieken
| API | Parameters | Resultaat en kosten |
flush() | Geen | Result<()>. Leegt wachtende schrijfacties, installeert SSTables en het manifest, synchroniseert de WAL en reclaimt geschikte WAL-segmenten. |
compact() | Geen | Result<CompactionResult>. Leegt de vastgelegde compactie-scope en rapporteert bestanden, bytes, duur, gereclaimde tombstones en of er werk overblijft. |
status() | Geen | Goedkope DatabaseStatus snapshot van onderhoudsfouten, retries en schrijf-backpressure. |
logical_stats() | Geen | Exacte Result<LogicalStats> voor unieke live sleutels en bytes. Scant fysieke versies en kan I/O uitvoeren. |
physical_stats() | Geen | Goedkope PhysicalStats meters en process-lifetime counters voor de WAL, memtables, SSTables, cache, stalls en amplificatie. |
stats() | Geen | Verouderde gemengde fysieke counters, behouden voor compatibiliteit. |
close() | Consumeert Db | Flushed wachtende schrijfacties, stopt onderhoud en geeft eigendom vrij bij succes. |
closewithstatus() | Consumeert Db | Gestructureerde vorm van afsluiten; maakt onderscheid tussen storage-fouten en onopgeloste flush- of compactie-gezondheid. |
De meeste database-methoden retourneren DbError. Streaming iterator creatie retourneert DbError, terwijl fouten die later worden ontdekt worden yielded als ScanError. Voor geavanceerde API's, inclusief de Engine en component-configuraties, zie de crate-documentatie.
Benchmarks
De benchmark gebruikte TurboKV 0.6.0, fjall 2.11.2, en redb 2.6.3 over drie herhalingen. Doorvoer wordt gemeten in bevestigde sleutels per seconde; hoger is beter.
| Workload | TurboKV Fast | TurboKV Durable | TurboKV Paranoid | fjall Buffer | redb Eventual |
| Sequential fill (1 key/txn) | 2,989,537 | 1,774,574 | 213 | 485,252 | 1,397* |
| Random fill (1 key/txn) | 1,217,087 | 906,806 | 226 | 456,924 | 1,549* |
| Overwrite (1 key/txn) | 1,278,894 | 929,340 | 210 | 446,733 | 1,516* |
| Sequential batch (100 keys/txn) | 3,856,202 | 2,277,031 | 20,670 | 511,600 | 80,197 |
| Sequential batch (1,000 keys/txn) | 3,724,635 | 2,380,390 | 162,938 | 572,671 | 134,636 |
\ macOS barrier/txn*
Toelichting bij modi:
- Fast: Schakelt de WAL uit.
- Durable: Schrijft een herstelbare WAL-record zonder elke bevestiging naar persistente opslag te synchroniseren.
- Paranoid: Voert die synchronisatie uit vóór terugkeer; de doorvoer voor enkele sleutels wordt hierdoor beperkt door de latentie van de opslag-sync, terwijl expliciete batches één barrier over vele sleutels verspreiden.
Protocol en Hardware:
- 200.000 deterministische 20-byte sleutels, 400-byte waarden (84 MB logische input, boven de 64 MiB memtable).
- Eén aanroeper, atomaire batches waar aangegeven, compressie en block cache uitgeschakeld, en een niet-geleegde OS page cache.
redb 2.6.3's Durability::Eventual voert een macOS F_BARRIERFSYNC uit voor elke transactie, terwijl de TurboKV Recoverable en fjall Buffer modi stoppen bij hun procescrash-herstelbare OS-cache grenzen. Batching amortiseert die vaste redb-barrier.
- Gemeten tussen 28 en 29 augustus 2026 op een Apple M4 (Mac16,1), 32 GiB RAM, macOS 15.3.2 (24D81), APFS, en rustc 1.88.0.
TurboKV: Een snelle, embedded key-value store voor Rust
Installatie
Voeg de volgende pakketten toe via cargo:
cargo add turbokv
cargo add tokio --features full
Of voeg de afhankelijkheden direct toe aan je Cargo.toml:
[dependencies]
turbokv = "0.6"
tokio = { version = "1", features = ["full"] }
Het persistente Bloom-filter-formaat van TurboKV maakt gebruik van hardware AES. Bouw x86/x86_64 targets met RUSTFLAGS="-C target-feature=+aes,+sse2" en ARM/AArch64 targets met RUSTFLAGS="-C target-feature=+aes,+neon". Alternatief kun je -C target-cpu=native gebruiken wanneer het binary alleen op hetzelfde CPU-model of een superset van functies zal draaien.
Snelstart
use turbokv::{Db, DbOptions, WriteBatch};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let db = Db::open_with_options("./my-database", DbOptions::durable()).await?;
db.insert(b"user:1", b"Ada").await?;
assert_eq!(db.get(b"user:1").await?, Some(b"Ada".to_vec()));
let mut batch = WriteBatch::new();
batch.put(b"user:2", b"Grace");
batch.put(b"user:3", b"Linus");
batch.delete(b"user:1");
db.write_batch(&batch).await?;
for (key, value) in db.scan_prefix(b"user:").await? {
println!(
"{} = {}",
String::from_utf8_lossy(&key),
String::from_utf8_lossy(&value)
);
}
db.close().await?;
Ok(())
}
Beschikbare voorbeelden
De volgende runnable voorbeelden zijn beschikbaar:
- basic: invoegen, ophalen, bijwerken en verwijderen.
- batch_writes: atomaire puts en deletes.
- range_queries: geordende range scans en prefix scans.
- concurrent: gedeelde toegang vanuit Tokio-taken.
- persistence: herstel van de WAL (Write-Ahead Log) in 'paranoid' modus.
- configuration: opties voor cache, memtable en compressie.
API-overzicht
Duurzaamheidsinstellingen (Durability presets)
| Preset | Bevestigingsgrens (Acknowledgement boundary) | Gebruiksgeval |
DbOptions::fast() | Zichtbaarheid in het geheugen; geen WAL | Caches en reproduceerbare data |
DbOptions::durable() | Toegevoegd aan de WAL zonder per-schrijfactie sync | Herstel na procescrash; aanbevolen standaardinstelling |
DbOptions::paranoid() | WAL groep voltooit sync_all vóór terugkeer | Sterkste modus, afhankelijk van bestandssysteem/apparaat garanties |
Let op: Eén open Db of Engine bezit exclusief zijn datamap. Gebruik close() of closewithstatus() voor een nette afsluiting; het simpelweg laten vallen (dropping) van een handle wordt niet beschouwd als een nette afsluiting.
Database-operaties
Sleutels en waarden zijn willekeurige byte-sequenties die worden aangeleverd via AsRef<[u8]>; strings moeten door de aanroeper worden gecodeerd. Mutatie-API's kopiëren hun inputs voordat ze terugkeren. Point- en collecting-reads retourneren eigendomsrechten op Vec<u8> waarden. Een lege waarde is geldige data en is verschillend van een verwijderde sleutel.
Openen en configuratie
| API | Parameters | Resultaat en gedrag |
Db::open(path) | path: AsRef<Path> | Opent of maakt de directory aan met DbOptions::durable(). De open handle bezit exclusief de directory. |
Db::openwithoptions(path, options) | Database pad en een DbOptions waarde | Opent met expliciete instellingen voor duurzaamheid, geheugen, cache en compressie. Weigert tegenstrijdige instellingen (bijv. sync_writes = true terwijl de WAL is uitgeschakeld). |
DbOptions::fast() | Geen | Retourneert de preset zonder WAL. |
DbOptions::durable() | Geen | Retourneert de preset voor herstel na procescrash (WAL). |
DbOptions::paranoid() | Geen | Retourneert de preset voor synchronisatie vóór bevestiging. |
options.with_compression(compression) | Een Compression variant | Builder-stijl update die de gewijzigde opties retourneert. |
Alle presets starten standaard met een memtable van 64 MiB, een block cache van 64 MiB en LZ4-compressie. De volgende publieke velden kunnen worden aangepast vóór het openen:
Veld van DbOptions | Betekenis |
wal_enabled: bool | Voegt mutaties toe aan de WAL. Uitschakelen kan leiden tot dataverlies bij een procescrash tot de volgende succesvolle flush of afsluiting. |
sync_writes: bool | Wacht op een WAL sync-barrier vóór bevestiging van elke mutatiegroep. Vereist wal_enabled. |
memtable_size: usize | Benaderde drempelwaarde in bytes in het geheugen die een memtable-rotatie en achtergrond-flush triggert. |
blockcachesize: usize | Budget in bytes voor de gedecomprimeerde SSTable block-cache. Zet op 0 om de cache uit te schakelen. |
compression: Compression | SSTable-compressie voor nieuw geschreven data: Lz4, Snappy, Zstd, of None. Bestaande tabellen behouden hun eigen formaat. |
Point, bulk en batch operaties
| API | Parameters | Resultaat en semantiek |
insert(key, value) | Byte-achtige sleutel en waarde | Result<()>. Voegt de sleutel toe of vervangt deze. De gekozen duurzaamheidsgrens is bereikt vóór succes. |
insert_many(entries) | Iterator van (sleutel, waarde) paren | Result<()>. Kopieert de volledige iterator en past entries sequentieel toe; de laatste duplicate sleutel wint. Dit is een bulk-API, geen atomaire overgang. |
get(key) | Byte-achtige sleutel | Result<Option<Vec<u8>>>. Retourneert None voor ontbrekende of verwijderde sleutels en Some(Vec::new()) voor een opgeslagen lege waarde. |
remove(key) | Byte-achtige sleutel | Result<()>. Schrijft een tombstone; het verwijderen van een ontbrekende sleutel is toegestaan. |
contains_key(key) | Byte-achtige sleutel | Result<bool>. Geeft dezelfde status als get en veroorzaakt momenteel dezelfde waarde-allocatie. |
write_batch(batch) | &WriteBatch | Result<()>. Publiceert alle operaties atomair; lezers zien ofwel de staat vóór de batch, of de volledige batch. De laatste operatie voor een duplicate sleutel wint. |
Wanneer de WAL is ingeschakeld, moet één record of een volledige batch passen binnen de u32 payload-lengte van de WAL. Een mislukte of geannuleerde mutatie kan mogelijk al in de WAL zijn terechtgekomen; controleer de sleutel of open de database opnieuw voordat je een niet-idempotente operatie opnieuw probeert.
WriteBatch bezit kopieën van elke sleutel en waarde:
| API | Parameters | Effect |
WriteBatch::new() | Geen | Maakt een lege batch aan. |
WriteBatch::with_capacity(capacity) | Verwacht aantal operaties | Pre-alloceert slots voor operaties, maar niet de bytes voor sleutels of waarden. |
batch.put(key, value) | Byte-achtige sleutel en waarde | Voegt een 'owned' put-operatie toe. |
batch.delete(key) | Byte-achtige sleutel | Voegt een 'owned' delete-operatie toe. |
batch.ops() | Geen | Leent de geordende &[BatchOp] operatielijst. |
batch.len() / batch.is_empty() | Geen | Rapporteert het huidige aantal operaties. |
batch.clear() | Geen | Verwijdert alle operaties terwijl de allocatie behouden blijft voor hergebruik. |
Range en prefix scans
Sleutels zijn lexicografisch geordend op basis van ruwe bytes. Elke scan legt een coherent momentopname-beeld (point-in-time view) vast. Het maken van een scan kan een actieve memtable bevriezen, waardoor frequente kleine scans het latere flush-werk kunnen verhogen.
| API | Parameters | Resultaat en allocatie |
range(start, end) | Inclusieve start-sleutel en exclusieve eind-sleutel | Result<Vec<(Vec<u8>, Vec<u8>)>>; alloceert direct elke geretourneerde sleutel en waarde. |
scan_prefix(prefix) | Byte prefix; een lege prefix matcht alles | Collecteert direct alle matching key/value paren in volgorde. |
range_iter(start, end) | Dezelfde [start, end) grenzen | Maakt een RangeIter. Items zijn Result<EntryGuard, ScanError> omdat corruptie kan worden ontdekt tijdens het itereren. |
scanprefixiter(prefix) | Byte prefix | Maakt een PrefixIter, een alias van dezelfde streaming implementatie. |
Het voortbewegen van een streaming iterator is synchroon en kan mmap-reads, checksum-validatie, decompressie en cache-locking uitvoeren. Vernietig de iterator snel: de iterator pinst snapshot-readers en het eigendom van de database-directory.
Iterator of guard API
| API | Parameters | Resultaat |
iter.count() | Geen | Consumeert de iterator en retourneert Result<usize, ScanError>. |
iter.keys() | Geen | Consumeert de iterator en collecteert eigendomsrechten op sleutels zonder memtable waarden te materialiseren. |
iter.collect_pairs() | Geen | Consumeert de iterator en collecteert eigendomsrechten op key/value paren. |
iter.paginate(offset, limit) | Aantal entries om over te slaan en maximum entries | Retourneert een lazy iterator; overgeslagen entries worden getraverseerd, maar hun memtable waarden worden niet gekopieerd. |
guard.key() | Geen | Leent de sleutel zonder de waarde te laden. |
guard.value() / guard.value_len() | Geen | Leent de waarde, of rapporteert de lengte; een memtable-waarde wordt pas gekopieerd wanneer value() voor het eerst wordt aangevraagd. |
guard.intopair() / intokey() / into_value() | Geen | Consumeert de guard en retourneert de gevraagde eigendomsrechten op bytes. |
Persistentie, onderhoud en statistieken
| API | Parameters | Resultaat en kosten |
flush() | Geen | Result<()>. Leegt wachtende schrijfacties, installeert SSTables en het manifest, synchroniseert de WAL en reclaimt geschikte WAL-segmenten. |
compact() | Geen | Result<CompactionResult>. Leegt de vastgelegde compactie-scope en rapporteert bestanden, bytes, duur, gereclaimde tombstones en of er werk overblijft. |
status() | Geen | Goedkope DatabaseStatus snapshot van onderhoudsfouten, retries en schrijf-backpressure. |
logical_stats() | Geen | Exacte Result<LogicalStats> voor unieke live sleutels en bytes. Scant fysieke versies en kan I/O uitvoeren. |
physical_stats() | Geen | Goedkope PhysicalStats meters en process-lifetime counters voor de WAL, memtables, SSTables, cache, stalls en amplificatie. |
stats() | Geen | Verouderde gemengde fysieke counters, behouden voor compatibiliteit. |
close() | Consumeert Db | Flushed wachtende schrijfacties, stopt onderhoud en geeft eigendom vrij bij succes. |
closewithstatus() | Consumeert Db | Gestructureerde vorm van afsluiten; maakt onderscheid tussen storage-fouten en onopgeloste flush- of compactie-gezondheid. |
De meeste database-methoden retourneren DbError. Streaming iterator creatie retourneert DbError, terwijl fouten die later worden ontdekt worden yielded als ScanError. Voor geavanceerde API's, inclusief de Engine en component-configuraties, zie de crate-documentatie.
Benchmarks
De benchmark gebruikte TurboKV 0.6.0, fjall 2.11.2, en redb 2.6.3 over drie herhalingen. Doorvoer wordt gemeten in bevestigde sleutels per seconde; hoger is beter.
| Workload | TurboKV Fast | TurboKV Durable | TurboKV Paranoid | fjall Buffer | redb Eventual |
| Sequential fill (1 key/txn) | 2,989,537 | 1,774,574 | 213 | 485,252 | 1,397* |
| Random fill (1 key/txn) | 1,217,087 | 906,806 | 226 | 456,924 | 1,549* |
| Overwrite (1 key/txn) | 1,278,894 | 929,340 | 210 | 446,733 | 1,516* |
| Sequential batch (100 keys/txn) | 3,856,202 | 2,277,031 | 20,670 | 511,600 | 80,197 |
| Sequential batch (1,000 keys/txn) | 3,724,635 | 2,380,390 | 162,938 | 572,671 | 134,636 |
\ macOS barrier/txn*
Toelichting bij modi:
- Fast: Schakelt de WAL uit.
- Durable: Schrijft een herstelbare WAL-record zonder elke bevestiging naar persistente opslag te synchroniseren.
- Paranoid: Voert die synchronisatie uit vóór terugkeer; de doorvoer voor enkele sleutels wordt hierdoor beperkt door de latentie van de opslag-sync, terwijl expliciete batches één barrier over vele sleutels verspreiden.
Protocol en Hardware:
- 200.000 deterministische 20-byte sleutels, 400-byte waarden (84 MB logische input, boven de 64 MiB memtable).
- Eén aanroeper, atomaire batches waar aangegeven, compressie en block cache uitgeschakeld, en een niet-geleegde OS page cache.
redb 2.6.3's Durability::Eventual voert een macOS F_BARRIERFSYNC uit voor elke transactie, terwijl de TurboKV Recoverable en fjall Buffer modi stoppen bij hun procescrash-herstelbare OS-cache grenzen. Batching amortiseert die vaste redb-barrier.
- Gemeten tussen 28 en 29 augustus 2026 op een Apple M4 (Mac16,1), 32 GiB RAM, macOS 15.3.2 (24D81), APFS, en rustc 1.88.0.