Mercurial > lbo > hg > leveldb-rs
changeset 112:c0dbaae40771
Add test verifying behavior for corrupt data; fix TableIterator::reset() behavior
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 24 Dec 2016 14:22:42 +0000 |
parents | 74096ebd4337 |
children | 0d848c6665f5 |
files | src/table_reader.rs |
diffstat | 1 files changed, 57 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/table_reader.rs Sat Dec 24 13:41:32 2016 +0000 +++ b/src/table_reader.rs Sat Dec 24 14:22:42 2016 +0000 @@ -151,13 +151,12 @@ // Iterators read from the file; thus only one iterator can be borrowed (mutably) per scope fn iter<'a>(&'a mut self) -> TableIterator<'a, R, C, FP> { - let mut iter = TableIterator { + let iter = TableIterator { current_block: self.indexblock.iter(), // just for filling in here index_block: self.indexblock.iter(), table: self, init: false, }; - iter.skip_to_next_entry(); iter } } @@ -175,11 +174,11 @@ impl<'a, C: Comparator, R: Read + Seek, FP: FilterPolicy> TableIterator<'a, R, C, FP> { // Skips to the entry referenced by the next entry in the index block. // This is called once a block has run out of entries. - fn skip_to_next_entry(&mut self) -> bool { + fn skip_to_next_entry(&mut self) -> Result<bool> { if let Some((_key, val)) = self.index_block.next() { - self.load_block(&val).is_ok() + self.load_block(&val).map(|_| true) } else { - false + Ok(false) } } @@ -198,11 +197,17 @@ type Item = (Vec<u8>, Vec<u8>); fn next(&mut self) -> Option<Self::Item> { - self.init = true; + if !self.init { + self.init = true; + if self.skip_to_next_entry().is_err() { + return None; + } + } + if let Some((key, val)) = self.current_block.next() { Some((key, val)) } else { - if self.skip_to_next_entry() { + if self.skip_to_next_entry().unwrap_or(false) { self.next() } else { None @@ -269,7 +274,6 @@ fn reset(&mut self) { self.index_block.reset(); self.init = false; - self.skip_to_next_entry(); } // This iterator is special in that it's valid even before the first call to next(). It behaves @@ -279,7 +283,11 @@ } fn current(&self) -> Option<Self::Item> { - self.current_block.current() + if self.init { + self.current_block.current() + } else { + None + } } } @@ -309,7 +317,7 @@ let mut d = Vec::with_capacity(512); let mut opt = Options::default(); opt.block_restart_interval = 2; - opt.block_size = 64; + opt.block_size = 32; { let mut b = TableBuilder::new(opt, StandardComparator, &mut d, BloomPolicy::new(4)); @@ -328,6 +336,40 @@ } #[test] + fn test_table_reader_checksum() { + let (mut src, size) = build_table(); + println!("{}", size); + + src[45] = 0; + + let mut table = Table::new(Cursor::new(&src as &[u8]), + size, + StandardComparator, + BloomPolicy::new(4), + Options::default()) + .unwrap(); + + { + let iter = table.iter(); + // Last block is skipped + assert_eq!(iter.count(), 3); + + } + + { + let iter = table.iter(); + + for (k, _) in iter { + if k == build_data()[2].0.as_bytes() { + return; + } + } + + panic!("Should have hit 3rd record in table!"); + } + } + + #[test] fn test_table_iterator_fwd() { let (src, size) = build_table(); let data = build_data(); @@ -346,6 +388,9 @@ (k.as_ref(), v.as_ref())); i += 1; } + + assert_eq!(i, data.len()); + println!("tot len: {}", data.len()); } #[test] @@ -367,6 +412,7 @@ assert!(iter.current().is_none()); assert!(iter.next().is_some()); + let first = iter.current(); assert!(iter.valid()); assert!(iter.current().is_some()); @@ -377,6 +423,7 @@ iter.reset(); assert!(!iter.valid()); assert!(iter.current().is_none()); + assert_eq!(first, iter.next()); } #[test]