changeset 343:df206c176f83

version: Make find_file() return an Option, and invalidate iterator on bad seek.
author Lewin Bormann <lbo@spheniscida.de>
date Wed, 04 Oct 2017 20:02:45 +0200
parents b9cb08d20191
children 4f4aff8085b8
files src/version.rs
diffstat 1 files changed, 22 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.rs	Wed Oct 04 20:02:20 2017 +0200
+++ b/src/version.rs	Wed Oct 04 20:02:45 2017 +0200
@@ -104,8 +104,7 @@
         let icmp = InternalKeyCmp(self.user_cmp.clone());
         for level in 1..NUM_LEVELS {
             let files = &self.files[level];
-            let ix = find_file(&icmp, files, ikey);
-            if ix < files.len() {
+            if let Some(ix) = find_file(&icmp, files, ikey) {
                 let f = files[ix].borrow();
                 let fsmallest = parse_internal_key(&f.smallest).2;
                 if self.user_cmp.cmp(ukey, fsmallest) >= Ordering::Equal {
@@ -398,15 +397,15 @@
         }
     }
     fn seek(&mut self, key: &[u8]) {
-        let ix = find_file(&self.cmp, &self.files, key);
-        assert!(ix < self.files.len());
-        if let Ok(tbl) = self.cache.borrow_mut().get_table(self.files[ix].borrow().num) {
-            let mut iter = tbl.iter();
-            iter.seek(key);
-            if iter.valid() {
-                self.current_ix = ix;
-                self.current = Some(iter);
-                return;
+        if let Some(ix) = find_file(&self.cmp, &self.files, key) {
+            if let Ok(tbl) = self.cache.borrow_mut().get_table(self.files[ix].borrow().num) {
+                let mut iter = tbl.iter();
+                iter.seek(key);
+                if iter.valid() {
+                    self.current_ix = ix;
+                    self.current = Some(iter);
+                    return;
+                }
             }
         }
         self.reset();
@@ -461,8 +460,12 @@
 }
 
 /// find_file returns the index of the file in files that potentially contains the internal key
-/// key. files must not overlap and be ordered ascendingly.
-fn find_file<'a>(cmp: &InternalKeyCmp, files: &[FileMetaHandle], key: InternalKey<'a>) -> usize {
+/// key. files must not overlap and be ordered ascendingly. If no file can contain the key, None is
+/// returned.
+fn find_file<'a>(cmp: &InternalKeyCmp,
+                 files: &[FileMetaHandle],
+                 key: InternalKey<'a>)
+                 -> Option<usize> {
     let (mut left, mut right) = (0, files.len());
     while left < right {
         let mid = (left + right) / 2;
@@ -472,7 +475,11 @@
             right = mid;
         }
     }
-    return right;
+    if right < files.len() {
+        Some(right)
+    } else {
+        None
+    }
 }
 
 /// some_file_overlaps_range_disjoint returns true if any of the given disjoint files (i.e. level >
@@ -483,8 +490,7 @@
                                              largest: UserKey<'b>)
                                              -> bool {
     let ikey = LookupKey::new(smallest, MAX_SEQUENCE_NUMBER);
-    let ix = find_file(cmp, files, ikey.internal_key());
-    if ix < files.len() {
+    if let Some(ix) = find_file(cmp, files, ikey.internal_key()) {
         !key_is_before_file(cmp, largest, &files[ix])
     } else {
         false