use std::cmp::Ordering;
use super::ops::Op;
pub fn noncausal_sort(a: &Op, b: &Op) -> Ordering {
a.time
.cmp(&b.time)
.then_with(|| a.id.0.cmp(&b.id.0))
.then_with(|| a.id.1.cmp(&b.id.1))
}
pub(crate) fn only_in_first_sorted_list<
T: Clone,
L: IndexableList<T>,
F: Fn(&T, &T) -> Ordering,
>(
a: &L,
b: &L,
compare: F,
) -> Vec<T> {
if b.size() == 0 {
return a.iter().cloned().collect();
}
let mut result = vec![];
let mut maybe_a_item = a.at(0);
let mut maybe_b_item = b.at(0);
let mut i_a = 0;
let mut i_b = 0;
while let Some(a_item) = maybe_a_item {
if let Some(b_item) = maybe_b_item {
let ordering = compare(a_item, b_item);
match ordering {
Ordering::Less => {
result.push(a_item.clone());
i_a += 1;
maybe_a_item = a.at(i_a);
}
Ordering::Greater => {
i_b += 1;
maybe_b_item = b.at(i_b);
}
Ordering::Equal => {
i_a += 1;
maybe_a_item = a.at(i_a);
i_b += 1;
maybe_b_item = b.at(i_b);
}
}
} else {
result.push(a_item.clone());
i_a += 1;
maybe_a_item = a.at(i_a);
}
}
result
}
pub(crate) fn search_from_back<T, L: IndexableList<T>, F: Fn(&T, &T) -> Ordering>(
list: &L,
item: &T,
compare: F,
) -> Result<usize, usize> {
let mut insertion_pos = list.size();
while insertion_pos > 0 {
let prev = list
.at(insertion_pos - 1)
.expect("Should have never entered for loop if no deletes.");
let ordering = compare(prev, item);
match ordering {
Ordering::Less => break,
Ordering::Greater => {}
Ordering::Equal => return Result::Ok(insertion_pos),
}
insertion_pos -= 1;
}
Result::Err(insertion_pos)
}
pub(crate) trait IndexableList<T> {
fn size(&self) -> usize;
fn at(&self, at: usize) -> Option<&T>;
fn last(&self) -> Option<&T>;
fn iter<'a>(&'a self) -> Box<dyn DoubleEndedIterator<Item = &T> + 'a>;
}
impl<T> IndexableList<T> for Box<dyn IndexableList<T>> {
fn size(&self) -> usize {
self.as_ref().size()
}
fn at(&self, at: usize) -> Option<&T> {
self.as_ref().at(at)
}
fn last(&self) -> Option<&T> {
self.as_ref().last()
}
fn iter<'a>(&'a self) -> Box<dyn DoubleEndedIterator<Item = &T> + 'a> {
self.as_ref().iter()
}
}
impl<T: Clone> IndexableList<T> for im::Vector<T> {
fn size(&self) -> usize {
self.len()
}
fn at(&self, at: usize) -> Option<&T> {
self.get(at)
}
fn last(&self) -> Option<&T> {
self.last()
}
fn iter<'a>(&'a self) -> Box<dyn DoubleEndedIterator<Item = &T> + 'a> {
Box::new(self.iter())
}
}