diff --git a/src/stackvec.rs b/src/stackvec.rs new file mode 100644 index 0000000..13b12ee --- /dev/null +++ b/src/stackvec.rs @@ -0,0 +1,91 @@ +use std::io; + +pub struct StackVec<'a, T: 'a> { + data: &'a mut [T], + length: usize, +} + +impl<'a, T> StackVec<'a, T> { + pub fn from(data: &mut [T]) -> StackVec { + StackVec{ + data, + length: 0, + } + } +} + +impl<'a, T> StackVec<'a, T> { + pub fn len(&self) -> usize { + self.length + } +} + +impl<'a> io::Write for StackVec<'a, u8> { + fn write(&mut self, buf: &[u8]) -> io::Result { + if buf.len() > (self.data.len() - self.length) { + // not enough space on buffer. + return Err(io::Error::from(io::ErrorKind::WriteZero)); + } + let mut writable = &mut self.data[self.length..][0..buf.len()]; + writable.copy_from_slice(buf); + self.length += buf.len(); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn vec_write() { + use std::io::Write; + + let mut buf = [0u8; 200]; + { + let mut vec = StackVec::from(&mut buf); + assert!(vec.write("Hello World!".as_bytes()).is_ok()); + } + assert_eq!(buf[1] as char, 'e'); + } + + fn add_values(vec: &mut T) { + for i in 0..BUF_LEN { + assert!(vec.write(&[((i % 256) & 0xff) as u8]).is_ok()); + } + } + + use test::Bencher; + + const BUF_LEN : usize = 1024 * 1024 * 1; // 10MB + + #[bench] + fn vec_stack(bencher: &mut Bencher) { + bencher.iter(|| { + let mut buff = [0u8; BUF_LEN]; + let mut v = StackVec::from(&mut buff); + add_values(&mut v); + }); + } + + #[bench] + fn vec_heap(bencher: &mut Bencher) { + bencher.iter(|| { + let mut v = Vec::new(); + + add_values(&mut v); + }); + } + + #[bench] + fn vec_heap_cap(bencher: &mut Bencher) { + bencher.iter(|| { + let mut v = Vec::with_capacity(BUF_LEN); + add_values(&mut v); + }); + } +} \ No newline at end of file