diff options
Diffstat (limited to 'src/client/fs/dcache.rs')
-rw-r--r-- | src/client/fs/dcache.rs | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/client/fs/dcache.rs b/src/client/fs/dcache.rs new file mode 100644 index 0000000..b171abc --- /dev/null +++ b/src/client/fs/dcache.rs @@ -0,0 +1,107 @@ +use super::ino::Ino; +use std::{ + collections::{ + btree_map::{self, OccupiedError}, + BTreeMap, HashMap, + }, + ffi::{OsStr, OsString}, +}; + +#[derive(Debug)] +pub(super) struct Dcache { + inner: HashMap<Ino, Dentry>, +} + +impl Dcache { + pub fn new() -> Self { + Self { + inner: HashMap::new(), + } + } + + pub fn get_ino(&self, parent: Ino, name: &OsStr) -> Option<&Ino> { + self.get(parent).and_then(|dentry| dentry.get(name)) + } + + pub fn try_insert_name( + &mut self, + parent: Ino, + name: OsString, + ino: Ino, + ) -> Option<Result<(), ()>> { + match self + .get_mut(parent) + .map(|dentry| dentry.try_insert(name, ino)) + { + Some(Ok(_)) => Some(Ok(())), + Some(Err(_)) => Some(Err(())), + None => None, + } + } + + pub fn add_dentry(&mut self, ino: Ino, parent: Ino) -> Option<Dentry> { + self.insert(ino, Dentry::new(ino, parent)) + } + + // Map-like API + + pub fn insert(&mut self, ino: Ino, dentry: Dentry) -> Option<Dentry> { + self.inner.insert(ino, dentry) + } + + pub fn get(&self, ino: Ino) -> Option<&Dentry> { + self.inner.get(&ino) + } + + pub fn get_mut(&mut self, ino: Ino) -> Option<&mut Dentry> { + self.inner.get_mut(&ino) + } + + pub fn remove(&mut self, ino: Ino) -> Option<Dentry> { + self.inner.remove(&ino) + } +} + +#[derive(Debug)] +pub(super) struct Dentry { + inner: BTreeMap<OsString, Ino>, + pub loaded: bool, +} + +impl Dentry { + pub fn new(ino: Ino, parent: Ino) -> Self { + let mut dentry = Self { + inner: BTreeMap::new(), + loaded: false, + }; + + dentry.insert(".".into(), ino); + dentry.insert("..".into(), parent); + + dentry + } + + pub fn insert(&mut self, k: OsString, v: Ino) -> Option<Ino> { + self.inner.insert(k, v) + } + + pub fn try_insert( + &mut self, + k: OsString, + v: Ino, + ) -> Result<&mut Ino, btree_map::OccupiedError<'_, OsString, Ino>> { + self.inner.try_insert(k, v) + } + + pub fn get(&self, k: &OsStr) -> Option<&Ino> { + self.inner.get(k) + } + + pub fn remove(&mut self, k: &OsStr) -> Option<Ino> { + self.inner.remove(k) + } + + pub fn iter(&self) -> impl Iterator<Item = (&OsString, &Ino)> { + self.inner.iter() + } +} |