Mercurial > lbo > hg > leveldb-rs
changeset 453:ca875a71e17e
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 | 157c0286fdc9 |
children | f304c03079e4 |
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:58:29 2018 +0100 +++ b/src/db_impl.rs Sat Mar 10 20:07:26 2018 +0100 @@ -408,9 +408,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); @@ -433,15 +430,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:58:29 2018 +0100 +++ b/src/version.rs Sat Mar 10 20:07:26 2018 +0100 @@ -222,7 +222,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() {