add cache for SgxFile
This commit is contained in:
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 {}
|
||||
|
Loading…
Reference in New Issue
Block a user