use std::fmt::Debug;
use std::ops::{AddAssign, SubAssign};
use crate::ContentTraits;
pub trait TreeMetrics<E: ContentTraits> where Self: Debug + Copy + Clone + PartialEq + Eq {
type Update: Debug + Default + PartialEq + Eq;
type Value: Copy + Clone + Default + Debug + AddAssign + SubAssign + PartialEq + Eq + Sized;
fn increment_marker(marker: &mut Self::Update, entry: &E);
fn decrement_marker(marker: &mut Self::Update, entry: &E);
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value);
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update);
fn increment_offset(offset: &mut Self::Value, by: &E);
const CAN_COUNT_ITEMS: bool = false;
fn count_items(_idx: Self::Value) -> usize { panic!("Index cannot count items") }
}
pub trait FindContent<E: ContentTraits + ContentLength>: TreeMetrics<E> {
fn index_to_content(offset: Self::Value) -> usize;
}
pub trait FindOffset<E: ContentTraits>: TreeMetrics<E> {
fn index_to_offset(offset: Self::Value) -> usize;
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ContentMetrics;
impl<E: ContentTraits + ContentLength> TreeMetrics<E> for ContentMetrics {
type Update = isize;
type Value = usize;
fn increment_marker(marker: &mut Self::Update, entry: &E) {
*marker += entry.content_len() as isize;
}
fn decrement_marker(marker: &mut Self::Update, entry: &E) {
*marker -= entry.content_len() as isize;
}
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value) {
*marker -= *val as isize;
}
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update) {
*offset = offset.wrapping_add(*by as Self::Value);
}
fn increment_offset(offset: &mut Self::Value, by: &E) {
*offset += by.content_len() as Self::Value;
}
}
impl<E: ContentTraits + ContentLength> FindContent<E> for ContentMetrics {
fn index_to_content(offset: Self::Value) -> usize { offset as usize }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct RawPositionMetricsU32;
impl<E: ContentTraits> TreeMetrics<E> for RawPositionMetricsU32 {
type Update = isize;
type Value = u32;
fn increment_marker(marker: &mut Self::Update, entry: &E) {
*marker += entry.len() as isize;
}
fn decrement_marker(marker: &mut Self::Update, entry: &E) {
*marker -= entry.len() as isize;
}
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value) {
*marker -= *val as isize;
}
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update) {
*offset = offset.wrapping_add(*by as u32);
}
fn increment_offset(offset: &mut Self::Value, by: &E) {
*offset += by.len() as u32;
}
const CAN_COUNT_ITEMS: bool = true;
fn count_items(idx: Self::Value) -> usize { idx as usize }
}
impl<E: ContentTraits> FindOffset<E> for RawPositionMetricsU32 {
fn index_to_offset(offset: Self::Value) -> usize { offset as usize }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct RawPositionMetricsUsize;
impl<E: ContentTraits> TreeMetrics<E> for RawPositionMetricsUsize {
type Update = isize;
type Value = usize;
fn increment_marker(marker: &mut Self::Update, entry: &E) {
*marker += entry.len() as isize;
}
fn decrement_marker(marker: &mut Self::Update, entry: &E) {
*marker -= entry.len() as isize;
}
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value) {
*marker -= *val as isize;
}
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update) {
*offset = offset.wrapping_add(*by as Self::Value);
}
fn increment_offset(offset: &mut Self::Value, by: &E) {
*offset += by.len();
}
const CAN_COUNT_ITEMS: bool = true;
fn count_items(idx: Self::Value) -> usize { idx }
}
impl<E: ContentTraits> FindOffset<E> for RawPositionMetricsUsize {
fn index_to_offset(offset: Self::Value) -> usize { offset }
}
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
pub struct Pair<V: Copy + Clone + Default + AddAssign + SubAssign + PartialEq + Eq>(pub V, pub V);
impl<V: Copy + Clone + Default + AddAssign + SubAssign + PartialEq + Eq> AddAssign for Pair<V> {
#[inline]
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
self.1 += rhs.1;
}
}
impl<V: Copy + Clone + Default + AddAssign + SubAssign + PartialEq + Eq> SubAssign for Pair<V> {
#[inline]
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
self.1 -= rhs.1;
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct FullMetricsU32;
impl<E: ContentTraits + ContentLength> TreeMetrics<E> for FullMetricsU32 {
type Update = Pair<i32>;
type Value = Pair<u32>;
fn increment_marker(marker: &mut Self::Update, entry: &E) {
marker.0 += entry.len() as i32;
marker.1 += entry.content_len() as i32;
}
fn decrement_marker(marker: &mut Self::Update, entry: &E) {
marker.0 -= entry.len() as i32;
marker.1 -= entry.content_len() as i32;
}
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value) {
marker.0 -= val.0 as i32;
marker.1 -= val.1 as i32;
}
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update) {
offset.0 = offset.0.wrapping_add(by.0 as u32);
offset.1 = offset.1.wrapping_add(by.1 as u32);
}
fn increment_offset(offset: &mut Self::Value, entry: &E) {
offset.0 += entry.len() as u32;
offset.1 += entry.content_len() as u32;
}
const CAN_COUNT_ITEMS: bool = true;
fn count_items(idx: Self::Value) -> usize { idx.0 as usize }
}
impl<E: ContentTraits + ContentLength> FindContent<E> for FullMetricsU32 {
fn index_to_content(offset: Self::Value) -> usize {
offset.1 as usize
}
}
impl<E: ContentTraits + ContentLength> FindOffset<E> for FullMetricsU32 {
fn index_to_offset(offset: Self::Value) -> usize {
offset.0 as usize
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct FullMetricsUsize;
impl<E: ContentTraits + ContentLength> TreeMetrics<E> for FullMetricsUsize {
type Update = Pair<isize>;
type Value = Pair<usize>;
fn increment_marker(marker: &mut Self::Update, entry: &E) {
marker.0 += entry.len() as isize;
marker.1 += entry.content_len() as isize;
}
fn decrement_marker(marker: &mut Self::Update, entry: &E) {
marker.0 -= entry.len() as isize;
marker.1 -= entry.content_len() as isize;
}
fn decrement_marker_by_val(marker: &mut Self::Update, val: &Self::Value) {
marker.0 -= val.0 as isize;
marker.1 -= val.1 as isize;
}
fn update_offset_by_marker(offset: &mut Self::Value, by: &Self::Update) {
offset.0 = offset.0.wrapping_add(by.0 as usize);
offset.1 = offset.1.wrapping_add(by.1 as usize);
}
fn increment_offset(offset: &mut Self::Value, entry: &E) {
offset.0 += entry.len();
offset.1 += entry.content_len();
}
const CAN_COUNT_ITEMS: bool = true;
fn count_items(idx: Self::Value) -> usize { idx.0 }
}
impl<E: ContentTraits + ContentLength> FindContent<E> for FullMetricsUsize {
fn index_to_content(offset: Self::Value) -> usize {
offset.1
}
}
impl<E: ContentTraits + ContentLength> FindOffset<E> for FullMetricsUsize {
fn index_to_offset(offset: Self::Value) -> usize {
offset.0
}
}
pub trait ContentLength {
fn content_len(&self) -> usize;
fn content_len_at_offset(&self, offset: usize) -> usize;
fn offset_len_at_content(&self, content: usize) -> usize { content }
}
pub trait Toggleable {
fn is_activated(&self) -> bool;
fn is_deactivated(&self) -> bool {
!self.is_activated()
}
fn mark_activated(&mut self);
fn mark_deactivated(&mut self);
}