into_iter() for reader
This commit is contained in:
		
							
								
								
									
										124
									
								
								lib/src/db.rs
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								lib/src/db.rs
									
									
									
									
									
								
							@@ -226,6 +226,10 @@ where
 | 
			
		||||
    pub fn iter(&self) -> ReaderIter<'_, T> {
 | 
			
		||||
        ReaderIter::new(self)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn into_iter(self) -> ReaderIntoIter<T> {
 | 
			
		||||
        ReaderIntoIter::new(self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct ReaderIter<'a, T>
 | 
			
		||||
@@ -310,6 +314,100 @@ where
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct ReaderIntoIter<T>
 | 
			
		||||
where
 | 
			
		||||
    T: bincode::Decode,
 | 
			
		||||
{
 | 
			
		||||
    reader: Reader<T>,
 | 
			
		||||
    index: Option<usize>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> ReaderIntoIter<T>
 | 
			
		||||
where
 | 
			
		||||
    T: bincode::Decode,
 | 
			
		||||
{
 | 
			
		||||
    fn new(reader: Reader<T>) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            reader,
 | 
			
		||||
            index: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> Iterator for ReaderIntoIter<T>
 | 
			
		||||
where
 | 
			
		||||
    T: bincode::Decode,
 | 
			
		||||
{
 | 
			
		||||
    type Item = T;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        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<Self::Item> {
 | 
			
		||||
        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<usize>) {
 | 
			
		||||
        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<T> ExactSizeIterator for ReaderIntoIter<T>
 | 
			
		||||
where
 | 
			
		||||
    T: bincode::Decode,
 | 
			
		||||
{
 | 
			
		||||
    fn len(&self) -> usize {
 | 
			
		||||
        self.reader.len()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T> IntoIterator for Reader<T> 
 | 
			
		||||
where
 | 
			
		||||
    T: bincode::Decode,
 | 
			
		||||
{
 | 
			
		||||
    type Item = T;
 | 
			
		||||
    type IntoIter = ReaderIntoIter<Self::Item>;
 | 
			
		||||
 | 
			
		||||
    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<TestData> = Writer::new(&tmpfile, opts).expect("new writer");
 | 
			
		||||
 | 
			
		||||
        let items_iter = gen_data(10);
 | 
			
		||||
        let items: Vec<TestData> = items_iter.collect();
 | 
			
		||||
 | 
			
		||||
        writer.load(&mut items.clone().into_iter()).expect("load");
 | 
			
		||||
        writer.finish().expect("finish write");
 | 
			
		||||
 | 
			
		||||
        let reader: Reader<TestData> = 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);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user