Skip to content

Commit c2f6207

Browse files
committed
refactor(bisect): pass Bounds to Strategy::midpoint
I forgot that we have a container type for the success+failure bounds, so use that here.
1 parent 2a4e363 commit c2f6207

File tree

3 files changed

+42
-41
lines changed

3 files changed

+42
-41
lines changed

scm-bisect/examples/guessing_game.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::cmp::Ordering;
2-
use std::collections::HashSet;
32
use std::convert::Infallible;
43
use std::io;
54
use std::ops::RangeInclusive;
@@ -38,10 +37,13 @@ impl search::Strategy<Graph> for Strategy {
3837
fn midpoint(
3938
&self,
4039
_graph: &Graph,
41-
success_bounds: &HashSet<Node>,
42-
failure_bounds: &HashSet<Node>,
40+
bounds: &search::Bounds<Node>,
4341
_statuses: &IndexMap<Node, search::Status>,
4442
) -> Result<Option<Node>, Self::Error> {
43+
let search::Bounds {
44+
success: success_bounds,
45+
failure: failure_bounds,
46+
} = bounds;
4547
let lower_bound = success_bounds
4648
.iter()
4749
.max()

scm-bisect/src/basic.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,13 @@ impl<G: BasicSourceControlGraph> search::Strategy<G> for BasicStrategy {
198198
fn midpoint(
199199
&self,
200200
graph: &G,
201-
success_bounds: &HashSet<G::Node>,
202-
failure_bounds: &HashSet<G::Node>,
201+
bounds: &search::Bounds<G::Node>,
203202
statuses: &IndexMap<G::Node, search::Status>,
204203
) -> Result<Option<G::Node>, G::Error> {
204+
let search::Bounds {
205+
success: success_bounds,
206+
failure: failure_bounds,
207+
} = bounds;
205208
let mut nodes_to_search = {
206209
let implied_success_nodes = graph.ancestors_all(success_bounds.clone())?;
207210
let implied_failure_nodes = graph.descendants_all(failure_bounds.clone())?;

scm-bisect/src/search.rs

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ pub trait Strategy<G: Graph>: Debug {
121121
fn midpoint(
122122
&self,
123123
graph: &G,
124-
success_bounds: &HashSet<G::Node>,
125-
failure_bounds: &HashSet<G::Node>,
124+
bounds: &Bounds<G::Node>,
126125
statuses: &IndexMap<G::Node, Status>,
127126
) -> Result<Option<G::Node>, Self::Error>;
128127
}
@@ -274,8 +273,7 @@ impl<G: Graph> Search<G> {
274273

275274
#[derive(Debug)]
276275
struct State<G: Graph> {
277-
success_bounds: HashSet<G::Node>,
278-
failure_bounds: HashSet<G::Node>,
276+
bounds: Bounds<G::Node>,
279277
statuses: IndexMap<G::Node, Status>,
280278
}
281279

@@ -292,24 +290,16 @@ impl<G: Graph> Search<G> {
292290
fn next(&mut self) -> Option<Self::Item> {
293291
while let Some(state) = self.states.pop_front() {
294292
debug!(?state, "Popped speculation state");
295-
let State {
296-
success_bounds,
297-
failure_bounds,
298-
statuses,
299-
} = state;
300-
301-
let node = match self.strategy.midpoint(
302-
self.graph,
303-
&success_bounds,
304-
&failure_bounds,
305-
&statuses,
306-
) {
293+
let State { bounds, statuses } = state;
294+
295+
let node = match self.strategy.midpoint(self.graph, &bounds, &statuses) {
307296
Ok(Some(node)) => node,
308297
Ok(None) => continue,
309298
Err(err) => return Some(Err(SearchError::Strategy(err))),
310299
};
311300

312-
for success_node in success_bounds.iter() {
301+
let Bounds { success, failure } = bounds;
302+
for success_node in success.iter() {
313303
match self.graph.is_ancestor(node.clone(), success_node.clone()) {
314304
Ok(true) => {
315305
return Some(Err(SearchError::AlreadySearchedMidpoint {
@@ -321,7 +311,7 @@ impl<G: Graph> Search<G> {
321311
Err(err) => return Some(Err(SearchError::Graph(err))),
322312
}
323313
}
324-
for failure_node in failure_bounds.iter() {
314+
for failure_node in failure.iter() {
325315
match self.graph.is_ancestor(failure_node.clone(), node.clone()) {
326316
Ok(true) => {
327317
return Some(Err(SearchError::AlreadySearchedMidpoint {
@@ -336,14 +326,16 @@ impl<G: Graph> Search<G> {
336326

337327
// Speculate failure:
338328
self.states.push_back(State {
339-
success_bounds: success_bounds.clone(),
340-
failure_bounds: {
341-
let mut failure_bounds = failure_bounds.clone();
342-
failure_bounds.insert(node.clone());
343-
match self.graph.simplify_failure_bounds(failure_bounds) {
344-
Ok(bounds) => bounds,
345-
Err(err) => return Some(Err(SearchError::Graph(err))),
346-
}
329+
bounds: Bounds {
330+
success: success.clone(),
331+
failure: {
332+
let mut failure_bounds = failure.clone();
333+
failure_bounds.insert(node.clone());
334+
match self.graph.simplify_failure_bounds(failure_bounds) {
335+
Ok(bounds) => bounds,
336+
Err(err) => return Some(Err(SearchError::Graph(err))),
337+
}
338+
},
347339
},
348340
statuses: {
349341
let mut statuses = statuses.clone();
@@ -354,15 +346,17 @@ impl<G: Graph> Search<G> {
354346

355347
// Speculate success:
356348
self.states.push_back(State {
357-
success_bounds: {
358-
let mut success_bounds = success_bounds.clone();
359-
success_bounds.insert(node.clone());
360-
match self.graph.simplify_success_bounds(success_bounds) {
361-
Ok(bounds) => bounds,
362-
Err(err) => return Some(Err(SearchError::Graph(err))),
363-
}
349+
bounds: Bounds {
350+
success: {
351+
let mut success_bounds = success.clone();
352+
success_bounds.insert(node.clone());
353+
match self.graph.simplify_success_bounds(success_bounds) {
354+
Ok(bounds) => bounds,
355+
Err(err) => return Some(Err(SearchError::Graph(err))),
356+
}
357+
},
358+
failure: failure.clone(),
364359
},
365-
failure_bounds: failure_bounds.clone(),
366360
statuses: {
367361
let mut statuses = statuses.clone();
368362
statuses.insert(node.clone(), Status::Success);
@@ -379,8 +373,10 @@ impl<G: Graph> Search<G> {
379373
}
380374

381375
let initial_state = State {
382-
success_bounds: success_bounds.clone(),
383-
failure_bounds: failure_bounds.clone(),
376+
bounds: Bounds {
377+
success: success_bounds.clone(),
378+
failure: failure_bounds.clone(),
379+
},
384380
statuses: self.nodes.clone(),
385381
};
386382
let iter = Iter {

0 commit comments

Comments
 (0)