Skip to content

Commit

Permalink
Enforce the repair timeout when collecting repairs.
Browse files Browse the repository at this point in the history
For some reason, it didn't occur to me that collecting repairs can take
a very, very long time: it's possible for this to take so long that it
exceeds any reasonable memory limit. Foolishly, I *had* realised that
`rank_rprs` needed a timeout, but I hadn't applied that to
`collect_repairs`. This commit does that, ensuring that the user's input
is less likely to cause grmtools to consume too much memory.
  • Loading branch information
ltratt committed Jan 3, 2025
1 parent 8482641 commit 9cab8a3
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions lrpar/src/lib/cpctplus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ where
return (in_laidx, vec![]);
}

let full_rprs = self.collect_repairs(in_laidx, astar_cnds);
let Some(full_rprs) = self.collect_repairs(finish_by, in_laidx, astar_cnds) else {
return (in_laidx, vec![]);
};
let mut rnk_rprs = rank_cnds(parser, finish_by, in_laidx, in_pstack, full_rprs);
if rnk_rprs.is_empty() {
return (in_laidx, vec![]);
Expand Down Expand Up @@ -372,19 +374,25 @@ where
}
}

/// Convert the output from `astar_all` into something more usable.
/// Convert the output from `astar_all` into something more usable. Returns `None` if it timed
/// out while doing so.
fn collect_repairs(
&self,
finish_by: Instant,
in_laidx: usize,
cnds: Vec<PathFNode<StorageT>>,
) -> Vec<Vec<Vec<ParseRepair<LexerTypesT::LexemeT, StorageT>>>> {
) -> Option<Vec<Vec<Vec<ParseRepair<LexerTypesT::LexemeT, StorageT>>>>> {
fn traverse<StorageT: PrimInt>(
finish_by: Instant,
rm: &Cactus<RepairMerge<StorageT>>,
) -> Vec<Vec<Repair<StorageT>>> {
) -> Option<Vec<Vec<Repair<StorageT>>>> {
if Instant::now() >= finish_by {
return None;
}
let mut out = Vec::new();
match *rm.val().unwrap() {
RepairMerge::Repair(r) => {
let parents = traverse(&rm.parent().unwrap());
let parents = traverse(finish_by, &rm.parent().unwrap())?;
if parents.is_empty() {
out.push(vec![r]);
} else {
Expand All @@ -395,7 +403,7 @@ where
}
}
RepairMerge::Merge(r, ref vc) => {
let parents = traverse(&rm.parent().unwrap());
let parents = traverse(finish_by, &rm.parent().unwrap())?;
if parents.is_empty() {
out.push(vec![r]);
} else {
Expand All @@ -405,26 +413,26 @@ where
}
}
for c in vc.vals() {
for pc in traverse(c) {
for pc in traverse(finish_by, c)? {
out.push(pc);
}
}
}
RepairMerge::Terminator => (),
}
out
Some(out)
}

let mut all_rprs = Vec::with_capacity(cnds.len());
for cnd in cnds {
all_rprs.push(
traverse(&cnd.repairs)
traverse(finish_by, &cnd.repairs)?
.into_iter()
.map(|x| self.repair_to_parse_repair(in_laidx, &x))
.collect::<Vec<_>>(),
);
}
all_rprs
Some(all_rprs)
}

fn repair_to_parse_repair(
Expand Down

0 comments on commit 9cab8a3

Please sign in to comment.