db185 0.3.0

Support for Berkeley DB 1.85
Documentation

Rust support for Berkeley DB 1.85

Crates.io Documentation License

db185 reads and writes Berkeley DB 1.85 btree files - the on-disk format used by 4.4BSD's dbopen(3) and still shipped today in NetBSD libc and pkgsrc's libnbcompat. It exists primarily for pkgsrc-rs to read and update pkgsrc's pkgdb.byfile.db.

What's supported:

  • Reader: any Berkeley DB 1.85 btree file, in either byte order.
  • Writer: builds a new file from scratch. Each key/value pair must fit in a single page (~4 KiB). That's enough for pkgsrc and similar workloads where keys are file paths and values are small identifiers; it is not a full Berkeley DB 1.85 writer.

Hash and recno access methods are out of scope.

use db185::Db;

let db = Db::open("/var/db/pkg/pkgdb.byfile.db")?;

if let Some(value) = db.get(b"/opt/pkg/bin/foo\0")? {
    println!("{}", String::from_utf8_lossy(value.as_ref()));
}

for entry in &db {
    let entry = entry?;
    println!(
        "{} -> {}",
        String::from_utf8_lossy(entry.key()),
        String::from_utf8_lossy(entry.value()),
    );
}

Performance

Numbers from a desktop Apple Silicon machine with a ~190k-entry pkgdb.byfile.db, measured with hyperfine via tools/bench.sh:

workload C (pkg_install / libnbcompat) Rust (db185) speedup
Full dump (read + iterate) ~34 ms ~14 ms 2.47x
Replay rebuild trace (writer) ~164 ms ~78 ms 2.11x
End-to-end pkg_admin rebuild ~514 ms ~558 ms 0.92x

The end-to-end rebuild row is slower in Rust because of overhead in pkgsrc-rs's filesystem walk and +CONTENTS parsing, not in db185 itself. This will be fixed in due course.