From 103b677d218a3916439d5c966fe5e75b7b110d59 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 28 Mar 2023 15:01:14 +0300 Subject: [PATCH] into_iter() for reader --- lib/src/db.rs | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/lib/src/db.rs b/lib/src/db.rs index d2b5396..73b121b 100644 --- a/lib/src/db.rs +++ b/lib/src/db.rs @@ -226,6 +226,10 @@ where pub fn iter(&self) -> ReaderIter<'_, T> { ReaderIter::new(self) } + + pub fn into_iter(self) -> ReaderIntoIter { + ReaderIntoIter::new(self) + } } pub struct ReaderIter<'a, T> @@ -310,6 +314,100 @@ where } } +pub struct ReaderIntoIter +where + T: bincode::Decode, +{ + reader: Reader, + index: Option, +} + +impl ReaderIntoIter +where + T: bincode::Decode, +{ + fn new(reader: Reader) -> Self { + Self { + reader, + index: None, + } + } +} + +impl Iterator for ReaderIntoIter +where + T: bincode::Decode, +{ + type Item = T; + + fn next(&mut self) -> Option { + if self.index.is_none() && !self.reader.is_empty() { + self.index = Some(0); + } + + match self.index { + Some(i) if i < self.reader.len() => self.nth(i), + _ => None, + } + } + + fn nth(&mut self, n: usize) -> Option { + if self.reader.len() <= n { + return None; + } + self.index = Some(n + 1); + + let item = self.reader.get(n); + match item { + Ok(item) => Some(item), + Err(_) => None, + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.reader.len(); + if self.index.is_none() { + return (len, Some(len)); + } + + let index = self.index.unwrap(); + let rem = if len > index + 1 { + len - (index + 1) + } else { + 0 + }; + (rem, Some(rem)) + } + + fn count(self) -> usize + where + Self: Sized, + { + self.reader.len() + } +} + +impl ExactSizeIterator for ReaderIntoIter +where + T: bincode::Decode, +{ + fn len(&self) -> usize { + self.reader.len() + } +} + +impl IntoIterator for Reader +where + T: bincode::Decode, +{ + type Item = T; + type IntoIter = ReaderIntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.into_iter() + } +} + #[cfg(test)] mod test { use super::*; @@ -380,4 +478,30 @@ mod test { assert_eq!(pair.0, pair.1); }); } + + #[test] + fn test_write_read_into_iter() { + let dir = tempdir().expect("tempdir"); + let tmpfile = dir.path().join("test.tmp"); + let opts = WriterOpts { + compress_lvl: 1, + data_buf_size: 10 * 1024 * 1024, + out_buf_size: 10 * 1024 * 1024, + current_buf_size: 4096, + }; + let mut writer: Writer = Writer::new(&tmpfile, opts).expect("new writer"); + + let items_iter = gen_data(10); + let items: Vec = items_iter.collect(); + + writer.load(&mut items.clone().into_iter()).expect("load"); + writer.finish().expect("finish write"); + + let reader: Reader = Reader::new(&tmpfile, 2048).expect("new reader"); + assert_eq!(items.len(), reader.len()); + + items.into_iter().zip(reader).for_each(|pair| { + assert_eq!(pair.0, pair.1); + }); + } }