#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
use std::cmp::Ordering;
use std::fmt;
use crate::avl_tree::{AVLTree, AVL_NULL};
use crate::data_structures::{
cmp_range_frags, InstPoint, RangeFrag, RangeFragIx, RangeId, SortedRangeFragIxs,
SortedRangeFrags, TypedIxVec,
};
#[derive(Clone)]
pub struct RangeFragAndRangeId {
pub frag: RangeFrag,
pub id: RangeId,
}
impl RangeFragAndRangeId {
fn new(frag: RangeFrag, id: RangeId) -> Self {
Self { frag, id }
}
}
impl PartialEq for RangeFragAndRangeId {
fn eq(&self, _other: &Self) -> bool {
panic!("impl PartialEq for RangeFragAndRangeId: should never be used");
}
}
impl PartialOrd for RangeFragAndRangeId {
fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
panic!("impl PartialOrd for RangeFragAndRangeId: should never be used");
}
}
impl fmt::Debug for RangeFragAndRangeId {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "(FnV {:?} {:?})", self.frag, self.id)
}
}
pub struct CommitmentMap {
pub tree: AVLTree<RangeFragAndRangeId>,
}
impl fmt::Debug for CommitmentMap {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let as_vec = self.tree.to_vec();
as_vec.fmt(fmt)
}
}
impl CommitmentMap {
pub fn new() -> Self {
let dflt = RangeFragAndRangeId::new(RangeFrag::invalid_value(), RangeId::invalid_value());
Self {
tree: AVLTree::<RangeFragAndRangeId>::new(dflt),
}
}
pub fn add(&mut self, to_add_frags: &SortedRangeFrags, to_add_lr_id: RangeId) {
for frag in &to_add_frags.frags {
let to_add = RangeFragAndRangeId::new(frag.clone(), to_add_lr_id);
let added = self.tree.insert(
to_add,
Some(&|pair1: RangeFragAndRangeId, pair2: RangeFragAndRangeId| {
cmp_range_frags(&pair1.frag, &pair2.frag)
}),
);
assert!(added);
}
}
pub fn add_indirect(
&mut self,
to_add_frags: &SortedRangeFragIxs,
to_add_lr_id: RangeId,
frag_env: &TypedIxVec<RangeFragIx, RangeFrag>,
) {
for fix in &to_add_frags.frag_ixs {
let to_add = RangeFragAndRangeId::new(frag_env[*fix].clone(), to_add_lr_id);
let added = self.tree.insert(
to_add,
Some(&|pair1: RangeFragAndRangeId, pair2: RangeFragAndRangeId| {
cmp_range_frags(&pair1.frag, &pair2.frag)
}),
);
assert!(added);
}
}
pub fn del(&mut self, to_del_frags: &SortedRangeFrags) {
for frag in &to_del_frags.frags {
let to_del = RangeFragAndRangeId::new(frag.clone(), RangeId::invalid_value());
let deleted = self.tree.delete(
to_del,
Some(&|pair1: RangeFragAndRangeId, pair2: RangeFragAndRangeId| {
cmp_range_frags(&pair1.frag, &pair2.frag)
}),
);
assert!(deleted);
}
}
pub fn lookup_inst_point(&self, pt: InstPoint) -> Option<RangeId> {
let mut root = self.tree.root;
while root != AVL_NULL {
let root_node = &self.tree.pool[root as usize];
let root_item = &root_node.item;
if pt < root_item.frag.first {
root = root_node.left;
} else if root_item.frag.last < pt {
root = root_node.right;
} else {
return Some(root_item.id);
}
}
None
}
}