use std::sync::Arc;
use crate::free_join::execute::TrieNode;
use crate::numeric_id::define_id;
use crate::offsets::OffsetRange;
use crate::Value;
use super::{AtomId, Variable};
define_id!(pub SubsetId, u32, "An offset into a buffer of subsets");
#[derive(Debug)]
pub(super) enum UpdateInstr {
PushBinding(Variable, Value),
RefineAtom(AtomId, Arc<TrieNode>),
RefineAtomDense(AtomId, OffsetRange),
EndFrame,
}
#[derive(Default)]
pub(super) struct FrameUpdates {
updates: Vec<UpdateInstr>,
frames: usize,
last_start: usize,
}
impl FrameUpdates {
pub(super) fn with_capacity(capacity: usize) -> FrameUpdates {
FrameUpdates {
updates: Vec::with_capacity(capacity * 2),
frames: 0,
last_start: 0,
}
}
pub(super) fn push_binding(&mut self, var: Variable, val: Value) {
self.updates.push(UpdateInstr::PushBinding(var, val));
}
pub(super) fn refine_atom(&mut self, atom: AtomId, node: Arc<TrieNode>) {
self.updates.push(UpdateInstr::RefineAtom(atom, node));
}
pub(super) fn refine_atom_dense(&mut self, atom: AtomId, range: OffsetRange) {
self.updates.push(UpdateInstr::RefineAtomDense(atom, range));
}
pub(super) fn rollback(&mut self) {
self.updates.truncate(self.last_start);
}
pub(super) fn finish_frame(&mut self) {
self.updates.push(UpdateInstr::EndFrame);
self.last_start = self.updates.len();
self.frames += 1;
}
pub(super) fn frames(&self) -> usize {
self.frames
}
pub(super) fn clear(&mut self) {
self.updates.clear();
}
pub(super) fn drain(&mut self, f: impl FnMut(UpdateInstr)) {
let start = 0;
self.updates.drain(start..).for_each(f);
self.frames = 0;
self.last_start = 0;
}
#[allow(dead_code)]
pub(super) fn updates(&self) -> &[UpdateInstr] {
&self.updates
}
}