Skip to content

Lisprez/yakvdb

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yet Another Kev-Value DataBase

Extremely simple (simplest possible?) single-file BTree-based key-value database.

Build for fun and learning: goal is to "demystify" the "database".

Operations amortized runtime complexity:

  • insert/remove: O(log(N) * log(K) + K)
  • lookup/min/max/above/below: O(log(N) * log(K))

Where:

  • N - number of entries in a tree
  • K - number of entries in a page

Binary search is run for each page (log(K)) and touches at most log(N) pages.

On insert/remove each page performs O(K) cleanup to keep keys ordered, as well as extra housekeeping is performed if necessary (split or merge of pages).

Each insert/remove gets flushed to the disk for durability.

API

Demo

Just cargo run --release to run example in from main.rs:

  • create/open database (file)
  • generate random key-value pairs
  • insert all key-value pairs
  • lookup all keys and check values match
  • iterate all keys in ascending order
  • iterate all keys in descending order
  • remove all keys and check database is empty
$ cargo run --release
[...][INFO] file="target/main_1M.tmp" count=1000000 page=4096
[...][INFO] insert: 27520 ms (rate=36337 op/s)
[...][INFO] lookup: 921 ms (rate=1085776 op/s)
[...][INFO] iter: min=000003cf1bb4e04d max=ffffe6e240320123
[...][INFO] iter:  asc 489 ms (rate=2044989 op/s) n=1000000
[...][INFO] iter: desc 465 ms (rate=2150537 op/s) n=1000000
[...][INFO] remove: 25819 ms (rate=38731 op/s)

Code

use std::cell::Ref;
use crate::api::error::Result;
use crate::disk::block::Block;
use crate::disk::file::File;

// Create new database with given page_size
let mut db: File<Block> = File::make(path, /*page_size=*/4096).unwrap();
// Or open a database from an existing file
let mut db: File<Block> = File::open(path).unwrap();

let r: Result<Optional<Ref<u8>>> = db.lookup(&b"key");
let _: Result<()> = db.insert(&b"key", &b"val");
let _: Result<()> = db.remove(&b"key");

// To iterate: db.min(), db.max(), db.above(&[u8]), db.below(&[u8])

About

Yet Another Kev-Value DataBase

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Rust 100.0%