Rename has_output to decided, add output iterator.

This commit is contained in:
Andreas Fackler 2018-05-15 16:05:55 +02:00
parent 3895949cf6
commit b8c534da2b
3 changed files with 28 additions and 7 deletions

View File

@ -100,7 +100,7 @@ pub struct Broadcast<N> {
/// Whether we have already multicast `Ready`.
ready_sent: bool,
/// Whether we have already output a value.
has_output: bool,
decided: bool,
/// The proofs we have received via `Echo` messages, by sender ID.
echos: BTreeMap<N, Proof<Vec<u8>>>,
/// The root hashes we received via `Ready` messages, by sender ID.
@ -154,7 +154,7 @@ impl<N: Eq + Debug + Clone + Ord> DistAlgorithm for Broadcast<N> {
}
fn terminated(&self) -> bool {
self.has_output
self.decided
}
fn our_id(&self) -> &N {
@ -182,7 +182,7 @@ impl<N: Eq + Debug + Clone + Ord> Broadcast<N> {
coding,
echo_sent: false,
ready_sent: false,
has_output: false,
decided: false,
echos: BTreeMap::new(),
readys: BTreeMap::new(),
messages: VecDeque::new(),
@ -351,14 +351,14 @@ impl<N: Eq + Debug + Clone + Ord> Broadcast<N> {
/// Checks whether the condition for output are met for this hash, and if so, sets the output
/// value.
fn compute_output(&mut self, hash: &[u8]) -> Result<(), Error> {
if self.has_output || self.count_readys(hash) <= 2 * self.num_faulty_nodes
if self.decided || self.count_readys(hash) <= 2 * self.num_faulty_nodes
|| self.count_echos(hash) <= self.num_faulty_nodes
{
return Ok(());
}
// Upon receiving 2f + 1 matching Ready(h) messages, wait for N 2f Echo messages.
self.has_output = true;
self.decided = true;
let mut leaf_values: Vec<Option<Box<[u8]>>> = self.all_uids
.iter()
.map(|id| {

View File

@ -89,6 +89,14 @@ pub trait DistAlgorithm {
{
MessageIter { algorithm: self }
}
/// Returns an iterator over the algorithm's outputs.
fn output_iter(&mut self) -> OutputIter<Self>
where
Self: Sized,
{
OutputIter { algorithm: self }
}
}
/// An iterator over a distributed algorithm's outgoing messages.
@ -103,3 +111,16 @@ impl<'a, D: DistAlgorithm + 'a> Iterator for MessageIter<'a, D> {
self.algorithm.next_message()
}
}
/// An iterator over a distributed algorithm's pending outputs.
pub struct OutputIter<'a, D: DistAlgorithm + 'a> {
algorithm: &'a mut D,
}
impl<'a, D: DistAlgorithm + 'a> Iterator for OutputIter<'a, D> {
type Item = D::Output;
fn next(&mut self) -> Option<Self::Item> {
self.algorithm.next_output()
}
}

View File

@ -49,13 +49,13 @@ impl<D: DistAlgorithm> TestNode<D> {
self.algo
.handle_message(&from_id, msg)
.expect("handling message");
self.outputs.extend(self.algo.next_output());
self.outputs.extend(self.algo.output_iter());
}
/// Inputs a value into the instance.
fn input(&mut self, input: D::Input) {
self.algo.input(input).expect("input");
self.outputs.extend(self.algo.next_output());
self.outputs.extend(self.algo.output_iter());
}
}