mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
use bitvec to return SCCs
This commit is contained in:
parent
a7e781ece2
commit
b8db6aae8d
2 changed files with 47 additions and 10 deletions
|
@ -30,7 +30,6 @@ use roc_types::types::AliasKind;
|
||||||
use roc_types::types::LambdaSet;
|
use roc_types::types::LambdaSet;
|
||||||
use roc_types::types::{Alias, Type};
|
use roc_types::types::{Alias, Type};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use ven_graph::topological_sort;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Def {
|
pub struct Def {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// see if we get better performance with different integer types
|
// see if we get better performance with different integer types
|
||||||
pub(crate) type Element = usize;
|
type Order = bitvec::order::Lsb0;
|
||||||
pub(crate) type BitVec = bitvec::vec::BitVec<Element>;
|
type Element = usize;
|
||||||
pub(crate) type BitSlice = bitvec::prelude::BitSlice<Element>;
|
type BitVec = bitvec::vec::BitVec<Element, Order>;
|
||||||
|
type BitSlice = bitvec::prelude::BitSlice<Element, Order>;
|
||||||
|
|
||||||
/// A square boolean matrix used to store relations
|
/// A square boolean matrix used to store relations
|
||||||
///
|
///
|
||||||
|
@ -172,7 +173,12 @@ impl ReferenceMatrix {
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
break params.scc;
|
let mut result = Vec::new();
|
||||||
|
for group in params.scc.components() {
|
||||||
|
result.push(group.map(|v| v as u32).collect());
|
||||||
|
}
|
||||||
|
|
||||||
|
break result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +208,7 @@ struct Params {
|
||||||
c: usize,
|
c: usize,
|
||||||
p: Vec<u32>,
|
p: Vec<u32>,
|
||||||
s: Vec<u32>,
|
s: Vec<u32>,
|
||||||
scc: Vec<Vec<u32>>,
|
scc: Sccs,
|
||||||
scca: Vec<u32>,
|
scca: Vec<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +225,10 @@ impl Params {
|
||||||
c: 0,
|
c: 0,
|
||||||
s: Vec::new(),
|
s: Vec::new(),
|
||||||
p: Vec::new(),
|
p: Vec::new(),
|
||||||
scc: Vec::new(),
|
scc: Sccs {
|
||||||
|
matrix: ReferenceMatrix::new(length),
|
||||||
|
components: 0,
|
||||||
|
},
|
||||||
scca: Vec::new(),
|
scca: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,15 +269,44 @@ fn recurse_onto(length: usize, bitvec: &BitVec, v: usize, params: &mut Params) {
|
||||||
if params.p.last() == Some(&(v as u32)) {
|
if params.p.last() == Some(&(v as u32)) {
|
||||||
params.p.pop();
|
params.p.pop();
|
||||||
|
|
||||||
let mut component = Vec::new();
|
|
||||||
while let Some(node) = params.s.pop() {
|
while let Some(node) = params.s.pop() {
|
||||||
component.push(node);
|
params
|
||||||
|
.scc
|
||||||
|
.matrix
|
||||||
|
.set_row_col(params.scc.components, node as usize, true);
|
||||||
params.scca.push(node);
|
params.scca.push(node);
|
||||||
params.preorders[node as usize] = Preorder::Removed;
|
params.preorders[node as usize] = Preorder::Removed;
|
||||||
if node as usize == v {
|
if node as usize == v {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.scc.push(component);
|
|
||||||
|
params.scc.components += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) struct Sccs {
|
||||||
|
components: usize,
|
||||||
|
matrix: ReferenceMatrix,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sccs {
|
||||||
|
fn components(&self) -> impl Iterator<Item = impl Iterator<Item = usize> + '_> + '_ {
|
||||||
|
// work around a panic when requesting a chunk size of 0
|
||||||
|
let length = if self.matrix.length == 0 {
|
||||||
|
// the `.take(self.components)` ensures the resulting iterator will be empty
|
||||||
|
assert!(self.components == 0);
|
||||||
|
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
self.matrix.length
|
||||||
|
};
|
||||||
|
|
||||||
|
self.matrix
|
||||||
|
.bitvec
|
||||||
|
.chunks(length)
|
||||||
|
.take(self.components)
|
||||||
|
.map(|row| row.iter_ones())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue