Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Avgor46 committed Aug 2, 2023
1 parent fcda39d commit af35d26
Showing 1 changed file with 42 additions and 48 deletions.
90 changes: 42 additions & 48 deletions libcasr/src/stacktrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,35 +287,23 @@ impl Filter for Stacktrace {
self.drain(pos + 1..);
}

// Find repeating intervals in stacktrace
// We need to create an element that will not be equal to others
let mut intervals = get_interval_repetitions(self);
intervals.sort_by(|x, y| x.0.cmp(&y.0));
let ilen = intervals.len();
let mut cur = (0, ilen);
let mut intervals = intervals.into_iter();

// Remove repeating intervals and trusted functions from stack trace
// Remove trusted functions from stack trace
*self = std::mem::take(self)
.into_iter()
.enumerate()
.filter(|(idx, _)| {
if *idx < cur.0 {
true
} else if cur.1 != ilen && *idx < cur.1 + 1 {
false
} else {
if let Some(interval) = intervals.next() {
cur = interval;
}
true
}
})
.map(|(_, entry)| entry)
.filter(|entry| (entry.function.is_empty() || !rfunction.is_match(&entry.function)))
.filter(|entry| (entry.module.is_empty() || !rfile.is_match(&entry.module)))
.filter(|entry| (entry.debug.file.is_empty() || !rfile.is_match(&entry.debug.file)))
.collect();
// Find repeating intervals in stacktrace
let mut vec = get_interval_repetitions(self);
while vec.iter().any(|el| !el) {
let mut keep = vec.iter();
*self = std::mem::take(self)
.into_iter()
.filter(|_| *keep.next().unwrap())
.collect();
vec = get_interval_repetitions(self);
}
}
}

Expand All @@ -327,9 +315,9 @@ impl Filter for Stacktrace {
///
/// # Return value
///
/// Resulting vector with repeating intervals: (start index, end index)
/// Start and end indices are included
fn get_interval_repetitions<T: PartialEq>(arr: &[T]) -> Vec<(usize, usize)> {
/// An vector of the same length as `arr`.
/// Vec\[i\] is false, if original element i is a duplicate in some loop.
fn get_interval_repetitions<T: PartialEq>(arr: &[T]) -> Vec<bool> {
let len = arr.len();
let mut indices = Vec::new();
indices.resize(len, true);
Expand All @@ -352,22 +340,7 @@ fn get_interval_repetitions<T: PartialEq>(arr: &[T]) -> Vec<(usize, usize)> {
(start..len - (len - start) % i - i).for_each(|index| indices[index] = false);
}
}
let mut intervals = Vec::new();
let mut start = len;
indices.iter().enumerate().for_each(|(idx, el)| {
if !*el {
if start == len {
start = idx;
}
} else if start != len {
intervals.push((start, idx - 1));
start = len;
}
});
if start != len {
intervals.push((start, len - 1));
}
intervals
indices
}

#[cfg(test)]
Expand All @@ -387,25 +360,46 @@ mod tests {
.iter()
.map(|x| x.chars().collect::<Vec<char>>())
.collect::<Vec<_>>();
let answer = get_interval_repetitions(&tests[0]);

fn convert_answer(indices: &[bool]) -> Vec<(usize, usize)> {
let mut intervals = Vec::new();
let len = indices.len();
let mut start = len;
indices.iter().enumerate().for_each(|(idx, el)| {
if !*el {
if start == len {
start = idx;
}
} else if start != len {
intervals.push((start, idx - 1));
start = len;
}
});
if start != len {
intervals.push((start, len - 1));
}
intervals
}

let answer = convert_answer(&get_interval_repetitions(&tests[0]));
assert!(answer.contains(&(0, 0)));

let answer = get_interval_repetitions(&tests[1]);
let answer = convert_answer(&get_interval_repetitions(&tests[1]));
assert!(answer.contains(&(0, 3)));

let answer = get_interval_repetitions(&tests[2]);
let answer = convert_answer(&get_interval_repetitions(&tests[2]));
assert!(answer.contains(&(0, 4)));

let answer = get_interval_repetitions(&tests[3]);
let answer = convert_answer(&get_interval_repetitions(&tests[3]));
assert!(answer.contains(&(0, 5)));
assert!(answer.contains(&(11, 11)));
assert!(answer.contains(&(13, 18)));

let answer = get_interval_repetitions(&tests[4]);
let answer = convert_answer(&get_interval_repetitions(&tests[4]));
assert!(answer.contains(&(2, 7)));
assert!(answer.contains(&(9, 9)));

let answer = get_interval_repetitions(&tests[5]);
let answer = convert_answer(&get_interval_repetitions(&tests[5]));
assert!(answer.contains(&(0, 9)));
}
}

0 comments on commit af35d26

Please sign in to comment.