summary refs log tree commit diff
diff options
context:
space:
mode:
authoredef <edef@unfathomable.blue>2022-05-03 17:22:36 +0000
committeredef <edef@unfathomable.blue>2022-05-03 21:10:17 +0000
commit41c76d66233db06c029db4fd4e881614a1fdd350 (patch)
tree01ccf6d61f9fed1aa3dca14a4f2616c936e6bf22
parent6acd605e50d05b026c9db1a3de10cca5d188dc44 (diff)
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
-rw-r--r--ripple/fossil/src/bin/mount.rs58
1 files 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> {
+		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<u32, Node>,
+		by_index: BTreeMap<u32, NodeBuf>,
 		by_name: BTreeMap<String, u32>,
 		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<String, Node>) -> Directory {
+		fn from_children(children: BTreeMap<String, NodeBuf>) -> 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<Node<'a>> {
 			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();
 			}
 		}