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]