add cache for SgxFile

This commit is contained in:
WangRunji 2019-04-21 18:04:48 +08:00
parent ad98a1698e
commit f4dacdc01d

@ -5,11 +5,13 @@ use std::boxed::Box;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::{Path, PathBuf};
use std::sgxfs::{remove, OpenOptions, SgxFile};
use std::sync::SgxMutex as Mutex;
use std::sync::{SgxMutex as Mutex, Arc};
use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::BTreeMap;
pub struct SgxStorage {
path: PathBuf,
file_cache: Mutex<BTreeMap<usize, LockedFile>>,
}
impl SgxStorage {
@ -17,46 +19,73 @@ impl SgxStorage {
// assert!(path.as_ref().is_dir());
SgxStorage {
path: path.as_ref().to_path_buf(),
file_cache: Mutex::new(BTreeMap::new())
}
}
/// Get file by `file_id`.
/// It lookups cache first, if miss, then call `open_fn` to open one,
/// and add it to cache before return.
fn get(&self, file_id: usize, open_fn: impl FnOnce(&Self) -> LockedFile) -> LockedFile {
// query cache
let mut caches = self.file_cache.lock().unwrap();
if let Some(locked_file) = caches.get(&file_id) {
// hit, return
return locked_file.clone();
}
// miss, open one
let locked_file = open_fn(self);
// add to cache
caches.insert(file_id, locked_file.clone());
locked_file
}
}
impl Storage for SgxStorage {
fn open(&self, file_id: usize) -> DevResult<Box<File>> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.read(true)
.update(true)
.open_ex(path, &key)
.expect("failed to open SgxFile");
Ok(Box::new(LockedFile(Mutex::new(file))))
let locked_file = self.get(file_id, |this| {
let mut path = this.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.read(true)
.update(true)
.open_ex(path, &key)
.expect("failed to open SgxFile");
LockedFile(Arc::new(Mutex::new(file)))
});
Ok(Box::new(locked_file))
}
fn create(&self, file_id: usize) -> DevResult<Box<File>> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.write(true)
.update(true)
.open_ex(path, &key)
.expect("failed to create SgxFile");
Ok(Box::new(LockedFile(Mutex::new(file))))
let locked_file = self.get(file_id, |this| {
let mut path = this.path.to_path_buf();
path.push(format!("{}", file_id));
// TODO: key
let key = [0u8; 16];
let file = OpenOptions::new()
.write(true)
.update(true)
.open_ex(path, &key)
.expect("failed to create SgxFile");
LockedFile(Arc::new(Mutex::new(file)))
});
Ok(Box::new(locked_file))
}
fn remove(&self, file_id: usize) -> DevResult<()> {
let mut path = self.path.to_path_buf();
path.push(format!("{}", file_id));
remove(path).expect("failed to remove SgxFile");
// remove from cache
let mut caches = self.file_cache.lock().unwrap();
caches.remove(&file_id);
Ok(())
}
}
pub struct LockedFile(Mutex<SgxFile>);
#[derive(Clone)]
pub struct LockedFile(Arc<Mutex<SgxFile>>);
// `sgx_tstd::sgxfs::SgxFile` not impl Send ...
unsafe impl Send for LockedFile {}