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::io::{Read, Seek, SeekFrom, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sgxfs::{remove, OpenOptions, SgxFile};
|
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::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
pub struct SgxStorage {
|
pub struct SgxStorage {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
file_cache: Mutex<BTreeMap<usize, LockedFile>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SgxStorage {
|
impl SgxStorage {
|
||||||
@ -17,46 +19,73 @@ impl SgxStorage {
|
|||||||
// assert!(path.as_ref().is_dir());
|
// assert!(path.as_ref().is_dir());
|
||||||
SgxStorage {
|
SgxStorage {
|
||||||
path: path.as_ref().to_path_buf(),
|
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 {
|
impl Storage for SgxStorage {
|
||||||
fn open(&self, file_id: usize) -> DevResult<Box<File>> {
|
fn open(&self, file_id: usize) -> DevResult<Box<File>> {
|
||||||
let mut path = self.path.to_path_buf();
|
let locked_file = self.get(file_id, |this| {
|
||||||
path.push(format!("{}", file_id));
|
let mut path = this.path.to_path_buf();
|
||||||
// TODO: key
|
path.push(format!("{}", file_id));
|
||||||
let key = [0u8; 16];
|
// TODO: key
|
||||||
let file = OpenOptions::new()
|
let key = [0u8; 16];
|
||||||
.read(true)
|
let file = OpenOptions::new()
|
||||||
.update(true)
|
.read(true)
|
||||||
.open_ex(path, &key)
|
.update(true)
|
||||||
.expect("failed to open SgxFile");
|
.open_ex(path, &key)
|
||||||
Ok(Box::new(LockedFile(Mutex::new(file))))
|
.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>> {
|
fn create(&self, file_id: usize) -> DevResult<Box<File>> {
|
||||||
let mut path = self.path.to_path_buf();
|
let locked_file = self.get(file_id, |this| {
|
||||||
path.push(format!("{}", file_id));
|
let mut path = this.path.to_path_buf();
|
||||||
// TODO: key
|
path.push(format!("{}", file_id));
|
||||||
let key = [0u8; 16];
|
// TODO: key
|
||||||
let file = OpenOptions::new()
|
let key = [0u8; 16];
|
||||||
.write(true)
|
let file = OpenOptions::new()
|
||||||
.update(true)
|
.write(true)
|
||||||
.open_ex(path, &key)
|
.update(true)
|
||||||
.expect("failed to create SgxFile");
|
.open_ex(path, &key)
|
||||||
Ok(Box::new(LockedFile(Mutex::new(file))))
|
.expect("failed to create SgxFile");
|
||||||
|
LockedFile(Arc::new(Mutex::new(file)))
|
||||||
|
});
|
||||||
|
Ok(Box::new(locked_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&self, file_id: usize) -> DevResult<()> {
|
fn remove(&self, file_id: usize) -> DevResult<()> {
|
||||||
let mut path = self.path.to_path_buf();
|
let mut path = self.path.to_path_buf();
|
||||||
path.push(format!("{}", file_id));
|
path.push(format!("{}", file_id));
|
||||||
remove(path).expect("failed to remove SgxFile");
|
remove(path).expect("failed to remove SgxFile");
|
||||||
|
// remove from cache
|
||||||
|
let mut caches = self.file_cache.lock().unwrap();
|
||||||
|
caches.remove(&file_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LockedFile(Mutex<SgxFile>);
|
#[derive(Clone)]
|
||||||
|
pub struct LockedFile(Arc<Mutex<SgxFile>>);
|
||||||
|
|
||||||
// `sgx_tstd::sgxfs::SgxFile` not impl Send ...
|
// `sgx_tstd::sgxfs::SgxFile` not impl Send ...
|
||||||
unsafe impl Send for LockedFile {}
|
unsafe impl Send for LockedFile {}
|
||||||
|
Loading…
Reference in New Issue
Block a user