This commit is contained in:
Rob Walker 2018-07-11 10:30:07 -07:00
parent a219e78f00
commit 705720f086
1 changed files with 37 additions and 60 deletions

View File

@ -33,13 +33,6 @@ pub const MAX_ENTRY_IDS: usize = 1024 * 16;
pub const VERIFY_BLOCK_SIZE: usize = 16; pub const VERIFY_BLOCK_SIZE: usize = 16;
fn rotate_vector<T: Clone>(v: Vec<T>, at: usize) -> Vec<T> {
let mut ret = Vec::with_capacity(v.len());
ret.extend_from_slice(&v[at..]);
ret.extend_from_slice(&v[0..at]);
ret
}
/// Reasons a transaction might be rejected. /// Reasons a transaction might be rejected.
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum BankError { pub enum BankError {
@ -324,8 +317,21 @@ impl Bank {
res res
} }
/// Process an ordered list of entries. fn process_entry(&self, entry: Entry) -> Result<()> {
pub fn process_entries_tail( if !entry.transactions.is_empty() {
for result in self.process_transactions(entry.transactions) {
result?;
}
}
if !entry.has_more {
self.register_entry_id(&entry.id);
}
Ok(())
}
/// Process an ordered list of entries, populating a circular buffer "tail"
/// as we go.
fn process_entries_tail(
&self, &self,
entries: Vec<Entry>, entries: Vec<Entry>,
tail: &mut Vec<Entry>, tail: &mut Vec<Entry>,
@ -334,8 +340,6 @@ impl Bank {
let mut entry_count = 0; let mut entry_count = 0;
for entry in entries { for entry in entries {
entry_count += 1;
if tail.len() > *tail_idx { if tail.len() > *tail_idx {
tail[*tail_idx] = entry.clone(); tail[*tail_idx] = entry.clone();
} else { } else {
@ -343,14 +347,8 @@ impl Bank {
} }
*tail_idx = (*tail_idx + 1) % WINDOW_SIZE as usize; *tail_idx = (*tail_idx + 1) % WINDOW_SIZE as usize;
if !entry.transactions.is_empty() { entry_count += 1;
for result in self.process_transactions(entry.transactions) { self.process_entry(entry)?;
result?;
}
}
if !entry.has_more {
self.register_entry_id(&entry.id);
}
} }
Ok(entry_count) Ok(entry_count)
@ -361,21 +359,13 @@ impl Bank {
let mut entry_count = 0; let mut entry_count = 0;
for entry in entries { for entry in entries {
entry_count += 1; entry_count += 1;
self.process_entry(entry)?;
if !entry.transactions.is_empty() {
for result in self.process_transactions(entry.transactions) {
result?;
}
}
if !entry.has_more {
self.register_entry_id(&entry.id);
}
} }
Ok(entry_count) Ok(entry_count)
} }
/// Append entry blocks to the ledger, verifying them along the way. /// Append entry blocks to the ledger, verifying them along the way.
pub fn process_blocks<I>( fn process_blocks<I>(
&self, &self,
entries: I, entries: I,
tail: &mut Vec<Entry>, tail: &mut Vec<Entry>,
@ -433,8 +423,8 @@ impl Bank {
let mut tail_idx = 2; let mut tail_idx = 2;
let entry_count = 2 + self.process_blocks(entries, &mut tail, &mut tail_idx)?; let entry_count = 2 + self.process_blocks(entries, &mut tail, &mut tail_idx)?;
// check if we need to shift tail around // check f we need to rotate tail
let tail = if tail.len() == WINDOW_SIZE as usize && tail_idx != 0 { let tail = if tail.len() == WINDOW_SIZE as usize {
rotate_vector(tail, tail_idx) rotate_vector(tail, tail_idx)
} else { } else {
tail tail
@ -541,6 +531,17 @@ impl Bank {
} }
} }
fn rotate_vector<T: Clone>(v: Vec<T>, at: usize) -> Vec<T> {
if at != 0 {
let mut ret = Vec::with_capacity(v.len());
ret.extend_from_slice(&v[at..]);
ret.extend_from_slice(&v[0..at]);
ret
} else {
v
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -827,7 +828,6 @@ mod tests {
let window_size = WINDOW_SIZE as usize; let window_size = WINDOW_SIZE as usize;
for entry_count in window_size - 3..window_size + 2 { for entry_count in window_size - 3..window_size + 2 {
eprintln!("entry_count {}", entry_count);
let (ledger, pubkey) = create_sample_ledger(entry_count); let (ledger, pubkey) = create_sample_ledger(entry_count);
let bank = Bank::default(); let bank = Bank::default();
let (ledger_height, tail) = bank.process_ledger(ledger).unwrap(); let (ledger_height, tail) = bank.process_ledger(ledger).unwrap();
@ -872,35 +872,12 @@ mod tests {
#[test] #[test]
fn test_rotate_vector() { fn test_rotate_vector() {
let test = vec![4, 1, 2, 3]; let expect = vec![1, 2, 3, 4];
let etest = vec![4, 1, 2, 3];
let (left, right) = etest.split_at(1); assert_eq!(rotate_vector(vec![4, 1, 2, 3], 1), expect);
let mut right = right.to_vec(); assert_eq!(rotate_vector(vec![1, 2, 3, 4], 0), expect);
right.extend(left); assert_eq!(rotate_vector(vec![2, 3, 4, 1], 3), expect);
assert_eq!(rotate_vector(vec![3, 4, 1, 2], 2), expect);
assert_eq!(rotate_vector(test, 1), right);
// TODO: put me back in when Criterion is up
//let now = Instant::now();
//for _ in 0..100_000 {
// let etest = vec![4, 1, 2, 3];
// let (left, right) = etest.split_at(1);
// let mut right = right.to_vec();
// right.extend(left);
//}
//eprintln!("split_at {}", duration_as_us(&now.elapsed()));
//
//let now = Instant::now();
//for _ in 0..100_000 {
// let test = vec![4, 1, 2, 3];
// rotate_vector(test, 1);
//}
//eprintln!("rotate {}", duration_as_us(&now.elapsed()));
// expected ratio:
// split_at 97145
// rotate 70582
} }
} }