bbolt-rs 1.3.10

A Rust port of the Bolt database
Documentation
use crate::common::page::meta::{MappedMetaPage, MetaPage};
use crate::common::page::{CoerciblePage, MutPage};
use crate::common::SplitRef;
use crate::iter::{DbWalker, ValueBucketSeq};
use crate::tx::{TxCell, TxIApi};
use crate::{Bolt, BucketRwApi, DbApi, DbPath, PgId, TxRwApi, TxRwRefApi};
use aligners::{alignment, AlignedBytes};
use std::fs::OpenOptions;
use std::ops::Deref;
use std::path::Path;

#[cfg(test)]
fn copy<P: AsRef<Path>>(cell: TxCell, path: P) {
  let mut f = OpenOptions::new()
    .write(true)
    .truncate(true)
    .open(path)
    .unwrap();
  let page_size = cell.page_size();
  let meta = *cell.meta();
  let db_path = cell.split_r().db;
  let mut bytes = AlignedBytes::<alignment::Page>::new_zeroed(page_size);
  {
    let mut page = MutPage::new(bytes.as_mut_ptr());
    let meta_page = MappedMetaPage::mut_into(&mut page);
    meta_page.page.set_meta();
    meta_page.meta = meta;

    meta_page.page.id = PgId(0);
    let checksum = meta_page.meta.checksum();
    meta_page.meta.set_checksum(checksum);
  }
  {
    let mut page = MutPage::new(bytes.as_mut_ptr());
    let meta_page = MappedMetaPage::coerce_mut(&mut page).unwrap();

    meta_page.page.id = PgId(1);
    let txid = meta_page.meta.txid();
    meta_page.meta.set_txid(txid - 1);
    let checksum = meta_page.meta.checksum();
    meta_page.meta.set_checksum(checksum);
  }
}

pub fn compact(src: &Bolt, dst: &mut Bolt, tx_max_size: u64) -> crate::Result<()> {
  if dst.path() != &DbPath::Memory {
    assert_ne!(src.path(), dst.path());
  }
  let mut size = 0u64;
  let mut dst_tx = dst.begin_rw_tx()?;

  let src_tx = src.begin_tx()?;
  let mut walker = DbWalker::new(src_tx.tx.api_cursor());
  while let Some((k, v)) = walker.next() {
    let sz = (k.len() + v.len()) as u64;
    if size + sz > tx_max_size && tx_max_size != 0 {
      dst_tx.commit()?;
      dst_tx = dst.begin_rw_tx()?;
      size = 0;
    }
    size += sz;
    let path = walker.path();
    let mut b = dst_tx.bucket_mut_path(path).unwrap();
    b.set_fill_percent(1.0);
    match v {
      ValueBucketSeq::Value(v) => {
        b.put(k, v)?;
      }
      ValueBucketSeq::BucketSeq(seq) => {
        let mut b = b.create_bucket(k)?;
        b.set_sequence(seq)?;
      }
    }
  }
  Ok(())
}