Mercurial > lbo > hg > leveldb-rs
changeset 134:2788dee1b457
Make entry parsing and offset arithmetics more understandable and properly documented
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Mon, 02 Jan 2017 11:31:17 +0100 |
parents | d0c7a2c7c798 |
children | 2dd641bded74 |
files | src/block.rs |
diffstat | 1 files changed, 34 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/block.rs Mon Jan 02 11:15:42 2017 +0100 +++ b/src/block.rs Mon Jan 02 11:31:17 2017 +0100 @@ -94,8 +94,15 @@ } impl BlockIter { - // Returns SHARED, NON_SHARED and VALSIZE from the current position. Advances self.offset. - fn parse_entry(&mut self) -> (usize, usize, usize) { + /// The layout of an entry is + /// [SHARED varint, NON_SHARED varint, VALSIZE varint, KEY (NON_SHARED bytes), + /// VALUE (VALSIZE bytes)]. + /// + /// Returns SHARED, NON_SHARED, VALSIZE and [length of length spec] from the current position, + /// where 'length spec' is the length of the three values in the entry header, as described + /// above. + /// Advances self.offset to point to the beginning of the next entry. + fn parse_entry_and_advance(&mut self) -> (usize, usize, usize, usize) { let mut i = 0; let (shared, sharedlen) = usize::decode_var(&self.block[self.offset..]); i += sharedlen; @@ -106,16 +113,22 @@ let (valsize, valsizelen) = usize::decode_var(&self.block[self.offset + i..]); i += valsizelen; - self.offset += i; + self.val_offset = self.offset + i + non_shared; + self.offset = self.offset + i + non_shared + valsize; - (shared, non_shared, valsize) + (shared, non_shared, valsize, i) } - /// offset is assumed to be at the beginning of the non-shared key part. - /// offset is not advanced. - fn assemble_key(&mut self, shared: usize, non_shared: usize) { + /// Assemble the current key from shared and non-shared parts (an entry usually contains only + /// the part of the key that is different from the previous key). + /// + /// `off` is the offset of the key string within the whole block (self.current_entry_offset + /// + entry header length); `shared` and `non_shared` are the lengths of the shared + /// respectively non-shared parts of the key. + /// Only self.key is mutated. + fn assemble_key(&mut self, off: usize, shared: usize, non_shared: usize) { self.key.resize(shared, 0); - self.key.extend_from_slice(&self.block[self.offset..self.offset + non_shared]); + self.key.extend_from_slice(&self.block[off..off + non_shared]); } pub fn seek_to_last(&mut self) { @@ -147,17 +160,18 @@ self.current_entry_offset = self.offset; } - let (shared, non_shared, valsize) = self.parse_entry(); - self.assemble_key(shared, non_shared); + let current_off = self.current_entry_offset; - self.val_offset = self.offset + non_shared; - self.offset = self.val_offset + valsize; + let (shared, non_shared, valsize, entry_head_len) = self.parse_entry_and_advance(); + self.assemble_key(current_off + entry_head_len, shared, non_shared); + // Adjust current_restart_ix let num_restarts = self.number_restarts(); while self.current_restart_ix + 1 < num_restarts && self.get_restart_point(self.current_restart_ix + 1) < self.current_entry_offset { self.current_restart_ix += 1; } + Some((self.key.clone(), Vec::from(&self.block[self.val_offset..self.val_offset + valsize]))) } } @@ -219,14 +233,19 @@ // Do a binary search over the restart points. while left < right { let middle = (left + right + 1) / 2; + let current_entry_offset = self.offset; self.offset = self.get_restart_point(middle); - // advances self.offset - let (shared, non_shared, _) = self.parse_entry(); + // advances self.offset to point to the next entry + let (shared, non_shared, _, head_len) = self.parse_entry_and_advance(); // At a restart, the shared part is supposed to be 0. assert_eq!(shared, 0); - let c = self.opt.cmp.cmp(&self.block[self.offset..self.offset + non_shared], to); + let c = self.opt + .cmp + .cmp(&self.block[current_entry_offset + head_len..current_entry_offset + head_len + + non_shared], + to); if c == Ordering::Less { left = middle;