use super::*;
use crate::append_table::checkpoint::memory::allocate_capacity;
use crate::background::{CheckpointAllocationOwner, CheckpointValues, CheckpointWorkError};
use crate::relational::overflow::CheckpointRelationalOverflow;
use std::borrow::Cow;
#[derive(Debug)]
pub(super) struct CheckpointExternalizedRow<'a> {
pub(super) row: Cow<'a, RelationalRow>,
pub(super) _allocations: CheckpointAllocationOwner,
}
impl std::ops::Deref for CheckpointExternalizedRow<'_> {
type Target = RelationalRow;
fn deref(&self) -> &Self::Target {
&self.row
}
}
pub(super) fn row_values(
count: usize,
allocations: &mut CheckpointAllocationOwner,
work: &CheckpointWorkContext,
) -> Result<Vec<RelationalValue>, AppendTableError> {
let bytes = count
.checked_mul(std::mem::size_of::<RelationalValue>())
.and_then(|bytes| bytes.checked_add(std::mem::size_of::<Vec<RelationalValue>>()))
.and_then(|bytes| {
bytes.checked_add(2 * std::mem::size_of::<std::sync::atomic::AtomicUsize>())
})
.ok_or_else(|| {
work_error(work.record_failure(CheckpointWorkError::Allocation {
bytes: u64::MAX,
reason: "externalized row capacity overflows usize".into(),
}))
})?;
let unit = work.start_unit().map_err(work_error)?;
allocations.reserve(bytes, work).map_err(work_error)?;
let values = allocate_capacity(count, work)?;
unit.finish();
work.checkpoint().map_err(work_error)?;
Ok(values)
}
#[derive(Debug, Default)]
pub(super) struct CheckpointExternalizedOverflows {
values: Option<CheckpointValues<CheckpointRelationalOverflow>>,
}
impl std::ops::Deref for CheckpointExternalizedOverflows {
type Target = [CheckpointRelationalOverflow];
fn deref(&self) -> &Self::Target {
self.values.as_ref().map_or(&[], CheckpointValues::as_slice)
}
}
impl CheckpointExternalizedOverflows {
pub(super) fn new(
count: usize,
work: &CheckpointWorkContext,
) -> Result<Self, AppendTableError> {
Ok(Self {
values: Some(CheckpointValues::new(count, work).map_err(work_error)?),
})
}
pub(super) fn push(
&mut self,
value: CheckpointRelationalOverflow,
work: &CheckpointWorkContext,
) -> Result<(), AppendTableError> {
self.values
.as_mut()
.expect("externalized overflow capacity was admitted")
.push(value, work)
.map_err(work_error)
}
}