use crate::LUInt;
pub(crate) fn dfs(
i: usize,
begin: &[LUInt],
end: Option<&[LUInt]>,
index: &[LUInt],
top: usize,
xi: &mut [LUInt],
pstack: &mut [f64],
marked: &mut [LUInt],
m: LUInt,
) -> usize {
if marked[i as usize] == m as LUInt {
return top;
}
if let Some(end) = end {
dfs_end(i, begin, end, index, top, xi, pstack, marked, m)
} else {
dfs_begin(i, begin, index, top, xi, pstack, marked, m)
}
}
fn dfs_end(
mut i: usize,
begin: &[LUInt],
end: &[LUInt],
index: &[LUInt],
mut top: usize,
xi: &mut [LUInt],
pstack: &mut [f64],
marked: &mut [LUInt],
m: LUInt,
) -> usize {
let mut head: LUInt = 0;
assert_ne!(marked[i as usize], m as LUInt);
xi[0] = i as LUInt;
while head >= 0 {
i = xi[head as usize] as usize;
if marked[i] != m {
marked[i] = m;
pstack[head as usize] = begin[i] as f64;
}
let mut done = 1;
for p in (pstack[head as usize] as LUInt)..end[i] {
let inext = index[p as usize];
if marked[inext as usize] == m {
continue; }
pstack[head as usize] = (p + 1) as f64;
head += 1;
xi[head as usize] = inext; done = 0;
break;
}
if done != 0 {
head -= 1;
top -= 1;
xi[top] = i as LUInt;
}
}
top
}
fn dfs_begin(
mut i: usize,
begin: &[LUInt],
index: &[LUInt],
mut top: usize,
xi: &mut [LUInt],
pstack: &mut [f64],
marked: &mut [LUInt],
m: LUInt,
) -> usize {
let mut head: LUInt = 0;
assert_ne!(marked[i as usize], m as LUInt);
xi[0] = i as LUInt;
while head >= 0 {
i = xi[head as usize] as usize;
if marked[i] != m {
marked[i] = m;
pstack[head as usize] = begin[i] as f64;
}
let mut done = 1;
let mut p = pstack[head as usize] as LUInt;
while index[p as usize] >= 0 {
let inext = index[p as usize];
if marked[inext as usize] == m {
p += 1; continue; }
pstack[head as usize] = (p + 1) as f64;
head += 1;
xi[head as usize] = inext; done = 0;
break;
}
if done != 0 {
head -= 1;
top -= 1;
xi[top] = i as LUInt;
}
}
top
}