Mercurial > lbo > hg > leveldb-rs
changeset 167:9e7e1a943718
Revamp RandomAccess trait to be more Rust-like.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 16 Jul 2017 11:47:48 +0200 |
parents | ef5426303667 |
children | b61d6db64da0 |
files | src/env.rs src/table_reader.rs |
diffstat | 2 files changed, 21 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/env.rs Sun Jul 16 10:56:40 2017 +0200 +++ b/src/env.rs Sun Jul 16 11:47:48 2017 +0200 @@ -10,27 +10,31 @@ use std::sync::Mutex; pub trait RandomAccess { - fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>>; + fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize>; } impl RandomAccess for File { - fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>> { - let mut buf = vec![0 as u8; len]; - error::from_io_result((self as &FileExt).read_at(buf.as_mut(), off as u64)).map(|_| buf) + fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize> { + error::from_io_result((self as &FileExt).read_at(dst, off as u64)) } } -/// BufferBackedFile implements RandomAccess on a cursor. It wraps the cursor in a mutex -/// to enable using an immutable receiver, like the File implementation. -pub type BufferBackedFile = Mutex<Vec<u8>>; +/// BufferBackedFile is a simple type implementing RandomAccess on a Vec<u8>. +pub type BufferBackedFile = Vec<u8>; impl RandomAccess for BufferBackedFile { - fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>> { - let c = self.lock().unwrap(); - if off + len > c.len() { - return Err(error::Status::new(error::StatusCode::InvalidArgument, "off-limits read")); + fn read_at(&self, off: usize, dst: &mut [u8]) -> Result<usize> { + if off > self.len() { + return Ok(0); } - Ok(c[off..off + len].to_vec()) + let remaining = self.len() - off; + let to_read = if dst.len() > remaining { + remaining + } else { + dst.len() + }; + (&mut dst[0..to_read]).copy_from_slice(&self[off..off + to_read]); + Ok(to_read) } }
--- a/src/table_reader.rs Sun Jul 16 10:56:40 2017 +0200 +++ b/src/table_reader.rs Sun Jul 16 11:47:48 2017 +0200 @@ -19,13 +19,14 @@ /// Reads the table footer. fn read_footer(f: &RandomAccess, size: usize) -> Result<Footer> { - let buf = try!(f.read_at(size - table_builder::FULL_FOOTER_LENGTH, - table_builder::FULL_FOOTER_LENGTH)); + let mut buf = vec![0; table_builder::FULL_FOOTER_LENGTH]; + f.read_at(size - table_builder::FULL_FOOTER_LENGTH, &mut buf)?; Ok(Footer::decode(&buf)) } fn read_bytes(f: &RandomAccess, location: &BlockHandle) -> Result<Vec<u8>> { - f.read_at(location.offset(), location.size()) + let mut buf = vec![0; location.size()]; + f.read_at(location.offset(), &mut buf).map(|_| buf) } #[derive(Clone)] @@ -467,8 +468,7 @@ } fn wrap_buffer(src: Vec<u8>) -> Arc<Box<RandomAccess>> { - let file = Mutex::new(src); - Arc::new(Box::new(file)) + Arc::new(Box::new(src)) } #[test]