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]