parent
676dc9073f
commit
3c80180df0
4 changed files with 46 additions and 103 deletions
|
@ -1,83 +0,0 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::ops::Drop;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::result::Result as RResult;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::RwLock;
|
|
||||||
|
|
||||||
pub use store::Store;
|
|
||||||
pub use store::Result;
|
|
||||||
pub use store::FileLockEntry;
|
|
||||||
pub use entry::Entry;
|
|
||||||
pub use error::StoreError;
|
|
||||||
|
|
||||||
pub struct FSStore {
|
|
||||||
location: PathBuf,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal Path->File cache map
|
|
||||||
*
|
|
||||||
* Caches the files, so they remain flock()ed
|
|
||||||
*
|
|
||||||
* Could be optimized for a threadsafe HashMap
|
|
||||||
*/
|
|
||||||
cache: Arc<RwLock<HashMap<PathBuf, File>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FSStore {
|
|
||||||
|
|
||||||
pub fn new(location: PathBuf) -> FSStore {
|
|
||||||
FSStore {
|
|
||||||
location: location,
|
|
||||||
cache: Arc::new(RwLock::new(HashMap::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Store for FSStore {
|
|
||||||
|
|
||||||
fn location(&self) -> &PathBuf {
|
|
||||||
&self.location
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create(&self, entry: Entry) -> Result<()> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn retrieve<'a>(&'a self, path: PathBuf) -> Result<FileLockEntry<'a, Self>> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn retrieve_copy(&self, id : String) -> Result<Entry> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update<'a>(&'a self, entry: FileLockEntry<'a, Self>) -> Result<()> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn delete(&self, path: PathBuf) -> Result<()> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for FSStore {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlock all files on drop
|
|
||||||
*
|
|
||||||
* TODO: Error message when file cannot be unlocked?
|
|
||||||
*/
|
|
||||||
fn drop(&mut self) {
|
|
||||||
use std::ops::DerefMut;
|
|
||||||
use fs2::FileExt;
|
|
||||||
|
|
||||||
let cache = self.cache.clone();
|
|
||||||
cache.write().unwrap().deref_mut().iter().map(|(_, f)| f.unlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ extern crate toml;
|
||||||
pub mod content;
|
pub mod content;
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod fsstore;
|
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod single_use_lock;
|
|
||||||
pub mod store;
|
pub mod store;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
pub trait SingleUseLock<T> {
|
|
||||||
fn access(&self) -> &T;
|
|
||||||
fn unlock(self) -> T;
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,25 +11,58 @@ pub use error::StoreError;
|
||||||
|
|
||||||
pub type Result<T> = RResult<T, StoreError>;
|
pub type Result<T> = RResult<T, StoreError>;
|
||||||
|
|
||||||
pub trait Store : Sized {
|
pub struct Store {
|
||||||
|
location: PathBuf,
|
||||||
|
|
||||||
fn location(&self) -> &PathBuf;
|
/**
|
||||||
|
* Internal Path->File cache map
|
||||||
|
*
|
||||||
|
* Caches the files, so they remain flock()ed
|
||||||
|
*
|
||||||
|
* Could be optimized for a threadsafe HashMap
|
||||||
|
*/
|
||||||
|
cache: Arc<RwLock<HashMap<PathBuf, RwLock<File>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
fn create(&self, entry: Entry) -> Result<()>;
|
impl Store {
|
||||||
fn retrieve<'a>(&'a self, path: PathBuf) -> Result<FileLockEntry<'a, Self>>;
|
|
||||||
fn update<'a>(&'a self, entry: FileLockEntry<'a, Self>) -> Result<()>;
|
fn create(&self, entry: Entry) -> Result<()> {
|
||||||
fn retrieve_copy(&self, id : String) -> Result<Entry>;
|
unimplemented!();
|
||||||
fn delete(&self, path: PathBuf) -> Result<()>;
|
}
|
||||||
|
fn retrieve<'a>(&'a self, path: PathBuf) -> Result<FileLockEntry<'a>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
fn update<'a>(&'a self, entry: FileLockEntry<'a>) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
fn retrieve_copy(&self, id : String) -> Result<Entry> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
fn delete(&self, path: PathBuf) -> Result<()> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Store {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock all files on drop
|
||||||
|
*
|
||||||
|
* TODO: Error message when file cannot be unlocked?
|
||||||
|
*/
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.cache.iter().map(|f| f.unlock());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FileLockEntry<'a, S: Store + 'a> {
|
pub struct FileLockEntry<'a> {
|
||||||
store: &'a S,
|
store: &'a Store,
|
||||||
entry: Entry
|
entry: Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: Store + 'a> FileLockEntry<'a, S > {
|
impl<'a> FileLockEntry<'a, > {
|
||||||
fn new(store: &'a S, entry: Entry) -> FileLockEntry<'a, S> {
|
fn new(store: &'a Store, entry: Entry) -> FileLockEntry<'a> {
|
||||||
FileLockEntry {
|
FileLockEntry {
|
||||||
store: store,
|
store: store,
|
||||||
entry: entry,
|
entry: entry,
|
||||||
|
@ -37,7 +70,7 @@ impl<'a, S: Store + 'a> FileLockEntry<'a, S > {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: Store + 'a> ::std::ops::Deref for FileLockEntry<'a, S> {
|
impl<'a> ::std::ops::Deref for FileLockEntry<'a> {
|
||||||
type Target = Entry;
|
type Target = Entry;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -45,7 +78,7 @@ impl<'a, S: Store + 'a> ::std::ops::Deref for FileLockEntry<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, S: Store + 'a> ::std::ops::DerefMut for FileLockEntry<'a, S> {
|
impl<'a> ::std::ops::DerefMut for FileLockEntry<'a> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.entry
|
&mut self.entry
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue