2021-08-20 22:18:39 +00:00
|
|
|
use super::Operation;
|
2021-05-06 07:32:14 +00:00
|
|
|
use std::{fmt::Debug, ops::Add};
|
2021-10-01 21:55:21 +00:00
|
|
|
use sum_tree::{Cursor, Dimension, Edit, Item, KeyedItem, SumTree, Summary};
|
2021-03-18 19:13:31 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
2021-08-20 22:18:39 +00:00
|
|
|
pub struct OperationQueue(SumTree<Operation>);
|
2021-03-18 19:13:31 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
|
2021-10-04 12:34:02 +00:00
|
|
|
pub struct OperationKey(clock::Lamport);
|
2021-03-18 19:13:31 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
|
|
pub struct OperationSummary {
|
2021-08-20 22:18:39 +00:00
|
|
|
pub key: OperationKey,
|
|
|
|
pub len: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl OperationKey {
|
2021-10-04 12:34:02 +00:00
|
|
|
pub fn new(timestamp: clock::Lamport) -> Self {
|
2021-08-20 22:18:39 +00:00
|
|
|
Self(timestamp)
|
|
|
|
}
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
|
|
|
|
2021-08-20 22:18:39 +00:00
|
|
|
impl OperationQueue {
|
2021-03-18 19:13:31 +00:00
|
|
|
pub fn new() -> Self {
|
|
|
|
OperationQueue(SumTree::new())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.0.summary().len
|
|
|
|
}
|
|
|
|
|
2021-08-20 22:18:39 +00:00
|
|
|
pub fn insert(&mut self, mut ops: Vec<Operation>) {
|
|
|
|
ops.sort_by_key(|op| op.lamport_timestamp());
|
|
|
|
ops.dedup_by_key(|op| op.lamport_timestamp());
|
2021-05-06 17:29:38 +00:00
|
|
|
self.0
|
|
|
|
.edit(ops.into_iter().map(Edit::Insert).collect(), &());
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn drain(&mut self) -> Self {
|
|
|
|
let clone = self.clone();
|
|
|
|
self.0 = SumTree::new();
|
|
|
|
clone
|
|
|
|
}
|
|
|
|
|
2021-09-25 01:04:43 +00:00
|
|
|
pub fn cursor(&self) -> Cursor<Operation, ()> {
|
2021-03-18 19:13:31 +00:00
|
|
|
self.0.cursor()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-06 07:32:14 +00:00
|
|
|
impl Summary for OperationSummary {
|
2021-05-06 14:13:35 +00:00
|
|
|
type Context = ();
|
|
|
|
|
2021-05-06 17:29:38 +00:00
|
|
|
fn add_summary(&mut self, other: &Self, _: &()) {
|
2021-03-18 19:13:31 +00:00
|
|
|
assert!(self.key < other.key);
|
|
|
|
self.key = other.key;
|
|
|
|
self.len += other.len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Add<&'a Self> for OperationSummary {
|
|
|
|
type Output = Self;
|
|
|
|
|
|
|
|
fn add(self, other: &Self) -> Self {
|
|
|
|
assert!(self.key < other.key);
|
|
|
|
OperationSummary {
|
|
|
|
key: other.key,
|
|
|
|
len: self.len + other.len,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Dimension<'a, OperationSummary> for OperationKey {
|
2021-06-01 10:50:10 +00:00
|
|
|
fn add_summary(&mut self, summary: &OperationSummary, _: &()) {
|
2021-03-18 19:13:31 +00:00
|
|
|
assert!(*self <= summary.key);
|
|
|
|
*self = summary.key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-20 22:18:39 +00:00
|
|
|
impl Item for Operation {
|
|
|
|
type Summary = OperationSummary;
|
|
|
|
|
|
|
|
fn summary(&self) -> Self::Summary {
|
|
|
|
OperationSummary {
|
|
|
|
key: OperationKey::new(self.lamport_timestamp()),
|
|
|
|
len: 1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl KeyedItem for Operation {
|
|
|
|
type Key = OperationKey;
|
|
|
|
|
|
|
|
fn key(&self) -> Self::Key {
|
|
|
|
OperationKey::new(self.lamport_timestamp())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-18 19:13:31 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_len() {
|
2021-10-04 12:34:02 +00:00
|
|
|
let mut clock = clock::Lamport::new(0);
|
2021-03-18 19:13:31 +00:00
|
|
|
|
|
|
|
let mut queue = OperationQueue::new();
|
|
|
|
assert_eq!(queue.len(), 0);
|
|
|
|
|
|
|
|
queue.insert(vec![
|
2021-08-20 22:18:39 +00:00
|
|
|
Operation::Test(clock.tick()),
|
|
|
|
Operation::Test(clock.tick()),
|
2021-03-18 19:13:31 +00:00
|
|
|
]);
|
|
|
|
assert_eq!(queue.len(), 2);
|
|
|
|
|
2021-08-20 22:18:39 +00:00
|
|
|
queue.insert(vec![Operation::Test(clock.tick())]);
|
2021-03-18 19:13:31 +00:00
|
|
|
assert_eq!(queue.len(), 3);
|
|
|
|
|
|
|
|
drop(queue.drain());
|
|
|
|
assert_eq!(queue.len(), 0);
|
|
|
|
|
2021-08-20 22:18:39 +00:00
|
|
|
queue.insert(vec![Operation::Test(clock.tick())]);
|
2021-03-18 19:13:31 +00:00
|
|
|
assert_eq!(queue.len(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
2021-10-04 12:34:02 +00:00
|
|
|
struct TestOperation(clock::Lamport);
|
2021-03-18 19:13:31 +00:00
|
|
|
}
|