changeset 454:6b16d8c1b5a6

fix(borrow): Attempt at fixing #2 (BorrowError in DBImpl). It looks like maybe_do_compaction() was called with the current version being borrowed, and VersionSet::needs_compaction() attempts to re-borrow the current version.
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 10 Mar 2018 20:07:26 +0100
parents 98fe747656e5
children fbd81ef2b3c6
files src/db_impl.rs src/version.rs
diffstat 2 files changed, 19 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/db_impl.rs	Sat Mar 03 11:51:22 2018 +0100
+++ b/src/db_impl.rs	Sat Mar 10 20:07:26 2018 +0100
@@ -398,9 +398,6 @@
     // READ //
 
     fn get_internal(&mut self, seq: SequenceNumber, key: &[u8]) -> Result<Option<Vec<u8>>> {
-        let current = self.current();
-        let mut current = current.borrow_mut();
-
         // Using this lookup key will skip all entries with higher sequence numbers, because they
         // will compare "Lesser" using the InternalKeyCmp
         let lkey = LookupKey::new(key, seq);
@@ -423,15 +420,27 @@
             }
         }
 
-        if let Ok(Some((v, st))) = current.get(lkey.internal_key()) {
-            if current.update_stats(st) {
-                if let Err(e) = self.maybe_do_compaction() {
-                    log!(self.opt.log, "error while doing compaction in get: {}", e);
+        let mut do_compaction = false;
+        let mut result = None;
+
+        // Limiting the borrow scope of self.current.
+        {
+            let current = self.current();
+            let mut current = current.borrow_mut();
+            if let Ok(Some((v, st))) = current.get(lkey.internal_key()) {
+                if current.update_stats(st) {
+                    do_compaction = true;
                 }
+                result = Some(v)
             }
-            return Ok(Some(v));
         }
-        Ok(None)
+
+        if do_compaction {
+            if let Err(e) = self.maybe_do_compaction() {
+                log!(self.opt.log, "error while doing compaction in get: {}", e);
+            }
+        }
+        Ok(result)
     }
 
     /// get_at reads the value for a given key at or before snapshot. It returns Ok(None) if the
--- a/src/version.rs	Sat Mar 03 11:51:22 2018 +0100
+++ b/src/version.rs	Sat Mar 10 20:07:26 2018 +0100
@@ -216,7 +216,7 @@
     }
 
     /// update_stats updates the number of seeks, and remembers files with too many seeks as
-    /// compaction candidates.
+    /// compaction candidates. It returns true if a compaction makes sense.
     pub fn update_stats(&mut self, stats: GetStats) -> bool {
         if let Some(file) = stats.file {
             if file.borrow().allowed_seeks <= 1 && self.file_to_compact.is_none() {