changeset 163:54f8c4f68b99

Implement RandomAccess with immutable receiver for in-memory files.
author Lewin Bormann <lbo@spheniscida.de>
date Mon, 10 Jul 2017 19:37:38 +0200
parents d41dceaba22b
children fbab9802c402
files src/env.rs src/table_reader.rs
diffstat 2 files changed, 25 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/env.rs	Mon Jul 10 19:19:38 2017 +0200
+++ b/src/env.rs	Mon Jul 10 19:37:38 2017 +0200
@@ -3,27 +3,36 @@
 
 use error::{self, Result};
 
-use std::io::{Read, Write};
+use std::io::{Cursor, Read, Seek, SeekFrom, Write};
+use std::fs::File;
 use std::os::unix::fs::FileExt;
 use std::path::Path;
+use std::sync::Mutex;
 
 pub trait RandomAccess {
     fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>>;
 }
-impl<T: FileExt> RandomAccess for T {
+
+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)
     }
 }
-// impl<T: AsRef<[u8]>> RandomAccess for Cursor<T> {
-// fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>> {
-// self.seek(io::SeekFrom::Start(off));
-// let mut buf = vec![0 as u8; len];
-// error::from_io_result(self.read_exact(&mut buf)).map(|_| buf)
-// }
-// }
-//
+
+/// 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<Cursor<Vec<u8>>>;
+
+impl RandomAccess for BufferBackedFile {
+    fn read_at(&self, off: usize, len: usize) -> Result<Vec<u8>> {
+        let mut c = self.lock().unwrap();
+        error::from_io_result(c.seek(SeekFrom::Start(off as u64)))?;
+        let mut buf = vec![0 as u8; len];
+        error::from_io_result(c.read_exact(&mut buf)).map(|_| buf)
+    }
+}
+
 
 pub struct FileLock {
     pub id: String,
--- a/src/table_reader.rs	Mon Jul 10 19:19:38 2017 +0200
+++ b/src/table_reader.rs	Mon Jul 10 19:37:38 2017 +0200
@@ -391,6 +391,7 @@
     use key_types::LookupKey;
 
     use std::io::Cursor;
+    use std::sync::Mutex;
 
     use super::*;
 
@@ -466,8 +467,10 @@
         (d, size)
     }
 
-    fn wrap_buffer(src: Vec<u8>) -> Box<RandomAccess> {
-        Box::new(Cursor::new(src))
+    fn wrap_buffer(src: Vec<u8>) -> Arc<Box<RandomAccess>> {
+        // sigh...
+        let file = Mutex::new(Cursor::new(src));
+        Arc::new(Box::new(file))
     }
 
     #[test]
@@ -658,7 +661,7 @@
 
         let (src, size) = build_internal_table();
 
-        let mut table = Table::new(Options::default(), Box::new(Cursor::new(src)), size).unwrap();
+        let mut table = Table::new(Options::default(), wrap_buffer(src), size).unwrap();
         let filter_reader = table.filters.clone().unwrap();
 
         // Check that we're actually using internal keys