mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-11 14:53:12 +00:00
fix: remove heap
This commit is contained in:
parent
524916239a
commit
e3a93be6a2
1 changed files with 29 additions and 30 deletions
|
@ -3,7 +3,7 @@ use num::Zero;
|
||||||
use super::DagUtils;
|
use super::DagUtils;
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
ops::{Range, RangeBounds},
|
ops::{Add, Range, RangeBounds},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::version::IdSpanVector;
|
use crate::version::IdSpanVector;
|
||||||
|
@ -198,7 +198,6 @@ pub(crate) struct DagCausalIter<'a, Dag> {
|
||||||
in_degrees: FxHashMap<ID, usize>,
|
in_degrees: FxHashMap<ID, usize>,
|
||||||
succ: BTreeMap<ID, SmallVec<[ID; 2]>>,
|
succ: BTreeMap<ID, SmallVec<[ID; 2]>>,
|
||||||
stack: Vec<ID>,
|
stack: Vec<ID>,
|
||||||
heap: BinaryHeap<(bool, ID)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -213,42 +212,36 @@ pub(crate) struct IterReturn<'a, T> {
|
||||||
|
|
||||||
impl<'a, T: DagNode, D: Dag<Node = T>> DagCausalIter<'a, D> {
|
impl<'a, T: DagNode, D: Dag<Node = T>> DagCausalIter<'a, D> {
|
||||||
pub fn new(dag: &'a D, from: SmallVec<[ID; 2]>, target: IdSpanVector) -> Self {
|
pub fn new(dag: &'a D, from: SmallVec<[ID; 2]>, target: IdSpanVector) -> Self {
|
||||||
// make dag
|
let mut in_degrees: FxHashMap<ID, usize> = FxHashMap::default();
|
||||||
let mut in_degrees = FxHashMap::default();
|
|
||||||
let mut succ = BTreeMap::default();
|
let mut succ = BTreeMap::default();
|
||||||
let mut stack = Vec::new();
|
let mut stack = Vec::new();
|
||||||
let mut heap = BinaryHeap::default();
|
|
||||||
let mut q = vec![];
|
let mut q = vec![];
|
||||||
for id in target.iter() {
|
for id in target.iter() {
|
||||||
if id.1.content_len() > 0 {
|
if id.1.content_len() > 0 {
|
||||||
let id = id.id_start();
|
let id = id.id_start();
|
||||||
let node = dag.get(id).unwrap();
|
q.push(id);
|
||||||
let diff = id.counter - node.id_start().counter;
|
|
||||||
heap.push(IdHeapItem {
|
|
||||||
id,
|
|
||||||
lamport: node.lamport() + diff as Lamport,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(id) = heap.pop() {
|
|
||||||
q.push(id.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// traverse all nodes
|
// traverse all nodes
|
||||||
while let Some(id) = q.pop() {
|
while let Some(id) = q.pop() {
|
||||||
let client = id.client_id;
|
let client = id.client_id;
|
||||||
let node = dag.get(id).unwrap();
|
let node = dag.get(id).unwrap();
|
||||||
let deps = node.deps();
|
let deps = node.deps();
|
||||||
if id.counter == target.get(&client).unwrap().min() {
|
if deps.len().is_zero() {
|
||||||
// right after the `from` node can be appended causally
|
in_degrees.insert(id, 0);
|
||||||
// target start nodes maybe have deps relation so we use Lamport.
|
|
||||||
stack.push(id);
|
|
||||||
} else {
|
|
||||||
in_degrees.insert(id, deps.len());
|
|
||||||
}
|
}
|
||||||
|
for dep in deps.iter() {
|
||||||
for dep in node.deps().iter() {
|
let filter = if let Some(span) = target.get(&dep.client_id) {
|
||||||
|
dep.counter < span.min()
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
if filter {
|
||||||
|
in_degrees.entry(id).or_insert(0);
|
||||||
|
} else {
|
||||||
|
in_degrees.entry(id).and_modify(|i| *i += 1).or_insert(1);
|
||||||
|
}
|
||||||
succ.entry(*dep).or_insert_with(SmallVec::new).push(id);
|
succ.entry(*dep).or_insert_with(SmallVec::new).push(id);
|
||||||
}
|
}
|
||||||
let mut target_span = *target.get(&client).unwrap();
|
let mut target_span = *target.get(&client).unwrap();
|
||||||
|
@ -259,6 +252,14 @@ impl<'a, T: DagNode, D: Dag<Node = T>> DagCausalIter<'a, D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_degrees.retain(|k, v| {
|
||||||
|
if v.is_zero() {
|
||||||
|
stack.push(*k);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
dag,
|
dag,
|
||||||
frontier: from,
|
frontier: from,
|
||||||
|
@ -266,7 +267,6 @@ impl<'a, T: DagNode, D: Dag<Node = T>> DagCausalIter<'a, D> {
|
||||||
in_degrees,
|
in_degrees,
|
||||||
succ,
|
succ,
|
||||||
stack,
|
stack,
|
||||||
heap: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,7 @@ impl<'a, T: DagNode + 'a, D: Dag<Node = T>> Iterator for DagCausalIter<'a, D> {
|
||||||
|
|
||||||
let current_client = node_id.client_id;
|
let current_client = node_id.client_id;
|
||||||
let mut keys = Vec::new();
|
let mut keys = Vec::new();
|
||||||
|
let mut heap = BinaryHeap::new();
|
||||||
// The in-degree of the successor node minus 1, and if it becomes 0, it is added to the heap
|
// The in-degree of the successor node minus 1, and if it becomes 0, it is added to the heap
|
||||||
for (key, succ) in self.succ.range((node.id_start(), node.id_end())) {
|
for (key, succ) in self.succ.range((node.id_start(), node.id_end())) {
|
||||||
keys.push(*key);
|
keys.push(*key);
|
||||||
|
@ -338,8 +339,7 @@ impl<'a, T: DagNode + 'a, D: Dag<Node = T>> Iterator for DagCausalIter<'a, D> {
|
||||||
self.in_degrees.entry(*succ_id).and_modify(|i| *i -= 1);
|
self.in_degrees.entry(*succ_id).and_modify(|i| *i -= 1);
|
||||||
if let Some(in_degree) = self.in_degrees.get(succ_id) {
|
if let Some(in_degree) = self.in_degrees.get(succ_id) {
|
||||||
if in_degree.is_zero() {
|
if in_degree.is_zero() {
|
||||||
self.heap
|
heap.push((succ_id.client_id != current_client, *succ_id));
|
||||||
.push((succ_id.client_id == current_client, *succ_id));
|
|
||||||
self.in_degrees.remove(succ_id);
|
self.in_degrees.remove(succ_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,7 +349,7 @@ impl<'a, T: DagNode + 'a, D: Dag<Node = T>> Iterator for DagCausalIter<'a, D> {
|
||||||
keys.into_iter().for_each(|k| {
|
keys.into_iter().for_each(|k| {
|
||||||
self.succ.remove(&k);
|
self.succ.remove(&k);
|
||||||
});
|
});
|
||||||
while let Some(id) = self.heap.pop() {
|
while let Some(id) = heap.pop() {
|
||||||
self.stack.push(id.1)
|
self.stack.push(id.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,6 @@ impl<'a, T: DagNode + 'a, D: Dag<Node = T>> Iterator for DagCausalIter<'a, D> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
change::ChangeMergeCfg,
|
change::ChangeMergeCfg,
|
||||||
configure::Configure,
|
configure::Configure,
|
||||||
|
@ -498,11 +497,11 @@ mod test {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut from_vv = VersionVector::new();
|
let mut from_vv = VersionVector::new();
|
||||||
from_vv.set_end(ID {
|
from_vv.set_last(ID {
|
||||||
client_id: 1,
|
client_id: 1,
|
||||||
counter: 1,
|
counter: 1,
|
||||||
});
|
});
|
||||||
from_vv.set_end(ID {
|
from_vv.set_last(ID {
|
||||||
client_id: 2,
|
client_id: 2,
|
||||||
counter: 1,
|
counter: 1,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue