use crate::EventSet;
use serde::{Deserialize, Serialize};
use std::cmp::{self, Ordering};
use std::collections::btree_set::{self, BTreeSet};
use std::collections::HashSet;
use std::fmt;
use std::iter::FromIterator;
#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct AboveExSet {
max: u64,
exs: HashSet<u64>,
}
impl EventSet for AboveExSet {
type EventIter = EventIter;
fn new() -> Self {
AboveExSet {
max: 0,
exs: HashSet::new(),
}
}
fn next_event(&mut self) -> u64 {
debug_assert!(self.exs.is_empty());
self.max += 1;
self.max
}
fn add_event(&mut self, event: u64) -> bool {
let next_max = self.max + 1;
match event.cmp(&next_max) {
Ordering::Equal => {
self.max = event;
self.try_compress();
true
}
Ordering::Greater => {
self.exs.insert(event)
}
Ordering::Less => {
false
}
}
}
fn add_event_range(&mut self, start: u64, end: u64) -> bool {
if start <= self.max + 1 && end > self.max {
self.max = end;
let max = self.max;
self.exs.retain(|ex| *ex > max);
self.try_compress();
true
} else if start > self.max + 1 {
self.exs.extend(start..=end);
true
} else {
false
}
}
fn is_event(&self, event: u64) -> bool {
event <= self.max || self.exs.contains(&event)
}
fn events(&self) -> (u64, Vec<u64>) {
let mut exs: Vec<_> = self.exs.clone().into_iter().collect();
exs.sort_unstable();
(self.max, exs)
}
fn frontier(&self) -> u64 {
self.max
}
fn join(&mut self, other: &Self) {
self.max = cmp::max(self.max, other.max);
let max = self.max;
other.exs.iter().filter(|ex| **ex > max).for_each(|ex| {
self.exs.insert(*ex);
});
self.try_compress();
}
fn meet(&mut self, other: &Self) {
let previous_max = self.max;
self.max = cmp::min(self.max, other.max);
self.exs
.retain(|ex| ex <= &other.max || other.exs.contains(ex));
self.exs.extend(
((self.max + 1)..=previous_max).filter(|ex| other.exs.contains(ex)),
);
self.try_compress();
}
fn subtracted(&self, other: &Self) -> Vec<u64> {
let iter = self.exs.iter().filter(|ex| !other.is_event(**ex)).cloned();
if self.max > other.max {
iter.chain(
((other.max + 1)..=self.max)
.filter(|event| !other.exs.contains(event)),
)
.collect()
} else {
iter.collect()
}
}
fn event_iter(self) -> Self::EventIter {
EventIter {
current: 0,
max: self.max,
exs: BTreeSet::from_iter(self.exs).into_iter(),
}
}
}
impl AboveExSet {
fn try_compress(&mut self) {
while self.exs.remove(&(self.max + 1)) {
self.max = self.max + 1;
}
}
pub fn from<I: IntoIterator<Item = u64>>(max: u64, iter: I) -> Self {
AboveExSet {
max,
exs: HashSet::from_iter(iter),
}
}
pub fn missing_below(&self, ceil: u64) -> impl Iterator<Item = u64> + '_ {
let below = (self.max + 1)..ceil;
below.filter(move |event| !self.exs.contains(event))
}
}
pub struct EventIter {
current: u64,
max: u64,
exs: btree_set::IntoIter<u64>,
}
impl Iterator for EventIter {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
if self.current == self.max {
self.exs.next()
} else {
self.current += 1;
Some(self.current)
}
}
}
impl fmt::Debug for AboveExSet {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.exs.is_empty() {
write!(f, "{}", self.max)
} else {
let exs: std::collections::BTreeSet<_> = self.exs.iter().collect();
write!(f, "({} + {:?})", self.max, exs)
}
}
}