use crate::{platform::prelude::*, Time};
use core::{
cmp::min,
slice::{Iter, IterMut},
};
#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct SegmentHistory(Vec<(i32, Time)>);
impl SegmentHistory {
pub fn try_get_min_index(&self) -> Option<i32> {
Some(self.0.first()?.0)
}
pub fn min_index(&self) -> i32 {
self.try_get_min_index().map_or(1, |m| min(m, 1))
}
pub fn try_get_max_index(&self) -> Option<i32> {
Some(self.0.last()?.0)
}
fn get_pos(&self, index: i32) -> Result<usize, usize> {
self.0.binary_search_by_key(&index, |&(i, _)| i)
}
#[inline]
pub fn insert(&mut self, index: i32, time: Time) {
if let Err(pos) = self.get_pos(index) {
self.0.insert(pos, (index, time));
}
}
#[inline]
pub fn get(&self, index: i32) -> Option<Time> {
let pos = self.get_pos(index).ok()?;
Some(self.0.get(pos)?.1)
}
#[inline]
pub fn get_mut(&mut self, index: i32) -> Option<&mut Time> {
let pos = self.get_pos(index).ok()?;
Some(&mut self.0.get_mut(pos)?.1)
}
#[inline]
pub fn remove(&mut self, index: i32) -> Option<Time> {
let pos = self.get_pos(index).ok()?;
Some(self.0.remove(pos).1)
}
#[inline]
pub fn clear(&mut self) {
self.0.clear();
}
#[inline]
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&(i32, Time)) -> bool,
{
self.0.retain(f);
}
#[inline]
pub fn iter(&self) -> Iter<'_, (i32, Time)> {
IntoIterator::into_iter(self)
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, (i32, Time)> {
self.0.iter_mut()
}
#[inline]
pub fn iter_actual_runs(&self) -> Iter<'_, (i32, Time)> {
let start = match self.get_pos(1) {
Ok(pos) | Err(pos) => pos,
};
self.0[start..].iter()
}
}
impl<'a> IntoIterator for &'a SegmentHistory {
type Item = &'a (i32, Time);
type IntoIter = Iter<'a, (i32, Time)>;
fn into_iter(self) -> Iter<'a, (i32, Time)> {
self.0.iter()
}
}