changeset 209:d1d0a777f0d1

version: enhance control flow in overlapping_inputs()
author Lewin Bormann <lbo@spheniscida.de>
date Wed, 06 Sep 2017 19:07:55 +0200
parents acbd2d3dd789
children 6e1e7c828b69
files src/version.rs
diffstat 1 files changed, 25 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/version.rs	Tue Sep 05 20:43:36 2017 +0200
+++ b/src/version.rs	Wed Sep 06 19:07:55 2017 +0200
@@ -230,51 +230,52 @@
                                   end: InternalKey<'b>)
                                   -> Vec<FileMetaHandle> {
         assert!(level < NUM_LEVELS);
-        let mut inputs = vec![];
         let (mut ubegin, mut uend) = (parse_internal_key(begin).2.to_vec(),
                                       parse_internal_key(end).2.to_vec());
 
-        let mut done = false;
-        while !done {
-            // By default, only do one search. In the special case outlined below, done is set to
-            // false in order to restart the search from scratch.
-            done = true;
+        loop {
+            match do_search(self, level, ubegin, uend) {
+                (Some((newubegin, newuend)), _) => {
+                    ubegin = newubegin;
+                    uend = newuend;
+                },
+                (None, result) => return result
+            }
+        }
 
-            'inner: for f in self.files[level].iter() {
+        // the actual search happens in this inner function. This is done to enhance the control
+        // flow. It takes the smallest and largest user keys and returns a new pair of user keys if
+        // the search range should be expanded, or a list of overlapping files.
+        fn do_search(myself: &Version, level: usize, ubegin: Vec<u8>, uend: Vec<u8>) -> (Option<(Vec<u8>, Vec<u8>)>, Vec<FileMetaHandle>) {
+            let mut inputs = vec![];
+            for f in myself.files[level].iter() {
                 let ((_, _, fsmallest), (_, _, flargest)) = (parse_internal_key(&(*f).smallest),
                                                              parse_internal_key(&(*f).largest));
                 // Skip files that are not overlapping.
-                if !ubegin.is_empty() && self.user_cmp.cmp(flargest, &ubegin) == Ordering::Less {
-                    continue 'inner;
+                if !ubegin.is_empty() && myself.user_cmp.cmp(flargest, &ubegin) == Ordering::Less {
+                    continue;
                 } else if !uend.is_empty() &&
-                          self.user_cmp.cmp(fsmallest, &uend) == Ordering::Greater {
-                    continue 'inner;
+                          myself.user_cmp.cmp(fsmallest, &uend) == Ordering::Greater {
+                    continue;
                 } else {
                     inputs.push(f.clone());
                     // In level 0, files may overlap each other. Check if the new file begins
-                    // before begin or ends after end, and expand the range, if so. Then, restart
+                    // before ubegin or ends after uend, and expand the range, if so. Then, restart
                     // the search.
                     if level == 0 {
                         if !ubegin.is_empty() &&
-                           self.user_cmp.cmp(fsmallest, &ubegin) == Ordering::Less {
-                            ubegin = fsmallest.to_vec();
-                            inputs.truncate(0);
-                            done = false;
-                            break 'inner;
+                           myself.user_cmp.cmp(fsmallest, &ubegin) == Ordering::Less {
+                            return (Some((fsmallest.to_vec(), uend)), inputs)
                         } else if !uend.is_empty() &&
-                                  self.user_cmp.cmp(flargest, &uend) == Ordering::Greater {
-                            uend = flargest.to_vec();
-                            inputs.truncate(0);
-                            done = false;
-                            break 'inner;
-                        } else {
+                                  myself.user_cmp.cmp(flargest, &uend) == Ordering::Greater {
+                            return (Some((ubegin, flargest.to_vec())), inputs)
                         }
                     }
                 }
             }
+            (None, inputs)
         }
 
-        inputs
     }
 
     fn new_concat_iter(&self, level: usize) -> VersionIter {