use super::*;
use std::mem::{align_of, size_of};
use std::ptr::NonNull;
#[derive(Default)]
pub(super) struct MapMemory {
admitted_nodes: usize,
}
impl MapMemory {
pub(super) fn node_bytes() -> usize {
let alignment = align_of::<String>()
.max(align_of::<Value>())
.max(align_of::<NonNull<u8>>())
.max(align_of::<u16>());
size_of::<Option<NonNull<u8>>>()
+ 2 * size_of::<u16>()
+ 11 * (size_of::<String>() + size_of::<Value>())
+ 12 * size_of::<NonNull<u8>>()
+ 8 * (alignment - 1)
}
pub(super) fn before_insert(&mut self, len: usize, work: &DecodeContext) -> Result<()> {
let keys = len
.checked_add(1)
.ok_or_else(|| allocation("WAL map cardinality overflows usize", usize::MAX, work))?;
let nodes = keys / 4 + 2;
if nodes > self.admitted_nodes {
let bytes = (nodes - self.admitted_nodes)
.checked_mul(Self::node_bytes())
.ok_or_else(|| {
allocation("WAL map node capacity overflows usize", usize::MAX, work)
})?;
let _token = work.reserve(bytes)?;
self.admitted_nodes = nodes;
}
Ok(())
}
}