extern crate alloc;
use alloc::vec::Vec;
use core::num::NonZeroU64;
use super::{Dot, Extraction, FRAG_CAP, Fragment, NIL, Node, NodeKind, OrderThread};
impl OrderThread {
pub(in crate::metis::rhapsody) fn set_visible(&mut self, dot: Dot, visible: bool) -> bool {
let Some((leaf, frag_position, offset)) = self.locate(dot) else {
return false;
};
let NodeKind::Leaf(frags) = &mut self.nodes[leaf as usize].kind else {
unreachable!("locate returns leaves only");
};
let bit = 1u64 << offset;
if visible {
frags[frag_position].visible |= bit;
} else {
frags[frag_position].visible &= !bit;
}
self.refresh_to_root(leaf);
true
}
pub(in crate::metis::rhapsody) fn set_visible_run(
&mut self,
station: u32,
first: NonZeroU64,
len: u32,
visible: bool,
) {
if len == 0 {
return;
}
let last = first.get().saturating_add(u64::from(len) - 1);
let mut cursor = first;
loop {
let covered = match self.locate(Dot::new(station, cursor)) {
Some((leaf, frag_position, offset)) => {
let NodeKind::Leaf(frags) = &mut self.nodes[leaf as usize].kind else {
unreachable!("locate returns leaves only");
};
let frag = &mut frags[frag_position];
let span_end = frag.base.get() + u64::from(frag.len) - 1;
let covered = span_end.min(last) - cursor.get() + 1;
let width = u32::try_from(covered).expect("a fragment spans at most 64 dots");
let mask = if width == 64 {
u64::MAX
} else {
((1u64 << width) - 1) << offset
};
if visible {
frag.visible |= mask;
} else {
frag.visible &= !mask;
}
self.refresh_to_root(leaf);
covered
}
None => 1,
};
match cursor.checked_add(covered) {
Some(next) if next.get() <= last => cursor = next,
_ => return,
}
}
}
pub(in crate::metis::rhapsody) fn insert_slot(
&mut self,
position: usize,
dot: Dot,
visible: bool,
) {
debug_assert!(position <= self.slot_len());
if self.root == NIL {
let leaf = self.alloc(Node {
parent: NIL,
slots: 1,
visible: usize::from(visible),
kind: NodeKind::Leaf(alloc::vec![Fragment::single(dot, visible)]),
});
self.root = leaf;
let _ = self.index.insert(dot, leaf);
return;
}
let (leaf, mut within) = self.leaf_at_slot(position);
let NodeKind::Leaf(frags) = &mut self.nodes[leaf as usize].kind else {
unreachable!("slot descent returns leaves only");
};
let mut frag_position = 0;
while frag_position < frags.len() && within > frags[frag_position].slots() {
within -= frags[frag_position].slots();
frag_position += 1;
}
if frag_position < frags.len() && within == frags[frag_position].slots() {
let frag = &mut frags[frag_position];
if frag.station == dot.station()
&& frag.base.checked_add(u64::from(frag.len)) == Some(dot.counter_nonzero())
&& frag.slots() < FRAG_CAP
{
if visible {
frag.visible |= 1u64 << frag.len;
}
frag.len += 1;
self.refresh_to_root(leaf);
return;
}
frag_position += 1;
within = 0;
}
let fresh = Fragment::single(dot, visible);
if within == 0 || frag_position >= frags.len() {
frags.insert(frag_position.min(frags.len()), fresh);
} else {
let head = frags[frag_position];
let cut = u8::try_from(within).expect("fragment offsets fit u8");
let tail = Fragment {
station: head.station,
base: head.base.saturating_add(u64::from(cut)),
len: head.len - cut,
visible: head.visible >> cut,
};
frags[frag_position] = Fragment {
visible: head.visible & ((1u64 << cut) - 1),
len: cut,
..head
};
frags.insert(frag_position + 1, fresh);
frags.insert(frag_position + 2, tail);
let _ = self.index.insert(tail.base_dot(), leaf);
}
let _ = self.index.insert(dot, leaf);
self.split_leaf_if_over(leaf);
self.refresh_to_root(leaf);
}
pub(in crate::metis::rhapsody) fn insert_run(
&mut self,
position: usize,
station: u32,
first: NonZeroU64,
len: u32,
visible: bool,
) {
if len == 0 {
return;
}
let mut frags: Vec<Fragment> = Vec::with_capacity((len as usize).div_ceil(FRAG_CAP));
let mut base = first;
let mut remaining = len as usize;
while remaining > 0 {
let take = remaining.min(FRAG_CAP);
let mask = if !visible {
0
} else if take == FRAG_CAP {
u64::MAX
} else {
(1u64 << take) - 1
};
frags.push(Fragment {
station,
base,
len: u8::try_from(take).expect("a fragment holds at most FRAG_CAP slots"),
visible: mask,
});
remaining -= take;
if remaining > 0 {
base = base.saturating_add(take as u64);
}
}
self.insert_fragments(position, Extraction { frags });
}
pub(in crate::metis::rhapsody) fn remove_slot(&mut self, dot: Dot) -> bool {
let Some((leaf, frag_position, offset)) = self.locate(dot) else {
return false;
};
let NodeKind::Leaf(frags) = &mut self.nodes[leaf as usize].kind else {
unreachable!("locate returns leaves only");
};
let frag = frags[frag_position];
let _ = self.index.remove(&frag.base_dot());
if frag.len == 1 {
let _ = frags.remove(frag_position);
if frags.is_empty() {
self.detach_empty(leaf);
} else {
self.refresh_to_root(leaf);
}
return true;
}
let cut = u8::try_from(offset).expect("fragment offsets fit u8");
let below = (1u64 << cut) - 1;
if cut == 0 {
let rebased = Fragment {
station: frag.station,
base: frag.base.saturating_add(1),
len: frag.len - 1,
visible: frag.visible >> 1,
};
frags[frag_position] = rebased;
let _ = self.index.insert(rebased.base_dot(), leaf);
} else if cut == frag.len - 1 {
let truncated = Fragment {
len: frag.len - 1,
visible: frag.visible & below,
..frag
};
frags[frag_position] = truncated;
let _ = self.index.insert(truncated.base_dot(), leaf);
} else {
let head = Fragment {
len: cut,
visible: frag.visible & below,
..frag
};
let tail = Fragment {
station: frag.station,
base: frag.base.saturating_add(u64::from(cut) + 1),
len: frag.len - cut - 1,
visible: frag.visible >> (cut + 1),
};
frags[frag_position] = head;
frags.insert(frag_position + 1, tail);
let _ = self.index.insert(head.base_dot(), leaf);
let _ = self.index.insert(tail.base_dot(), leaf);
self.split_leaf_if_over(leaf);
}
self.refresh_to_root(leaf);
true
}
}