use super::ino::Ino; use std::{ collections::{ btree_map::{self, OccupiedError}, BTreeMap, HashMap, }, ffi::{OsStr, OsString}, }; #[derive(Debug)] pub(super) struct Dcache { inner: HashMap, } 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> { 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 { self.insert(ino, Dentry::new(ino, parent)) } // Map-like API pub fn insert(&mut self, ino: Ino, dentry: Dentry) -> Option { 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 { self.inner.remove(&ino) } } #[derive(Debug)] pub(super) struct Dentry { inner: BTreeMap, 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 { 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 { self.inner.remove(k) } pub fn iter(&self) -> impl Iterator { self.inner.iter() } }