use std::{cmp, fmt};
use pool::Transaction;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Choice {
RejectNew,
ReplaceOld,
InsertNew,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Change<T = ()> {
InsertedAt(usize),
RemovedAt(usize),
ReplacedAt(usize),
Culled(usize),
Event(T),
}
pub trait Scoring<T>: fmt::Debug {
type Score: cmp::Ord + Clone + Default + fmt::Debug;
type Event: fmt::Debug;
fn compare(&self, old: &T, other: &T) -> cmp::Ordering;
fn choose(&self, old: &T, new: &T) -> Choice;
fn update_scores(&self, txs: &[Transaction<T>], scores: &mut [Self::Score], change: Change<Self::Event>);
fn should_replace(&self, old: &T, new: &T) -> bool;
}
#[derive(Debug)]
pub struct ScoreWithRef<T, S> {
pub score: S,
pub transaction: Transaction<T>,
}
impl<T, S> ScoreWithRef<T, S> {
pub fn new(score: S, transaction: Transaction<T>) -> Self {
ScoreWithRef { score, transaction }
}
}
impl<T, S: Clone> Clone for ScoreWithRef<T, S> {
fn clone(&self) -> Self {
ScoreWithRef {
score: self.score.clone(),
transaction: self.transaction.clone(),
}
}
}
impl<S: cmp::Ord, T> Ord for ScoreWithRef<T, S> {
fn cmp(&self, other: &Self) -> cmp::Ordering {
other.score.cmp(&self.score)
.then(other.transaction.insertion_id.cmp(&self.transaction.insertion_id))
}
}
impl<S: cmp::Ord, T> PartialOrd for ScoreWithRef<T, S> {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other))
}
}
impl<S: cmp::Ord, T> PartialEq for ScoreWithRef<T, S> {
fn eq(&self, other: &Self) -> bool {
self.score == other.score && self.transaction.insertion_id == other.transaction.insertion_id
}
}
impl<S: cmp::Ord, T> Eq for ScoreWithRef<T, S> {}