Mercurial > lbo > hg > leveldb-rs
changeset 339:9a6168d73c2e
table_reader: Invalidate iterator on bad seek.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 04 Oct 2017 19:20:16 +0200 |
parents | 5c5348656269 |
children | 801af25e9abd |
files | src/table_reader.rs |
diffstat | 1 files changed, 17 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/table_reader.rs Tue Oct 03 22:03:40 2017 +0200 +++ b/src/table_reader.rs Wed Oct 04 19:20:16 2017 +0200 @@ -327,21 +327,19 @@ // then set current_block and seek there self.index_block.seek(to); - let (past_block, handle) = current_key_val(&self.index_block) - .expect("current() on index block should return value"); - if self.table.opt.cmp.cmp(to, &past_block) <= Ordering::Equal { - // ok, found right block: continue - if let Ok(()) = self.load_block(&handle) { - // current_block is always set if load_block() returned Ok. - self.current_block.as_mut().unwrap().seek(to); - } else { - self.reset(); - return; + // It's possible that this is a seek past-last; reset in that case. + if let Some((past_block, handle)) = current_key_val(&self.index_block) { + if self.table.opt.cmp.cmp(to, &past_block) <= Ordering::Equal { + // ok, found right block: continue + if let Ok(()) = self.load_block(&handle) { + // current_block is always set if load_block() returned Ok. + self.current_block.as_mut().unwrap().seek(to); + return; + } } - } else { - self.reset(); - return; } + // Reached in case of failure. + self.reset(); } fn prev(&mut self) -> bool { @@ -669,6 +667,12 @@ assert!(iter.valid()); assert_eq!(current_key_val(&iter), Some(("abc".as_bytes().to_vec(), "def".as_bytes().to_vec()))); + + // Seek-past-last invalidates. + iter.seek("{{{".as_bytes()); + assert!(!iter.valid()); + iter.seek("bbb".as_bytes()); + assert!(iter.valid()); } #[test]