Break split function into its own crate.
- Added tests - Remove it from the delegation dir - Added it as a crate in utils
This commit is contained in:
parent
ddc8037487
commit
9717698f7b
@ -37,6 +37,7 @@ members = [
|
||||
"beacon_chain/utils/bls",
|
||||
"beacon_chain/utils/boolean-bitfield",
|
||||
"beacon_chain/utils/hashing",
|
||||
"beacon_chain/utils/honey-badger-split",
|
||||
"beacon_chain/utils/shuffling",
|
||||
"beacon_chain/utils/ssz",
|
||||
"beacon_chain/utils/ssz_helpers",
|
||||
|
@ -4,5 +4,6 @@ version = "0.1.0"
|
||||
authors = ["Age Manning <Age@AgeManning.com>"]
|
||||
|
||||
[dependencies]
|
||||
honey-badger-split = { path = "../utils/honey-badger-split" }
|
||||
types = { path = "../types" }
|
||||
shuffling = { path = "../utils/shuffling" }
|
||||
|
@ -1,3 +1,4 @@
|
||||
use super::honey_badger_split;
|
||||
use super::types;
|
||||
use super::TransitionError;
|
||||
use super::shuffling::shuffle;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use super::honey_badger_split::SplitExt;
|
||||
use super::types::{ShardAndCommittee, ValidatorRecord, ChainConfig};
|
||||
use super::TransitionError;
|
||||
use super::shuffle;
|
||||
@ -5,52 +6,6 @@ use std::cmp::min;
|
||||
|
||||
type DelegatedCycle = Vec<Vec<ShardAndCommittee>>;
|
||||
|
||||
/// Iterator for the honey_badger_split function
|
||||
struct Split<'a, T: 'a> {
|
||||
n: usize,
|
||||
current_pos: usize,
|
||||
list: &'a [T],
|
||||
list_length: usize
|
||||
}
|
||||
|
||||
impl<'a,T> Iterator for Split<'a, T> {
|
||||
type Item = &'a [T];
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.current_pos +=1;
|
||||
if self.current_pos <= self.n {
|
||||
match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
|
||||
Some(v) => Some(v),
|
||||
None => unreachable!()
|
||||
}
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Splits a slice into chunks of size n. All postive n values are applicable,
|
||||
/// hence the honey_badger prefix.
|
||||
/// Returns an iterator over the original list.
|
||||
trait SplitExt<T> {
|
||||
fn honey_badger_split(&self, n: usize) -> Split<T>;
|
||||
}
|
||||
|
||||
impl<T> SplitExt<T> for [T] {
|
||||
|
||||
fn honey_badger_split(&self, n: usize) -> Split<T> {
|
||||
Split {
|
||||
n,
|
||||
current_pos: 0,
|
||||
list: &self,
|
||||
list_length: self.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Produce a vector of validators indicies where those validators start and end
|
||||
/// dynasties are within the supplied `dynasty`.
|
||||
fn active_validator_indicies(
|
||||
|
@ -1,3 +1,4 @@
|
||||
extern crate honey_badger_split;
|
||||
extern crate types;
|
||||
extern crate shuffling;
|
||||
|
||||
|
6
beacon_chain/utils/honey-badger-split/Cargo.toml
Normal file
6
beacon_chain/utils/honey-badger-split/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "honey-badger-split"
|
||||
version = "0.1.0"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
|
||||
[dependencies]
|
85
beacon_chain/utils/honey-badger-split/src/lib.rs
Normal file
85
beacon_chain/utils/honey-badger-split/src/lib.rs
Normal file
@ -0,0 +1,85 @@
|
||||
/// A function for splitting a list into N pieces.
|
||||
///
|
||||
/// We have titled it the "honey badger split" because of its robustness. It don't care.
|
||||
|
||||
|
||||
/// Iterator for the honey_badger_split function
|
||||
pub struct Split<'a, T: 'a> {
|
||||
n: usize,
|
||||
current_pos: usize,
|
||||
list: &'a [T],
|
||||
list_length: usize
|
||||
}
|
||||
|
||||
impl<'a,T> Iterator for Split<'a, T> {
|
||||
type Item = &'a [T];
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.current_pos +=1;
|
||||
if self.current_pos <= self.n {
|
||||
match self.list.get(self.list_length*(self.current_pos-1)/self.n..self.list_length*self.current_pos/self.n) {
|
||||
Some(v) => Some(v),
|
||||
None => unreachable!()
|
||||
}
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Splits a slice into chunks of size n. All postive n values are applicable,
|
||||
/// hence the honey_badger prefix.
|
||||
///
|
||||
/// Returns an iterator over the original list.
|
||||
pub trait SplitExt<T> {
|
||||
fn honey_badger_split(&self, n: usize) -> Split<T>;
|
||||
}
|
||||
|
||||
impl<T> SplitExt<T> for [T] {
|
||||
|
||||
fn honey_badger_split(&self, n: usize) -> Split<T> {
|
||||
Split {
|
||||
n,
|
||||
current_pos: 0,
|
||||
list: &self,
|
||||
list_length: self.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_honey_badger_split() {
|
||||
/*
|
||||
* These test cases are generated from the eth2.0 spec `split()`
|
||||
* function at commit cbd254a.
|
||||
*/
|
||||
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||
let output: Vec<&[usize]> = input.honey_badger_split(2).collect();
|
||||
assert_eq!(output, vec![&[0, 1], &[2, 3]]);
|
||||
|
||||
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||
let output: Vec<&[usize]> = input.honey_badger_split(6).collect();
|
||||
let expected: Vec<&[usize]> = vec![&[], &[0], &[1], &[], &[2], &[3]];
|
||||
assert_eq!(output, expected);
|
||||
|
||||
let input: Vec<usize> = vec![0, 1, 2, 3];
|
||||
let output: Vec<&[usize]> = input.honey_badger_split(10).collect();
|
||||
let expected: Vec<&[usize]> = vec![&[], &[], &[0], &[], &[1], &[], &[], &[2], &[], &[3]];
|
||||
assert_eq!(output, expected);
|
||||
|
||||
let input: Vec<usize> = vec![0];
|
||||
let output: Vec<&[usize]> = input.honey_badger_split(5).collect();
|
||||
let expected: Vec<&[usize]> = vec![&[], &[], &[], &[], &[0]];
|
||||
assert_eq!(output, expected);
|
||||
|
||||
let input: Vec<usize> = vec![0, 1, 2];
|
||||
let output: Vec<&[usize]> = input.honey_badger_split(2).collect();
|
||||
let expected: Vec<&[usize]> = vec![&[0], &[1, 2]];
|
||||
assert_eq!(output, expected);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user