use dbutils::checksum::{BuildChecksumer, Crc32};
use rarena_allocator::Allocator;
use crate::{error::Error, sealed::Constructor, Mutable};
use super::*;
pub struct Builder<S = Crc32> {
pub(super) opts: Options,
pub(super) cks: S,
}
impl Default for Builder {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl Builder {
#[inline]
pub fn new() -> Self {
Self {
opts: Options::new(),
cks: Crc32::new(),
}
}
}
impl<S> Builder<S> {
#[inline]
pub fn with_checksumer<NS>(self, cks: NS) -> Builder<NS> {
Builder {
cks,
opts: self.opts,
}
}
#[inline]
pub const fn with_options(mut self, opts: Options) -> Self {
self.opts = opts;
self
}
#[inline]
pub const fn with_reserved(mut self, reserved: u32) -> Self {
self.opts.reserved = reserved;
self
}
#[inline]
pub const fn with_sync(mut self, sync: bool) -> Self {
self.opts.sync = sync;
self
}
#[inline]
pub const fn with_lock_meta(mut self, lock_meta: bool) -> Self {
self.opts.lock_meta = lock_meta;
self
}
#[inline]
pub const fn with_magic_version(mut self, magic_version: u16) -> Self {
self.opts.magic_version = magic_version;
self
}
#[inline]
pub const fn with_freelist(mut self, freelist: Freelist) -> Self {
self.opts.freelist = freelist;
self
}
#[inline]
pub const fn with_unify(mut self, unify: bool) -> Self {
self.opts.unify = unify;
self
}
#[inline]
pub const fn with_maximum_value_size(mut self, size: u32) -> Self {
self.opts.max_value_size = size;
self
}
#[inline]
pub const fn with_capacity(mut self, capacity: u32) -> Self {
self.opts.capacity = Some(capacity);
self
}
#[inline]
pub const fn reserved(&self) -> u32 {
self.opts.reserved
}
#[inline]
pub const fn sync(&self) -> bool {
self.opts.sync
}
#[inline]
pub const fn lock_meta(&self) -> bool {
self.opts.lock_meta
}
#[inline]
pub const fn maximum_value_size(&self) -> u32 {
self.opts.max_value_size
}
#[inline]
pub const fn capacity(&self) -> u32 {
self.opts.capacity()
}
#[inline]
pub const fn unify(&self) -> bool {
self.opts.unify
}
#[inline]
pub const fn magic_version(&self) -> u16 {
self.opts.magic_version
}
#[inline]
pub const fn freelist(&self) -> Freelist {
self.opts.freelist
}
}
impl<S: BuildChecksumer> Builder<S> {
#[inline]
pub fn alloc<C>(self, fid: C::Id) -> Result<C, Error>
where
C: Constructor<Checksumer = S> + Mutable,
{
let Self { opts, cks } = self;
let unify = opts.unify;
let mv = opts.magic_version;
opts
.to_arena_options()
.alloc::<C::Allocator>()
.map_err(Error::from_insufficient_space)
.map(|arena| {
if unify {
unsafe {
let slice = arena.reserved_slice_mut();
write_header(slice, mv);
}
}
C::construct(fid, arena, cks, opts)
})
}
}