#![allow(unused)]
use loro_common::{IdFull, IdLp, TreeID};
use rustc_hash::FxHashMap;
use crate::VersionVector;
use super::bool_rle_vec::BoolRleVec;
pub(crate) struct TreeLinearHistory {
ops: Vec<TreeOpWrap>,
has_effect: BoolRleVec,
target_to_op_idx: FxHashMap<TreeID, usize>,
}
struct TreeOpWrap {
op: TreeOp,
last_effective_update_on_target: Option<usize>,
}
pub(crate) struct TreeOp {
pub id: IdFull,
pub target: TreeID,
}
pub(crate) struct PoppedTreeOp {
pub op: TreeOp,
pub has_effect: bool,
pub last_update_on_target: Option<IdFull>,
}
impl TreeLinearHistory {
pub fn new() -> Self {
Self {
ops: Vec::new(),
has_effect: BoolRleVec::new(),
target_to_op_idx: FxHashMap::default(),
}
}
pub fn from_vec(ops: Vec<TreeOp>, has_effect: BoolRleVec) -> Self {
let mut this = Self::new();
for (op, e) in ops.into_iter().zip(has_effect.iter()) {
this.push(op, e);
}
this
}
pub fn push(&mut self, op: TreeOp, has_effect: bool) {
if has_effect {
let last = self.target_to_op_idx.insert(op.target, self.ops.len());
self.ops.push(TreeOpWrap {
op,
last_effective_update_on_target: last,
});
} else {
self.ops.push(TreeOpWrap {
op,
last_effective_update_on_target: None,
});
}
self.has_effect.push(has_effect);
}
pub fn pop_util(&mut self, threshold: IdLp) -> Vec<PoppedTreeOp> {
let index = match self
.ops
.binary_search_by(|op_wrap| op_wrap.op.id.idlp().cmp(&threshold))
{
Ok(index) => index,
Err(index) => index,
};
self._pop_util(index)
}
#[must_use]
pub fn pop_until_all_inside_vv(&mut self, vv: &VersionVector) -> Vec<PoppedTreeOp> {
for (i, op_wrap) in self.ops.iter().enumerate() {
if vv.get(&op_wrap.op.id.peer).unwrap() <= &op_wrap.op.id.counter {
return self._pop_util(i);
}
}
vec![]
}
fn _pop_util(&mut self, index: usize) -> Vec<PoppedTreeOp> {
todo!()
}
pub fn last_update_on(&self, target: TreeID) -> Option<IdFull> {
self.target_to_op_idx
.get(&target)
.and_then(|&idx| self.ops.get(idx))
.map(|op_wrap| op_wrap.op.id)
}
pub fn greatest_idlp(&self) -> Option<IdLp> {
self.ops.last().map(|op| op.op.id.idlp())
}
#[inline]
pub fn len(&self) -> usize {
self.ops.len()
}
#[inline]
pub fn get_bool_rle_vec(&self) -> &BoolRleVec {
&self.has_effect
}
}