mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 02:59:51 +00:00
refactor: rm unused code
This commit is contained in:
parent
a615104fb1
commit
7b81bed19d
1 changed files with 2 additions and 349 deletions
|
@ -218,33 +218,12 @@ impl ContainerHistoryCache {
|
|||
}
|
||||
}
|
||||
|
||||
#[enum_dispatch(OpGroupTrait)]
|
||||
#[derive(Debug, Clone, EnumAsInner)]
|
||||
pub(crate) enum HistoryCacheForCheckout {
|
||||
Map(MapOpGroup),
|
||||
MovableList(MovableListOpGroup),
|
||||
}
|
||||
|
||||
#[enum_dispatch(OpGroupTrait)]
|
||||
#[derive(Debug, Clone, EnumAsInner)]
|
||||
pub(crate) enum HistoryCacheForImporting {
|
||||
Tree(TreeOpGroup),
|
||||
}
|
||||
|
||||
impl HistoryCacheForCheckout {
|
||||
fn fork(&self, a: &SharedArena) -> Self {
|
||||
match self {
|
||||
HistoryCacheForCheckout::Map(m) => HistoryCacheForCheckout::Map(m.clone()),
|
||||
HistoryCacheForCheckout::MovableList(m) => {
|
||||
HistoryCacheForCheckout::MovableList(MovableListOpGroup {
|
||||
arena: a.clone(),
|
||||
elem_mappings: m.elem_mappings.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HistoryCacheForImporting {
|
||||
fn insert(&mut self, op: &RichOp) {
|
||||
match self {
|
||||
|
@ -393,45 +372,6 @@ impl MapHistoryCache {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub(crate) struct MapOpGroup {
|
||||
ops: FxHashMap<InternalString, SmallSet<GroupedMapOpInfo>>,
|
||||
}
|
||||
|
||||
impl MapOpGroup {
|
||||
pub(crate) fn last_op(
|
||||
&self,
|
||||
key: &InternalString,
|
||||
vv: &VersionVector,
|
||||
) -> Option<&GroupedMapOpInfo> {
|
||||
self.ops.get(key).and_then(|set| {
|
||||
set.iter()
|
||||
.rev()
|
||||
.find(|op| vv.get(&op.peer).copied().unwrap_or(0) > op.counter)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn keys(&self) -> impl Iterator<Item = &InternalString> {
|
||||
self.ops.keys()
|
||||
}
|
||||
}
|
||||
|
||||
impl HistoryCacheTrait for MapOpGroup {
|
||||
fn insert(&mut self, op: &RichOp) {
|
||||
let key = match &op.raw_op().content {
|
||||
InnerContent::Map(map) => map.key.clone(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let entry = self.ops.entry(key).or_default();
|
||||
entry.insert(GroupedMapOpInfo {
|
||||
value: op.raw_op().content.as_map().unwrap().value.clone(),
|
||||
counter: op.raw_op().counter,
|
||||
lamport: op.lamport(),
|
||||
peer: op.peer,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct GroupedTreeOpInfo {
|
||||
pub(crate) peer: PeerID,
|
||||
|
@ -485,8 +425,8 @@ impl HistoryCacheTrait for TreeOpGroup {
|
|||
|
||||
#[derive(Debug, Default)]
|
||||
pub(crate) struct MovableListHistoryCache {
|
||||
pub(crate) move_set: BTreeSet<MovableListInnerDeltaEntry>,
|
||||
pub(crate) set_set: BTreeSet<MovableListInnerDeltaEntry>,
|
||||
move_set: BTreeSet<MovableListInnerDeltaEntry>,
|
||||
set_set: BTreeSet<MovableListInnerDeltaEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone)]
|
||||
|
@ -647,290 +587,3 @@ impl MovableListHistoryCache {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct MovableListOpGroup {
|
||||
arena: SharedArena,
|
||||
/// mappings from elem_id to a set of target poses & values
|
||||
elem_mappings: FxHashMap<IdLp, MovableListTarget>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum MovableListTarget {
|
||||
One { value: LoroValue, counter: Counter },
|
||||
Multiple(Box<MultipleInner>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct MultipleInner {
|
||||
poses: BTreeSet<GroupedMapOpInfo<()>>,
|
||||
values: BTreeSet<GroupedMapOpInfo<LoroValue>>,
|
||||
}
|
||||
|
||||
impl MovableListTarget {
|
||||
fn upgrade(&mut self, key_idlp: IdLp) -> &mut MultipleInner {
|
||||
match self {
|
||||
MovableListTarget::One { value, counter } => {
|
||||
let mut inner = MultipleInner {
|
||||
poses: BTreeSet::default(),
|
||||
values: BTreeSet::default(),
|
||||
};
|
||||
inner.poses.insert(GroupedMapOpInfo {
|
||||
value: (),
|
||||
counter: *counter,
|
||||
lamport: key_idlp.lamport,
|
||||
peer: key_idlp.peer,
|
||||
});
|
||||
inner.values.insert(GroupedMapOpInfo {
|
||||
value: value.clone(),
|
||||
counter: *counter,
|
||||
lamport: key_idlp.lamport,
|
||||
peer: key_idlp.peer,
|
||||
});
|
||||
*self = MovableListTarget::Multiple(Box::new(inner));
|
||||
match self {
|
||||
MovableListTarget::Multiple(a) => a,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
MovableListTarget::Multiple(a) => a,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HistoryCacheTrait for MovableListOpGroup {
|
||||
fn insert(&mut self, op: &RichOp) {
|
||||
let start_id = op.id_full().idlp();
|
||||
match &op.op().content {
|
||||
InnerContent::List(list) => match list {
|
||||
crate::container::list::list_op::InnerListOp::Set { elem_id, value } => {
|
||||
let full_id = op.id_full();
|
||||
let mapping = self
|
||||
.elem_mappings
|
||||
.entry(*elem_id)
|
||||
.or_insert_with(|| {
|
||||
MovableListTarget::Multiple(Box::new(MultipleInner {
|
||||
poses: BTreeSet::default(),
|
||||
values: BTreeSet::default(),
|
||||
}))
|
||||
})
|
||||
.upgrade(*elem_id);
|
||||
mapping.values.insert(GroupedMapOpInfo {
|
||||
value: value.clone(),
|
||||
counter: full_id.counter,
|
||||
lamport: full_id.lamport,
|
||||
peer: full_id.peer,
|
||||
});
|
||||
}
|
||||
crate::container::list::list_op::InnerListOp::Insert { slice, pos: _ } => {
|
||||
for (i, v) in self.arena.iter_value_slice(slice.to_range()).enumerate() {
|
||||
let id = start_id.inc(i as i32);
|
||||
let full_id = op.id_full().inc(i as i32);
|
||||
if let Some(target) = self.elem_mappings.get_mut(&id) {
|
||||
let inner = target.upgrade(id);
|
||||
inner.poses.insert(GroupedMapOpInfo {
|
||||
value: (),
|
||||
counter: full_id.counter,
|
||||
lamport: full_id.lamport,
|
||||
peer: full_id.peer,
|
||||
});
|
||||
inner.values.insert(GroupedMapOpInfo {
|
||||
value: v.clone(),
|
||||
counter: full_id.counter,
|
||||
lamport: full_id.lamport,
|
||||
peer: full_id.peer,
|
||||
});
|
||||
} else {
|
||||
self.elem_mappings.insert(
|
||||
id,
|
||||
MovableListTarget::One {
|
||||
value: v,
|
||||
counter: full_id.counter,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
crate::container::list::list_op::InnerListOp::Move {
|
||||
elem_id: from_id, ..
|
||||
} => {
|
||||
let full_id = op.id_full();
|
||||
let mapping = self
|
||||
.elem_mappings
|
||||
.entry(*from_id)
|
||||
.or_insert_with(|| {
|
||||
MovableListTarget::Multiple(Box::new(MultipleInner {
|
||||
poses: BTreeSet::default(),
|
||||
values: BTreeSet::default(),
|
||||
}))
|
||||
})
|
||||
.upgrade(*from_id);
|
||||
mapping.poses.insert(GroupedMapOpInfo {
|
||||
value: (),
|
||||
counter: full_id.counter,
|
||||
lamport: full_id.lamport,
|
||||
peer: full_id.peer,
|
||||
});
|
||||
}
|
||||
// Don't mark deletions for now, but the cost is the state now may contain invalid elements
|
||||
// that are deleted but not removed from the state.
|
||||
// Maybe we can remove the elements with no valid pos mapping directly from the state. When
|
||||
// it's needed, we load it lazily from this group.
|
||||
crate::container::list::list_op::InnerListOp::Delete(_) => {}
|
||||
crate::container::list::list_op::InnerListOp::StyleStart { .. }
|
||||
| crate::container::list::list_op::InnerListOp::StyleEnd
|
||||
| crate::container::list::list_op::InnerListOp::InsertText { .. } => unreachable!(),
|
||||
},
|
||||
InnerContent::Map(_) => unreachable!(),
|
||||
InnerContent::Tree(_) => unreachable!(),
|
||||
InnerContent::Future(_) => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl MovableListOpGroup {
|
||||
fn new(arena: SharedArena) -> Self {
|
||||
Self {
|
||||
arena,
|
||||
elem_mappings: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn last_pos(&self, key: &IdLp, vv: &VersionVector) -> Option<GroupedMapOpInfo<()>> {
|
||||
let ans = self.elem_mappings.get(key).and_then(|set| match set {
|
||||
MovableListTarget::One { value: _, counter } => {
|
||||
if vv.get(&key.peer).copied().unwrap_or(0) > *counter {
|
||||
Some(GroupedMapOpInfo {
|
||||
value: (),
|
||||
counter: *counter,
|
||||
lamport: key.lamport,
|
||||
peer: key.peer,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
MovableListTarget::Multiple(m) => m
|
||||
.poses
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|op| vv.get(&op.peer).copied().unwrap_or(0) > op.counter)
|
||||
.cloned(),
|
||||
});
|
||||
|
||||
ans
|
||||
}
|
||||
|
||||
pub(crate) fn last_value(
|
||||
&self,
|
||||
key: &IdLp,
|
||||
vv: &VersionVector,
|
||||
) -> Option<GroupedMapOpInfo<LoroValue>> {
|
||||
self.elem_mappings.get(key).and_then(|set| match set {
|
||||
MovableListTarget::One { value, counter } => {
|
||||
if vv.get(&key.peer).copied().unwrap_or(0) > *counter {
|
||||
Some(GroupedMapOpInfo {
|
||||
value: value.clone(),
|
||||
counter: *counter,
|
||||
lamport: key.lamport,
|
||||
peer: key.peer,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
MovableListTarget::Multiple(m) => m
|
||||
.values
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|op| vv.get(&op.peer).copied().unwrap_or(0) > op.counter)
|
||||
.cloned(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
enum SmallSet<T> {
|
||||
#[default]
|
||||
Empty,
|
||||
One(T),
|
||||
Many(BTreeSet<T>),
|
||||
}
|
||||
|
||||
struct SmallSetIter<'a, T> {
|
||||
set: &'a SmallSet<T>,
|
||||
one_itered: bool,
|
||||
iter: Option<std::collections::btree_set::Iter<'a, T>>,
|
||||
}
|
||||
|
||||
impl<T: Ord> SmallSet<T> {
|
||||
fn insert(&mut self, new_value: T) {
|
||||
match self {
|
||||
SmallSet::Empty => *self = SmallSet::One(new_value),
|
||||
SmallSet::One(v) => {
|
||||
if v != &new_value {
|
||||
let mut set = BTreeSet::new();
|
||||
let SmallSet::One(v) = std::mem::take(self) else {
|
||||
unreachable!()
|
||||
};
|
||||
set.insert(v);
|
||||
set.insert(new_value);
|
||||
*self = SmallSet::Many(set);
|
||||
}
|
||||
}
|
||||
SmallSet::Many(set) => {
|
||||
set.insert(new_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn iter(&self) -> SmallSetIter<T> {
|
||||
SmallSetIter {
|
||||
set: self,
|
||||
one_itered: false,
|
||||
iter: match self {
|
||||
SmallSet::Empty => None,
|
||||
SmallSet::One(_) => None,
|
||||
SmallSet::Many(set) => Some(set.iter()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DoubleEndedIterator for SmallSetIter<'a, T> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
match self.iter {
|
||||
Some(ref mut iter) => iter.next_back(),
|
||||
None => {
|
||||
if self.one_itered {
|
||||
None
|
||||
} else {
|
||||
self.one_itered = true;
|
||||
match self.set {
|
||||
SmallSet::One(v) => Some(v),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for SmallSetIter<'a, T> {
|
||||
type Item = &'a T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.set {
|
||||
SmallSet::Empty => None,
|
||||
SmallSet::One(v) => {
|
||||
if self.one_itered {
|
||||
None
|
||||
} else {
|
||||
self.one_itered = true;
|
||||
Some(v)
|
||||
}
|
||||
}
|
||||
SmallSet::Many(_) => self.iter.as_mut().unwrap().next(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue