From 41c76d66233db06c029db4fd4e881614a1fdd350 Mon Sep 17 00:00:00 2001 From: edef Date: Tue, 3 May 2022 17:22:36 +0000 Subject: ripple/fossil/mount: make node references more flexible Essentially, memtree::Node becomes more of a NodeRef, and Node gets renamed to NodeBuf. This permits calling Node::find with an arbitrary owned Directory, without having to move it into the enum. Change-Id: I93838932a00f2e2073e3c7ddf7ce8d302ed4ed59 --- ripple/fossil/src/bin/mount.rs | 58 ++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/ripple/fossil/src/bin/mount.rs b/ripple/fossil/src/bin/mount.rs index c43a5ae..1dafc41 100644 --- a/ripple/fossil/src/bin/mount.rs +++ b/ripple/fossil/src/bin/mount.rs @@ -20,7 +20,7 @@ lazy_static! { static ref EPOCH_PLUS_ONE: SystemTime = UNIX_EPOCH + Duration::from_secs(1); } -fn file_attr(ino: u64, node: &memtree::Node) -> fuser::FileAttr { +fn file_attr(ino: u64, node: memtree::Node) -> fuser::FileAttr { let size = match node { memtree::Node::Directory(d) => d.len() as u64, memtree::Node::File(f) => f.size as u64, @@ -98,19 +98,16 @@ fn main() { struct Filesystem { store: fossil::Store, - root: memtree::Node, + root: memtree::Directory, } impl Filesystem { fn open(store: fossil::Store, root: memtree::Directory) -> Filesystem { - Filesystem { - store, - root: memtree::Node::Directory(root), - } + Filesystem { store, root } } - fn find(&self, ino: u64) -> Option<&memtree::Node> { - self.root.find(ino.checked_sub(1)?.try_into().ok()?) + fn find(&self, ino: u64) -> Option { + memtree::Node::Directory(&self.root).find(ino.checked_sub(1)?.try_into().ok()?) } unsafe fn from_fh<'a>(&'a self, fh: u64) -> *mut Handle<'a> { @@ -671,15 +668,32 @@ mod memtree { }; #[derive(Debug)] - pub enum Node { + enum NodeBuf { Directory(Directory), File(FileRef), Link { target: String }, } + #[derive(Debug, Clone, Copy)] + pub enum Node<'a> { + Directory(&'a Directory), + File(&'a FileRef), + Link { target: &'a str }, + } + + impl NodeBuf { + fn as_ref(&self) -> Node { + match self { + NodeBuf::Directory(d) => Node::Directory(d), + NodeBuf::File(f) => Node::File(f), + NodeBuf::Link { target } => Node::Link { target }, + } + } + } + #[derive(Default)] pub struct Directory { - by_index: BTreeMap, + by_index: BTreeMap, by_name: BTreeMap, size: u32, } @@ -687,7 +701,7 @@ mod memtree { pub struct DirectoryEntry<'a> { pub name: &'a str, pub index: u32, - pub node: &'a Node, + pub node: Node<'a>, } impl Directory { @@ -700,7 +714,7 @@ mod memtree { DirectoryEntry { name: &name, index: idx, - node, + node: node.as_ref(), } }) } @@ -710,7 +724,7 @@ mod memtree { Some(DirectoryEntry { name, index, - node: &self.by_index[&index], + node: self.by_index[&index].as_ref(), }) } } @@ -748,7 +762,7 @@ mod memtree { } in pb.directories { let child = load_root(store, fossil::digest_from_bytes(&r#ref)); - children.insert(name, Node::Directory(child)); + children.insert(name, NodeBuf::Directory(child)); } for store::FileNode { @@ -763,26 +777,26 @@ mod memtree { executable, size: child_size, }; - children.insert(name, Node::File(child)); + children.insert(name, NodeBuf::File(child)); } for store::LinkNode { name, target } in pb.links { - children.insert(name, Node::Link { target }); + children.insert(name, NodeBuf::Link { target }); } Directory::from_children(children) } impl Directory { - fn from_children(children: BTreeMap) -> Directory { + fn from_children(children: BTreeMap) -> Directory { let mut d = Directory::default(); for (name, child) in children { let index = d.size; let size = match child { - Node::Directory(Directory { size, .. }) => { + NodeBuf::Directory(Directory { size, .. }) => { size.checked_add(1).expect("overflow") } - Node::File(_) | Node::Link { .. } => 1, + NodeBuf::File(_) | NodeBuf::Link { .. } => 1, }; d.size = index.checked_add(size).expect("overflow"); @@ -800,8 +814,8 @@ mod memtree { } } - impl Node { - pub fn find(&self, mut index: u32) -> Option<&Node> { + impl<'a> Node<'a> { + pub fn find(self, mut index: u32) -> Option> { let mut root = self; loop { let d = match (index, root) { @@ -818,7 +832,7 @@ mod memtree { }; let (&child_index, child) = d.by_index.range(..=index).next_back()?; - root = child; + root = child.as_ref(); index = index.checked_sub(child_index).unwrap(); } } -- cgit 1.4.1